diff --git a/build.gradle b/build.gradle index c7f9b0696..60cd5e602 100644 --- a/build.gradle +++ b/build.gradle @@ -113,7 +113,7 @@ repositories { mavenCentral() } -// Fix for loading non-mod libraries in dev-env, used for miniball. +// Fix for loading non-mod libraries in dev-env, used for JOML and Miniball. // https://gist.github.com/SizableShrimp/66b22f1b24c255e1491c8d98d3f11f83 // v--------------------------------------------------------------------v configurations { @@ -131,14 +131,18 @@ minecraft.runs.all { dependencies { minecraft "net.minecraftforge:forge:${minecraft_version}-${forge_version}" - jarJar(group: 'com.dreizak', name: 'miniball', version: "1.0.3") { - jarJar.ranged(it, "[1.0,2.0)") + jarJar('org.joml:joml:1.10.5') { + jarJar.ranged(it, '[1.10.0,1.11.0)') } - library "com.dreizak:miniball:1.0.3" + library 'org.joml:joml:1.10.5' + + jarJar('com.dreizak:miniball:1.0.3') { + jarJar.ranged(it, '[1.0,2.0)') + } + library 'com.dreizak:miniball:1.0.3' // switch to implementation for debugging compileOnly fg.deobf("maven.modrinth:starlight-forge:1.0.2+1.18.2") - compileOnly fg.deobf("maven.modrinth:rubidium:0.5.3a") compileOnly fg.deobf("maven.modrinth:oculus:1.18.2-1.2.5a") diff --git a/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java index c52837e45..89ab8e959 100644 --- a/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java +++ b/src/main/java/com/jozufozu/flywheel/api/instance/Instance.java @@ -1,6 +1,6 @@ package com.jozufozu.flywheel.api.instance; -import com.jozufozu.flywheel.util.joml.FrustumIntersection; +import org.joml.FrustumIntersection; import net.minecraft.core.BlockPos; diff --git a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java index edc21b543..2a8c387d5 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java +++ b/src/main/java/com/jozufozu/flywheel/backend/gl/shader/GlProgram.java @@ -1,6 +1,8 @@ package com.jozufozu.flywheel.backend.gl.shader; -import static org.lwjgl.opengl.GL20.*; +import static org.lwjgl.opengl.GL20.glDeleteProgram; +import static org.lwjgl.opengl.GL20.glGetUniformLocation; +import static org.lwjgl.opengl.GL20.glUniform1i; import com.jozufozu.flywheel.backend.Backend; import com.jozufozu.flywheel.backend.gl.GlObject; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java index b38db6b34..7b92033c2 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstanceManager.java @@ -7,6 +7,8 @@ import java.util.List; import java.util.Set; import java.util.function.Consumer; +import org.joml.FrustumIntersection; + import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.backend.Backend; @@ -16,7 +18,6 @@ import com.jozufozu.flywheel.backend.instancing.ratelimit.NonLimiter; import com.jozufozu.flywheel.config.FlwConfig; import com.jozufozu.flywheel.core.RenderContext; import com.jozufozu.flywheel.light.LightUpdater; -import com.jozufozu.flywheel.util.joml.FrustumIntersection; import net.minecraft.core.BlockPos; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java index 2695ac4d2..ac962230d 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/InstancedRenderDispatcher.java @@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.instancing; import java.util.List; import com.jozufozu.flywheel.backend.Backend; -import com.jozufozu.flywheel.backend.gl.GlStateTracker; import com.jozufozu.flywheel.backend.instancing.effect.Effect; import com.jozufozu.flywheel.config.FlwCommands; import com.jozufozu.flywheel.config.FlwConfig; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java index 7cda44ec0..630a3b830 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/blockentity/BlockEntityInstance.java @@ -3,6 +3,8 @@ package com.jozufozu.flywheel.backend.instancing.blockentity; import java.util.ArrayList; import java.util.List; +import org.joml.FrustumIntersection; + import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.instancer.InstancedPart; @@ -10,7 +12,6 @@ import com.jozufozu.flywheel.api.instancer.InstancerManager; import com.jozufozu.flywheel.backend.instancing.AbstractInstance; import com.jozufozu.flywheel.util.box.GridAlignedBB; import com.jozufozu.flywheel.util.box.ImmutableBox; -import com.jozufozu.flywheel.util.joml.FrustumIntersection; import net.minecraft.core.BlockPos; import net.minecraft.world.level.block.entity.BlockEntity; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/compile/CompileUtil.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/compile/CompileUtil.java index 14a4631a4..bbf16226c 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/compile/CompileUtil.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/compile/CompileUtil.java @@ -1,7 +1,7 @@ package com.jozufozu.flywheel.backend.instancing.compile; +import static org.lwjgl.opengl.GL11.GL_TRUE; import static org.lwjgl.opengl.GL20.GL_LINK_STATUS; -import static org.lwjgl.opengl.GL20.GL_TRUE; import static org.lwjgl.opengl.GL20.glGetProgramInfoLog; import static org.lwjgl.opengl.GL20.glGetProgrami; import static org.lwjgl.opengl.GL20.glLinkProgram; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java index 352aa832b..125fc6718 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/entity/EntityInstance.java @@ -1,5 +1,7 @@ package com.jozufozu.flywheel.backend.instancing.entity; +import org.joml.FrustumIntersection; + import com.jozufozu.flywheel.api.instance.DynamicInstance; import com.jozufozu.flywheel.api.instance.TickableInstance; import com.jozufozu.flywheel.api.instancer.InstancerManager; @@ -8,7 +10,6 @@ import com.jozufozu.flywheel.backend.instancing.blockentity.BlockEntityInstanceM import com.jozufozu.flywheel.light.LightListener; import com.jozufozu.flywheel.light.TickingLightListener; import com.jozufozu.flywheel.util.box.GridAlignedBB; -import com.jozufozu.flywheel.util.joml.FrustumIntersection; import com.mojang.math.Vector3f; import net.minecraft.core.BlockPos; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectBuffers.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectBuffers.java index 2c9f5f7d1..a76b661fb 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectBuffers.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectBuffers.java @@ -1,7 +1,22 @@ package com.jozufozu.flywheel.backend.instancing.indirect; +import static org.lwjgl.opengl.GL15.glBindBuffer; +import static org.lwjgl.opengl.GL15.glDeleteBuffers; +import static org.lwjgl.opengl.GL15.nglDeleteBuffers; +import static org.lwjgl.opengl.GL30.GL_MAP_FLUSH_EXPLICIT_BIT; +import static org.lwjgl.opengl.GL30.GL_MAP_WRITE_BIT; +import static org.lwjgl.opengl.GL40.GL_DRAW_INDIRECT_BUFFER; +import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BUFFER; +import static org.lwjgl.opengl.GL44.GL_DYNAMIC_STORAGE_BIT; +import static org.lwjgl.opengl.GL44.GL_MAP_PERSISTENT_BIT; +import static org.lwjgl.opengl.GL44.nglBindBuffersRange; +import static org.lwjgl.opengl.GL45.glCopyNamedBufferSubData; import static org.lwjgl.opengl.GL45.glCreateBuffers; -import static org.lwjgl.opengl.GL46.*; +import static org.lwjgl.opengl.GL45.glFlushMappedNamedBufferRange; +import static org.lwjgl.opengl.GL45.glNamedBufferStorage; +import static org.lwjgl.opengl.GL45.nglCreateBuffers; +import static org.lwjgl.opengl.GL45.nglMapNamedBufferRange; +import static org.lwjgl.opengl.GL45.nglNamedBufferSubData; import org.lwjgl.system.MemoryUtil; import org.lwjgl.system.Pointer; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectCullingGroup.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectCullingGroup.java index 1e042eaff..acfd540ad 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectCullingGroup.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectCullingGroup.java @@ -1,15 +1,15 @@ package com.jozufozu.flywheel.backend.instancing.indirect; +import static org.lwjgl.opengl.GL30.glBindVertexArray; +import static org.lwjgl.opengl.GL30.glDeleteVertexArrays; import static org.lwjgl.opengl.GL42.GL_COMMAND_BARRIER_BIT; import static org.lwjgl.opengl.GL42.glMemoryBarrier; import static org.lwjgl.opengl.GL43.GL_SHADER_STORAGE_BARRIER_BIT; -import static org.lwjgl.opengl.GL46.glBindVertexArray; -import static org.lwjgl.opengl.GL46.glCreateVertexArrays; -import static org.lwjgl.opengl.GL46.glDeleteVertexArrays; -import static org.lwjgl.opengl.GL46.glDispatchCompute; -import static org.lwjgl.opengl.GL46.glEnableVertexArrayAttrib; -import static org.lwjgl.opengl.GL46.glVertexArrayElementBuffer; -import static org.lwjgl.opengl.GL46.glVertexArrayVertexBuffer; +import static org.lwjgl.opengl.GL43.glDispatchCompute; +import static org.lwjgl.opengl.GL45.glCreateVertexArrays; +import static org.lwjgl.opengl.GL45.glEnableVertexArrayAttrib; +import static org.lwjgl.opengl.GL45.glVertexArrayElementBuffer; +import static org.lwjgl.opengl.GL45.glVertexArrayVertexBuffer; import com.jozufozu.flywheel.api.RenderStage; import com.jozufozu.flywheel.api.instancer.InstancedPart; diff --git a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java index 3b17cd3e4..5a30d526a 100644 --- a/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java +++ b/src/main/java/com/jozufozu/flywheel/backend/instancing/indirect/IndirectEngine.java @@ -16,9 +16,9 @@ import com.jozufozu.flywheel.backend.instancing.Engine; import com.jozufozu.flywheel.backend.instancing.InstanceManager; import com.jozufozu.flywheel.backend.instancing.TaskExecutor; import com.jozufozu.flywheel.core.RenderContext; +import com.jozufozu.flywheel.core.context.SimpleContext; import com.jozufozu.flywheel.core.model.Model; import com.jozufozu.flywheel.util.FlwUtil; -import com.jozufozu.flywheel.core.context.SimpleContext; import com.mojang.blaze3d.systems.RenderSystem; import net.minecraft.client.Camera; diff --git a/src/main/java/com/jozufozu/flywheel/core/RenderContext.java b/src/main/java/com/jozufozu/flywheel/core/RenderContext.java index f6c99b41a..21125364a 100644 --- a/src/main/java/com/jozufozu/flywheel/core/RenderContext.java +++ b/src/main/java/com/jozufozu/flywheel/core/RenderContext.java @@ -1,9 +1,9 @@ package com.jozufozu.flywheel.core; import org.jetbrains.annotations.NotNull; +import org.joml.FrustumIntersection; import com.jozufozu.flywheel.util.MatrixUtil; -import com.jozufozu.flywheel.util.joml.FrustumIntersection; import com.mojang.blaze3d.vertex.PoseStack; import com.mojang.math.Matrix4f; @@ -23,7 +23,7 @@ public record RenderContext(LevelRenderer renderer, ClientLevel level, PoseStack } public static FrustumIntersection createCuller(Matrix4f viewProjection, float camX, float camY, float camZ) { - com.jozufozu.flywheel.util.joml.Matrix4f proj = MatrixUtil.toJoml(viewProjection); + org.joml.Matrix4f proj = MatrixUtil.toJoml(viewProjection); proj.translate(camX, camY, camZ); diff --git a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java index 8e29f75ee..d633b074a 100644 --- a/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java +++ b/src/main/java/com/jozufozu/flywheel/core/hardcoded/ModelPart.java @@ -2,6 +2,9 @@ package com.jozufozu.flywheel.core.hardcoded; import java.util.List; +import org.joml.Vector4f; +import org.joml.Vector4fc; + import com.jozufozu.flywheel.api.vertex.MutableVertexList; import com.jozufozu.flywheel.api.vertex.ReusableVertexList; import com.jozufozu.flywheel.backend.memory.MemoryBlock; @@ -9,8 +12,6 @@ import com.jozufozu.flywheel.core.model.Mesh; import com.jozufozu.flywheel.core.model.ModelUtil; import com.jozufozu.flywheel.core.vertex.Formats; import com.jozufozu.flywheel.core.vertex.PosTexNormalVertex; -import com.jozufozu.flywheel.util.joml.Vector4f; -import com.jozufozu.flywheel.util.joml.Vector4fc; public class ModelPart implements Mesh { private final int vertexCount; diff --git a/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java index bfa7adb55..7abae09cb 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/Mesh.java @@ -1,10 +1,11 @@ package com.jozufozu.flywheel.core.model; +import org.joml.Vector4fc; + import com.jozufozu.flywheel.api.vertex.MutableVertexList; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.instancing.instancing.ElementBuffer; import com.jozufozu.flywheel.core.QuadConverter; -import com.jozufozu.flywheel.util.joml.Vector4fc; /** * A holder for arbitrary vertex data that can be written to memory or a vertex list. diff --git a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java index 546846c60..bb2deb571 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/ModelUtil.java @@ -4,6 +4,7 @@ import java.lang.reflect.Field; import java.nio.ByteBuffer; import org.jetbrains.annotations.Nullable; +import org.joml.Vector4f; import org.lwjgl.system.MemoryUtil; import com.dreizak.miniball.highdim.Miniball; @@ -17,7 +18,6 @@ import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.memory.MemoryBlock; import com.jozufozu.flywheel.core.Materials; import com.jozufozu.flywheel.core.vertex.Formats; -import com.jozufozu.flywheel.util.joml.Vector4f; import com.mojang.blaze3d.vertex.BufferBuilder.DrawState; import com.mojang.blaze3d.vertex.VertexFormat; import com.mojang.datafixers.util.Pair; diff --git a/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java b/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java index 5d2a6236c..cd901b6ad 100644 --- a/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java +++ b/src/main/java/com/jozufozu/flywheel/core/model/SimpleMesh.java @@ -1,11 +1,12 @@ package com.jozufozu.flywheel.core.model; +import org.joml.Vector4f; +import org.joml.Vector4fc; + import com.jozufozu.flywheel.api.vertex.MutableVertexList; import com.jozufozu.flywheel.api.vertex.ReusableVertexList; import com.jozufozu.flywheel.api.vertex.VertexType; import com.jozufozu.flywheel.backend.memory.MemoryBlock; -import com.jozufozu.flywheel.util.joml.Vector4f; -import com.jozufozu.flywheel.util.joml.Vector4fc; public class SimpleMesh implements Mesh { private final VertexType vertexType; diff --git a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java index 4e6e33c1d..7c30d67c8 100644 --- a/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java +++ b/src/main/java/com/jozufozu/flywheel/core/source/SourceFile.java @@ -1,6 +1,10 @@ package com.jozufozu.flywheel.core.source; -import java.util.*; +import java.util.Collection; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.Optional; import java.util.regex.Matcher; import com.google.common.collect.ImmutableList; diff --git a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java index c8e31702a..a1d8ec095 100644 --- a/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java +++ b/src/main/java/com/jozufozu/flywheel/util/FlwUtil.java @@ -6,10 +6,10 @@ import java.util.Set; import java.util.WeakHashMap; import java.util.stream.Stream; +import org.joml.Math; +import org.joml.Matrix4f; import org.lwjgl.system.MemoryUtil; -import com.jozufozu.flywheel.util.joml.Math; -import com.jozufozu.flywheel.util.joml.Matrix4f; import com.mojang.blaze3d.vertex.PoseStack; public class FlwUtil { diff --git a/src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java b/src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java index dbd1c7b12..57b96de79 100644 --- a/src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java +++ b/src/main/java/com/jozufozu/flywheel/util/MatrixUtil.java @@ -63,7 +63,7 @@ public class MatrixUtil { buf.putFloat(m.flywheel$m22()); } - public static void store(Matrix4f matrix, com.jozufozu.flywheel.util.joml.Matrix4f jomlMatrix) { + public static void store(Matrix4f matrix, org.joml.Matrix4f jomlMatrix) { Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix; jomlMatrix.set( m.flywheel$m00(), m.flywheel$m10(), m.flywheel$m20(), m.flywheel$m30(), @@ -73,9 +73,9 @@ public class MatrixUtil { ); } - public static com.jozufozu.flywheel.util.joml.Matrix4f toJoml(Matrix4f matrix) { + public static org.joml.Matrix4f toJoml(Matrix4f matrix) { Matrix4fAccessor m = (Matrix4fAccessor) (Object) matrix; - return new com.jozufozu.flywheel.util.joml.Matrix4f( + return new org.joml.Matrix4f( m.flywheel$m00(), m.flywheel$m10(), m.flywheel$m20(), m.flywheel$m30(), m.flywheel$m01(), m.flywheel$m11(), m.flywheel$m21(), m.flywheel$m31(), m.flywheel$m02(), m.flywheel$m12(), m.flywheel$m22(), m.flywheel$m32(), @@ -96,7 +96,7 @@ public class MatrixUtil { MemoryUtil.memPutFloat(ptr + 32, m.flywheel$m22()); } - public static void store(Matrix3f matrix, com.jozufozu.flywheel.util.joml.Matrix3f jomlMatrix) { + public static void store(Matrix3f matrix, org.joml.Matrix3f jomlMatrix) { Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix; jomlMatrix.set( m.flywheel$m00(), m.flywheel$m10(), m.flywheel$m20(), @@ -105,9 +105,9 @@ public class MatrixUtil { ); } - public static com.jozufozu.flywheel.util.joml.Matrix3f toJoml(Matrix3f matrix) { + public static org.joml.Matrix3f toJoml(Matrix3f matrix) { Matrix3fAccessor m = (Matrix3fAccessor) (Object) matrix; - return new com.jozufozu.flywheel.util.joml.Matrix3f( + return new org.joml.Matrix3f( m.flywheel$m00(), m.flywheel$m10(), m.flywheel$m20(), m.flywheel$m01(), m.flywheel$m11(), m.flywheel$m21(), m.flywheel$m02(), m.flywheel$m12(), m.flywheel$m22() diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/AxisAngle4f.java b/src/main/java/com/jozufozu/flywheel/util/joml/AxisAngle4f.java deleted file mode 100644 index 9c565514c..000000000 --- a/src/main/java/com/jozufozu/flywheel/util/joml/AxisAngle4f.java +++ /dev/null @@ -1,543 +0,0 @@ -/* - * The MIT License - * - * Copyright (c) 2015-2021 Kai Burjack - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ -package com.jozufozu.flywheel.util.joml; - -import java.io.Externalizable; -import java.io.IOException; -import java.io.ObjectInput; -import java.io.ObjectOutput; -import java.text.DecimalFormat; -import java.text.NumberFormat; - -/** - * Represents a 3D rotation of a given radians about an axis represented as an - * unit 3D vector. - *
- * This class uses single-precision components.
- *
- * @author Kai Burjack
- */
-public class AxisAngle4f implements Externalizable, Cloneable {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * The angle in radians.
- */
- public float angle;
- /**
- * The x-component of the rotation axis.
- */
- public float x;
- /**
- * The y-component of the rotation axis.
- */
- public float y;
- /**
- * The z-component of the rotation axis.
- */
- public float z;
-
- /**
- * Create a new {@link AxisAngle4f} with zero rotation about (0, 0, 1)
.
- */
- public AxisAngle4f() {
- z = 1.0f;
- }
-
- /**
- * Create a new {@link AxisAngle4f} with the same values of a
.
- *
- * @param a
- * the AngleAxis4f to copy the values from
- */
- public AxisAngle4f(AxisAngle4f a) {
- x = a.x;
- y = a.y;
- z = a.z;
- angle = (float) ((a.angle < 0.0 ? Math.PI + Math.PI + a.angle % (Math.PI + Math.PI) : a.angle) % (Math.PI + Math.PI));
- }
-
- /**
- * Create a new {@link AxisAngle4f} from the given {@link Quaternionfc}.
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param q
- * the quaternion from which to create the new AngleAxis4f
- */
- public AxisAngle4f(Quaternionfc q) {
- float acos = Math.safeAcos(q.w());
- float invSqrt = Math.invsqrt(1.0f - q.w() * q.w());
- if (Float.isInfinite(invSqrt)) {
- this.x = 0.0f;
- this.y = 0.0f;
- this.z = 1.0f;
- } else {
- this.x = q.x() * invSqrt;
- this.y = q.y() * invSqrt;
- this.z = q.z() * invSqrt;
- }
- this.angle = acos + acos;
- }
-
- /**
- * Create a new {@link AxisAngle4f} with the given values.
- *
- * @param angle
- * the angle in radians
- * @param x
- * the x-coordinate of the rotation axis
- * @param y
- * the y-coordinate of the rotation axis
- * @param z
- * the z-coordinate of the rotation axis
- */
- public AxisAngle4f(float angle, float x, float y, float z) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.angle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
- }
-
- /**
- * Create a new {@link AxisAngle4f} with the given values.
- *
- * @param angle the angle in radians
- * @param v the rotation axis as a {@link Vector3f}
- */
- public AxisAngle4f(float angle, Vector3fc v) {
- this(angle, v.x(), v.y(), v.z());
- }
-
- /**
- * Set this {@link AxisAngle4f} to the values of a
.
- *
- * @param a
- * the AngleAxis4f to copy the values from
- * @return this
- */
- public AxisAngle4f set(AxisAngle4f a) {
- x = a.x;
- y = a.y;
- z = a.z;
- angle = a.angle;
- angle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
- return this;
- }
-
- /**
- * Set this {@link AxisAngle4f} to the given values.
- *
- * @param angle
- * the angle in radians
- * @param x
- * the x-coordinate of the rotation axis
- * @param y
- * the y-coordinate of the rotation axis
- * @param z
- * the z-coordinate of the rotation axis
- * @return this
- */
- public AxisAngle4f set(float angle, float x, float y, float z) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.angle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
- return this;
- }
-
- /**
- * Set this {@link AxisAngle4f} to the given values.
- *
- * @param angle
- * the angle in radians
- * @param v
- * the rotation axis as a {@link Vector3f}
- * @return this
- */
- public AxisAngle4f set(float angle, Vector3fc v) {
- return set(angle, v.x(), v.y(), v.z());
- }
-
- /**
- * Set this {@link AxisAngle4f} to be equivalent to the given
- * {@link Quaternionfc}.
- *
- * @param q
- * the quaternion to set this AngleAxis4f from
- * @return this
- */
- public AxisAngle4f set(Quaternionfc q) {
- float acos = Math.safeAcos(q.w());
- float invSqrt = Math.invsqrt(1.0f - q.w() * q.w());
- if (Float.isInfinite(invSqrt)) {
- this.x = 0.0f;
- this.y = 0.0f;
- this.z = 1.0f;
- } else {
- this.x = q.x() * invSqrt;
- this.y = q.y() * invSqrt;
- this.z = q.z() * invSqrt;
- }
- this.angle = acos + acos;
- return this;
- }
-
- /**
- * Set this {@link AxisAngle4f} to be equivalent to the rotation
- * of the given {@link Matrix3fc}.
- *
- * Reference: http://www.euclideanspace.com - * - * @param m - * the Matrix3fc to set this AngleAxis4f from - * @return this - */ - public AxisAngle4f set(Matrix3fc m) { - float nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02(); - float nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12(); - float nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22(); - float lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02()); - float lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12()); - float lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22()); - nm00 *= lenX; nm01 *= lenX; nm02 *= lenX; - nm10 *= lenY; nm11 *= lenY; nm12 *= lenY; - nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ; - float epsilon = 1E-4f, epsilon2 = 1E-3f; - if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) { - if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2 - && Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) { - x = 0; - y = 0; - z = 1; - angle = 0; - return this; - } - angle = Math.PI_f; - float xx = (nm00 + 1) / 2; - float yy = (nm11 + 1) / 2; - float zz = (nm22 + 1) / 2; - float xy = (nm10 + nm01) / 4; - float xz = (nm20 + nm02) / 4; - float yz = (nm21 + nm12) / 4; - if ((xx > yy) && (xx > zz)) { - x = Math.sqrt(xx); - y = xy / x; - z = xz / x; - } else if (yy > zz) { - y = Math.sqrt(yy); - x = xy / y; - z = yz / y; - } else { - z = Math.sqrt(zz); - x = xz / z; - y = yz / z; - } - return this; - } - float s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10)); - angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2); - x = (nm12 - nm21) / s; - y = (nm20 - nm02) / s; - z = (nm01 - nm10) / s; - return this; - } - - /** - * Set this {@link AxisAngle4f} to be equivalent to the rotational component - * of the given {@link Matrix4fc}. - *
- * Reference: http://www.euclideanspace.com - * - * @param m - * the Matrix4fc to set this AngleAxis4f from - * @return this - */ - public AxisAngle4f set(Matrix4fc m) { - float nm00 = m.m00(), nm01 = m.m01(), nm02 = m.m02(); - float nm10 = m.m10(), nm11 = m.m11(), nm12 = m.m12(); - float nm20 = m.m20(), nm21 = m.m21(), nm22 = m.m22(); - float lenX = Math.invsqrt(m.m00() * m.m00() + m.m01() * m.m01() + m.m02() * m.m02()); - float lenY = Math.invsqrt(m.m10() * m.m10() + m.m11() * m.m11() + m.m12() * m.m12()); - float lenZ = Math.invsqrt(m.m20() * m.m20() + m.m21() * m.m21() + m.m22() * m.m22()); - nm00 *= lenX; nm01 *= lenX; nm02 *= lenX; - nm10 *= lenY; nm11 *= lenY; nm12 *= lenY; - nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ; - float epsilon = 1E-4f, epsilon2 = 1E-3f; - if (Math.abs(nm10 - nm01) < epsilon && Math.abs(nm20 - nm02) < epsilon && Math.abs(nm21 - nm12) < epsilon) { - if (Math.abs(nm10 + nm01) < epsilon2 && Math.abs(nm20 + nm02) < epsilon2 && Math.abs(nm21 + nm12) < epsilon2 - && Math.abs(nm00 + nm11 + nm22 - 3) < epsilon2) { - x = 0; - y = 0; - z = 1; - angle = 0; - return this; - } - angle = Math.PI_f; - float xx = (nm00 + 1) / 2; - float yy = (nm11 + 1) / 2; - float zz = (nm22 + 1) / 2; - float xy = (nm10 + nm01) / 4; - float xz = (nm20 + nm02) / 4; - float yz = (nm21 + nm12) / 4; - if ((xx > yy) && (xx > zz)) { - x = Math.sqrt(xx); - y = xy / x; - z = xz / x; - } else if (yy > zz) { - y = Math.sqrt(yy); - x = xy / y; - z = yz / y; - } else { - z = Math.sqrt(zz); - x = xz / z; - y = yz / z; - } - return this; - } - float s = Math.sqrt((nm12 - nm21) * (nm12 - nm21) + (nm20 - nm02) * (nm20 - nm02) + (nm01 - nm10) * (nm01 - nm10)); - angle = Math.safeAcos((nm00 + nm11 + nm22 - 1) / 2); - x = (nm12 - nm21) / s; - y = (nm20 - nm02) / s; - z = (nm01 - nm10) / s; - return this; - } - - /** - * Set the given {@link Quaternionf} to be equivalent to this {@link AxisAngle4f} rotation. - * - * @see Quaternionf#set(AxisAngle4f) - * - * @param q - * the quaternion to set - * @return q - */ - public Quaternionf get(Quaternionf q) { - return q.set(this); - } - - /** - * Set the given {@link Matrix4f} to a rotation transformation equivalent to this {@link AxisAngle4f}. - * - * @see Matrix4f#set(AxisAngle4f) - * - * @param m - * the matrix to set - * @return m - */ - public Matrix4f get(Matrix4f m) { - return m.set(this); - } - - /** - * Set the given {@link Matrix3f} to a rotation transformation equivalent to this {@link AxisAngle4f}. - * - * @see Matrix3f#set(AxisAngle4f) - * - * @param m - * the matrix to set - * @return m - */ - public Matrix3f get(Matrix3f m) { - return m.set(this); - } - - /** - * Set the given {@link AxisAngle4f} to this {@link AxisAngle4f}. - * - * @param dest - * will hold the result - * @return dest - */ - public AxisAngle4f get(AxisAngle4f dest) { - return dest.set(this); - } - - public void writeExternal(ObjectOutput out) throws IOException { - out.writeFloat(angle); - out.writeFloat(x); - out.writeFloat(y); - out.writeFloat(z); - } - - public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { - angle = in.readFloat(); - x = in.readFloat(); - y = in.readFloat(); - z = in.readFloat(); - } - - /** - * Normalize the axis vector. - * - * @return this - */ - public AxisAngle4f normalize() { - float invLength = Math.invsqrt(x * x + y * y + z * z); - x *= invLength; - y *= invLength; - z *= invLength; - return this; - } - - /** - * Increase the rotation angle by the given amount. - *
- * This method also takes care of wrapping around.
- *
- * @param ang
- * the angle increase
- * @return this
- */
- public AxisAngle4f rotate(float ang) {
- angle += ang;
- angle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
- return this;
- }
-
- /**
- * Transform the given vector by the rotation transformation described by this {@link AxisAngle4f}.
- *
- * @param v
- * the vector to transform
- * @return v
- */
- public Vector3f transform(Vector3f v) {
- return transform(v, v);
- }
-
- /**
- * Transform the given vector by the rotation transformation described by this {@link AxisAngle4f}
- * and store the result in dest
.
- *
- * @param v
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- public Vector3f transform(Vector3fc v, Vector3f dest) {
- double sin = Math.sin(angle);
- double cos = Math.cosFromSin(sin, angle);
- float dot = x * v.x() + y * v.y() + z * v.z();
- dest.set((float) (v.x() * cos + sin * (y * v.z() - z * v.y()) + (1.0 - cos) * dot * x),
- (float) (v.y() * cos + sin * (z * v.x() - x * v.z()) + (1.0 - cos) * dot * y),
- (float) (v.z() * cos + sin * (x * v.y() - y * v.x()) + (1.0 - cos) * dot * z));
- return dest;
- }
-
- /**
- * Transform the given vector by the rotation transformation described by this {@link AxisAngle4f}.
- *
- * @param v
- * the vector to transform
- * @return v
- */
- public Vector4f transform(Vector4f v) {
- return transform(v, v);
- }
-
- /**
- * Transform the given vector by the rotation transformation described by this {@link AxisAngle4f}
- * and store the result in dest
.
- *
- * @param v
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- public Vector4f transform(Vector4fc v, Vector4f dest) {
- double sin = Math.sin(angle);
- double cos = Math.cosFromSin(sin, angle);
- float dot = x * v.x() + y * v.y() + z * v.z();
- dest.set((float) (v.x() * cos + sin * (y * v.z() - z * v.y()) + (1.0 - cos) * dot * x),
- (float) (v.y() * cos + sin * (z * v.x() - x * v.z()) + (1.0 - cos) * dot * y),
- (float) (v.z() * cos + sin * (x * v.y() - y * v.x()) + (1.0 - cos) * dot * z),
- dest.w);
- return dest;
- }
-
- /**
- * Return a string representation of this {@link AxisAngle4f}.
- *
- * This method creates a new {@link DecimalFormat} on every invocation with the format string " 0.000E0;-
".
- *
- * @return the string representation
- */
- public String toString() {
- return Runtime.formatNumbers(toString(Options.NUMBER_FORMAT));
- }
-
- /**
- * Return a string representation of this {@link AxisAngle4f} by formatting the components with the given {@link NumberFormat}.
- *
- * @param formatter
- * the {@link NumberFormat} used to format the vector components with
- * @return the string representation
- */
- public String toString(NumberFormat formatter) {
- return "(" + Runtime.format(x, formatter) + " " + Runtime.format(y, formatter) + " " + Runtime.format(z, formatter) + " <| " + Runtime.format(angle, formatter) + ")";
- }
-
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- float nangle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
- result = prime * result + Float.floatToIntBits(nangle);
- result = prime * result + Float.floatToIntBits(x);
- result = prime * result + Float.floatToIntBits(y);
- result = prime * result + Float.floatToIntBits(z);
- return result;
- }
-
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- AxisAngle4f other = (AxisAngle4f) obj;
- float nangle = (float) ((angle < 0.0 ? Math.PI + Math.PI + angle % (Math.PI + Math.PI) : angle) % (Math.PI + Math.PI));
- float nangleOther = (float) ((other.angle < 0.0 ? Math.PI + Math.PI + other.angle % (Math.PI + Math.PI) : other.angle) % (Math.PI + Math.PI));
- if (Float.floatToIntBits(nangle) != Float.floatToIntBits(nangleOther))
- return false;
- if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x))
- return false;
- if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y))
- return false;
- if (Float.floatToIntBits(z) != Float.floatToIntBits(other.z))
- return false;
- return true;
- }
-
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/ConfigurationException.java b/src/main/java/com/jozufozu/flywheel/util/joml/ConfigurationException.java
deleted file mode 100644
index 134865954..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/ConfigurationException.java
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2020-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-/**
- * Exception thrown when using an invalid JOML runtime configuration.
- *
- * @author Kai Burjack
- */
-public class ConfigurationException extends RuntimeException {
- private static final long serialVersionUID = -7832356906364070687L;
- public ConfigurationException(String message, Throwable cause) {
- super(message, cause);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/FrustumIntersection.java b/src/main/java/com/jozufozu/flywheel/util/joml/FrustumIntersection.java
deleted file mode 100644
index 30e9dc05a..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/FrustumIntersection.java
+++ /dev/null
@@ -1,992 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 Kai Burjack
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.nio.ByteBuffer;
-
-import org.lwjgl.system.MemoryUtil;
-/**
- * Efficiently performs frustum intersection tests by caching the frustum planes of an arbitrary transformation {@link Matrix4fc matrix}.
- *
- * This class is preferred over the frustum intersection methods in {@link Matrix4fc} when many objects need to be culled by the same static frustum.
- *
- * @author Kai Burjack
- */
-public class FrustumIntersection {
-
- /**
- * Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
- * and its different overloads identifying the plane with equation
- * In order to update the compute frustum planes later on, call {@link #set(Matrix4fc)}.
- *
- * @see #set(Matrix4fc)
- *
- * @param m
- * the {@link Matrix4fc} to create the frustum culler from
- */
- public FrustumIntersection(Matrix4fc m) {
- set(m, true);
- }
-
- /**
- * Create a new {@link FrustumIntersection} from the given {@link Matrix4fc matrix} by extracing the matrix's frustum planes.
- *
- * In order to update the compute frustum planes later on, call {@link #set(Matrix4fc)}.
- *
- * @see #set(Matrix4fc)
- *
- * @param m
- * the {@link Matrix4fc} to create the frustum culler from
- * @param allowTestSpheres
- * whether the methods {@link #testSphere(Vector3fc, float)}, {@link #testSphere(float, float, float, float)},
- * {@link #intersectSphere(Vector3fc, float)} or {@link #intersectSphere(float, float, float, float)} will used.
- * If no spheres need to be tested, then
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @param m
- * the {@link Matrix4fc matrix} to update
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @param m
- * the {@link Matrix4fc matrix} to update
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns {@link #INTERSECT} for spheres that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * @param center
- * the sphere's center
- * @param radius
- * the sphere's radius
- * @return {@link #INSIDE} if the given sphere is completely inside the frustum, or {@link #INTERSECT} if the sphere intersects
- * the frustum, or {@link #OUTSIDE} if the sphere is outside of the frustum
- */
- public int intersectSphere(Vector3fc center, float radius) {
- return intersectSphere(center.x(), center.y(), center.z(), radius);
- }
-
- /**
- * Determine whether the given sphere is partly or completely within or outside of the frustum defined by
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns {@link #INTERSECT} for spheres that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * @param x
- * the x-coordinate of the sphere's center
- * @param y
- * the y-coordinate of the sphere's center
- * @param z
- * the z-coordinate of the sphere's center
- * @param r
- * the sphere's radius
- * @return {@link #INSIDE} if the given sphere is completely inside the frustum, or {@link #INTERSECT} if the sphere intersects
- * the frustum, or {@link #OUTSIDE} if the sphere is outside of the frustum
- */
- public int intersectSphere(float x, float y, float z, float r) {
- boolean inside = true;
- float dist;
- dist = nxX * x + nxY * y + nxZ * z + nxW;
- if (dist >= -r) {
- inside &= dist >= r;
- dist = pxX * x + pxY * y + pxZ * z + pxW;
- if (dist >= -r) {
- inside &= dist >= r;
- dist = nyX * x + nyY * y + nyZ * z + nyW;
- if (dist >= -r) {
- inside &= dist >= r;
- dist = pyX * x + pyY * y + pyZ * z + pyW;
- if (dist >= -r) {
- inside &= dist >= r;
- dist = nzX * x + nzY * y + nzZ * z + nzW;
- if (dist >= -r) {
- inside &= dist >= r;
- dist = pzX * x + pzY * y + pzZ * z + pzW;
- if (dist >= -r) {
- inside &= dist >= r;
- return inside ? INSIDE : INTERSECT;
- }
- }
- }
- }
- }
- }
- return OUTSIDE;
- }
-
- /**
- * Test whether the given axis-aligned box is partly or completely within or outside of the frustum defined by
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns
- * Reference: Efficient View Frustum Culling
- *
- * @param minX
- * the x-coordinate of the minimum corner
- * @param minY
- * the y-coordinate of the minimum corner
- * @param minZ
- * the z-coordinate of the minimum corner
- * @param maxX
- * the x-coordinate of the maximum corner
- * @param maxY
- * the y-coordinate of the maximum corner
- * @param maxZ
- * the z-coordinate of the maximum corner
- * @return
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns
- * Reference: Efficient View Frustum Culling
- *
- * @param minX
- * the x-coordinate of the minimum corner
- * @param minY
- * the y-coordinate of the minimum corner
- * @param maxX
- * the x-coordinate of the maximum corner
- * @param maxY
- * the y-coordinate of the maximum corner
- * @return
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns
- * Reference: Efficient View Frustum Culling
- *
- * @param minX
- * the x-coordinate of the minimum corner
- * @param minZ
- * the z-coordinate of the minimum corner
- * @param maxX
- * the x-coordinate of the maximum corner
- * @param maxZ
- * the z-coordinate of the maximum corner
- * @return
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * @param min
- * the minimum corner coordinates of the axis-aligned box
- * @param max
- * the maximum corner coordinates of the axis-aligned box
- * @return the index of the first plane that culled the box, if the box does not intersect the frustum;
- * or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
- * The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
- */
- public int intersectAab(Vector3fc min, Vector3fc max) {
- return intersectAab(min.x(), min.y(), min.z(), max.x(), max.y(), max.z());
- }
-
- /**
- * Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * Reference: Efficient View Frustum Culling
- *
- * @param minX
- * the x-coordinate of the minimum corner
- * @param minY
- * the y-coordinate of the minimum corner
- * @param minZ
- * the z-coordinate of the minimum corner
- * @param maxX
- * the x-coordinate of the maximum corner
- * @param maxY
- * the y-coordinate of the maximum corner
- * @param maxZ
- * the z-coordinate of the maximum corner
- * @return the index of the first plane that culled the box, if the box does not intersect the frustum,
- * or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
- * The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
- */
- public int intersectAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- /*
- * This is an implementation of the "2.4 Basic intersection test" of the mentioned site.
- *
- * In addition to the algorithm in the paper, this method also returns the index of the first plane that culled the box.
- */
- int plane = PLANE_NX;
- boolean inside = true;
- if (nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW) {
- plane = PLANE_PX;
- inside &= nxX * (nxX < 0 ? maxX : minX) + nxY * (nxY < 0 ? maxY : minY) + nxZ * (nxZ < 0 ? maxZ : minZ) >= -nxW;
- if (pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW) {
- plane = PLANE_NY;
- inside &= pxX * (pxX < 0 ? maxX : minX) + pxY * (pxY < 0 ? maxY : minY) + pxZ * (pxZ < 0 ? maxZ : minZ) >= -pxW;
- if (nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW) {
- plane = PLANE_PY;
- inside &= nyX * (nyX < 0 ? maxX : minX) + nyY * (nyY < 0 ? maxY : minY) + nyZ * (nyZ < 0 ? maxZ : minZ) >= -nyW;
- if (pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW) {
- plane = PLANE_NZ;
- inside &= pyX * (pyX < 0 ? maxX : minX) + pyY * (pyY < 0 ? maxY : minY) + pyZ * (pyZ < 0 ? maxZ : minZ) >= -pyW;
- if (nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW) {
- plane = PLANE_PZ;
- inside &= nzX * (nzX < 0 ? maxX : minX) + nzY * (nzY < 0 ? maxY : minY) + nzZ * (nzZ < 0 ? maxZ : minZ) >= -nzW;
- if (pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW) {
- inside &= pzX * (pzX < 0 ? maxX : minX) + pzY * (pzY < 0 ? maxY : minY) + pzZ * (pzZ < 0 ? maxZ : minZ) >= -pzW;
- return inside ? INSIDE : INTERSECT;
- }
- }
- }
- }
- }
- }
- return plane;
- }
-
- /**
- * Compute the signed distance from the given axis-aligned box to the
- * This method differs from {@link #intersectAab(Vector3fc, Vector3fc)} in that
- * it allows to mask-off planes that should not be calculated. For example, in order to only test a box against the
- * left frustum plane, use a mask of {@link #PLANE_MASK_NX}. Or in order to test all planes except the left plane, use
- * a mask of
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * @param min
- * the minimum corner coordinates of the axis-aligned box
- * @param max
- * the maximum corner coordinates of the axis-aligned box
- * @param mask
- * contains as bitset all the planes that should be tested.
- * This value can be any combination of
- * {@link #PLANE_MASK_NX}, {@link #PLANE_MASK_PX},
- * {@link #PLANE_MASK_NY}, {@link #PLANE_MASK_PY},
- * {@link #PLANE_MASK_NZ} and {@link #PLANE_MASK_PZ}
- * @return the index of the first plane that culled the box, if the box does not intersect the frustum,
- * or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
- * The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
- */
- public int intersectAab(Vector3fc min, Vector3fc max, int mask) {
- return intersectAab(min.x(), min.y(), min.z(), max.x(), max.y(), max.z(), mask);
- }
-
- /**
- * Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by
- * This method differs from {@link #intersectAab(float, float, float, float, float, float)} in that
- * it allows to mask-off planes that should not be calculated. For example, in order to only test a box against the
- * left frustum plane, use a mask of {@link #PLANE_MASK_NX}. Or in order to test all planes except the left plane, use
- * a mask of
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * Reference: Efficient View Frustum Culling
- *
- * @param minX
- * the x-coordinate of the minimum corner
- * @param minY
- * the y-coordinate of the minimum corner
- * @param minZ
- * the z-coordinate of the minimum corner
- * @param maxX
- * the x-coordinate of the maximum corner
- * @param maxY
- * the y-coordinate of the maximum corner
- * @param maxZ
- * the z-coordinate of the maximum corner
- * @param mask
- * contains as bitset all the planes that should be tested.
- * This value can be any combination of
- * {@link #PLANE_MASK_NX}, {@link #PLANE_MASK_PX},
- * {@link #PLANE_MASK_NY}, {@link #PLANE_MASK_PY},
- * {@link #PLANE_MASK_NZ} and {@link #PLANE_MASK_PZ}
- * @return the index of the first plane that culled the box, if the box does not intersect the frustum,
- * or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
- * The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
- */
- public int intersectAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, int mask) {
- /*
- * This is an implementation of the first algorithm in "2.5 Plane masking and coherency" of the mentioned site.
- *
- * In addition to the algorithm in the paper, this method also returns the index of the first plane that culled the box.
- */
- int plane = PLANE_NX;
- boolean inside = true;
- if ((mask & PLANE_MASK_NX) == 0 || nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW) {
- plane = PLANE_PX;
- inside &= nxX * (nxX < 0 ? maxX : minX) + nxY * (nxY < 0 ? maxY : minY) + nxZ * (nxZ < 0 ? maxZ : minZ) >= -nxW;
- if ((mask & PLANE_MASK_PX) == 0 || pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW) {
- plane = PLANE_NY;
- inside &= pxX * (pxX < 0 ? maxX : minX) + pxY * (pxY < 0 ? maxY : minY) + pxZ * (pxZ < 0 ? maxZ : minZ) >= -pxW;
- if ((mask & PLANE_MASK_NY) == 0 || nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW) {
- plane = PLANE_PY;
- inside &= nyX * (nyX < 0 ? maxX : minX) + nyY * (nyY < 0 ? maxY : minY) + nyZ * (nyZ < 0 ? maxZ : minZ) >= -nyW;
- if ((mask & PLANE_MASK_PY) == 0 || pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW) {
- plane = PLANE_NZ;
- inside &= pyX * (pyX < 0 ? maxX : minX) + pyY * (pyY < 0 ? maxY : minY) + pyZ * (pyZ < 0 ? maxZ : minZ) >= -pyW;
- if ((mask & PLANE_MASK_NZ) == 0 || nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW) {
- plane = PLANE_PZ;
- inside &= nzX * (nzX < 0 ? maxX : minX) + nzY * (nzY < 0 ? maxY : minY) + nzZ * (nzZ < 0 ? maxZ : minZ) >= -nzW;
- if ((mask & PLANE_MASK_PZ) == 0 || pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW) {
- inside &= pzX * (pzX < 0 ? maxX : minX) + pzY * (pzY < 0 ? maxY : minY) + pzZ * (pzZ < 0 ? maxZ : minZ) >= -pzW;
- return inside ? INSIDE : INTERSECT;
- }
- }
- }
- }
- }
- }
- return plane;
- }
-
- /**
- * Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by
- * This method differs from {@link #intersectAab(Vector3fc, Vector3fc)} in that
- * it allows to mask-off planes that should not be calculated. For example, in order to only test a box against the
- * left frustum plane, use a mask of {@link #PLANE_MASK_NX}. Or in order to test all planes except the left plane, use
- * a mask of
- * In addition, the
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * @param min
- * the minimum corner coordinates of the axis-aligned box
- * @param max
- * the maximum corner coordinates of the axis-aligned box
- * @param mask
- * contains as bitset all the planes that should be tested.
- * This value can be any combination of
- * {@link #PLANE_MASK_NX}, {@link #PLANE_MASK_PX},
- * {@link #PLANE_MASK_NY}, {@link #PLANE_MASK_PY},
- * {@link #PLANE_MASK_NZ} and {@link #PLANE_MASK_PZ}
- * @param startPlane
- * the first frustum plane to test the axis-aligned box against. It is one of
- * {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
- * @return the index of the first plane that culled the box, if the box does not intersect the frustum,
- * or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
- * The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
- */
- public int intersectAab(Vector3fc min, Vector3fc max, int mask, int startPlane) {
- return intersectAab(min.x(), min.y(), min.z(), max.x(), max.y(), max.z(), mask, startPlane);
- }
-
- /**
- * Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by
- * This method differs from {@link #intersectAab(float, float, float, float, float, float)} in that
- * it allows to mask-off planes that should not be calculated. For example, in order to only test a box against the
- * left frustum plane, use a mask of {@link #PLANE_MASK_NX}. Or in order to test all planes except the left plane, use
- * a mask of
- * In addition, the
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns {@link #INTERSECT} for boxes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * Reference: Efficient View Frustum Culling
- *
- * @param minX
- * the x-coordinate of the minimum corner
- * @param minY
- * the y-coordinate of the minimum corner
- * @param minZ
- * the z-coordinate of the minimum corner
- * @param maxX
- * the x-coordinate of the maximum corner
- * @param maxY
- * the y-coordinate of the maximum corner
- * @param maxZ
- * the z-coordinate of the maximum corner
- * @param mask
- * contains as bitset all the planes that should be tested.
- * This value can be any combination of
- * {@link #PLANE_MASK_NX}, {@link #PLANE_MASK_PX},
- * {@link #PLANE_MASK_NY}, {@link #PLANE_MASK_PY},
- * {@link #PLANE_MASK_NZ} and {@link #PLANE_MASK_PZ}
- * @param startPlane
- * the first frustum plane to test the axis-aligned box against. It is one of
- * {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
- * @return the index of the first plane that culled the box, if the box does not intersect the frustum,
- * or {@link #INTERSECT} if the box intersects the frustum, or {@link #INSIDE} if the box is fully inside of the frustum.
- * The plane index is one of {@link #PLANE_NX}, {@link #PLANE_PX}, {@link #PLANE_NY}, {@link #PLANE_PY}, {@link #PLANE_NZ} and {@link #PLANE_PZ}
- */
- public int intersectAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, int mask, int startPlane) {
- /*
- * This is an implementation of the second algorithm in "2.5 Plane masking and coherency" of the mentioned site.
- *
- * In addition to the algorithm in the paper, this method also returns the index of the first plane that culled the box.
- */
- int plane = startPlane;
- boolean inside = true;
- Vector4f p = planes[startPlane];
- if ((mask & 1<
- * This can be used to compute the eye-rays in simple software-based raycasting/raytracing.
- *
- * To obtain the origin of the rays call {@link #origin(Vector3f)}.
- * Then to compute the directions of subsequent rays use {@link #dir(float, float, Vector3f)}.
- *
- * @author Kai Burjack
- */
-public class FrustumRayBuilder {
-
- private float nxnyX, nxnyY, nxnyZ;
- private float pxnyX, pxnyY, pxnyZ;
- private float pxpyX, pxpyY, pxpyZ;
- private float nxpyX, nxpyY, nxpyZ;
- private float cx, cy, cz;
-
- /**
- * Create a new {@link FrustumRayBuilder} with an undefined frustum.
- *
- * Before obtaining ray directions, make sure to define the frustum using {@link #set(Matrix4fc)}.
- */
- public FrustumRayBuilder() {
- }
-
- /**
- * Create a new {@link FrustumRayBuilder} from the given {@link Matrix4fc matrix} by extracing the matrix's frustum.
- *
- * @param m
- * the {@link Matrix4fc} to create the frustum from
- */
- public FrustumRayBuilder(Matrix4fc m) {
- set(m);
- }
-
- /**
- * Update the stored frustum corner rays and origin of
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * Reference: http://geomalgorithms.com
- *
- * @param m
- * the {@link Matrix4fc matrix} to update the frustum corner rays and origin with
- * @return this
- */
- public FrustumRayBuilder set(Matrix4fc m) {
- float nxX = m.m03() + m.m00(), nxY = m.m13() + m.m10(), nxZ = m.m23() + m.m20(), d1 = m.m33() + m.m30();
- float pxX = m.m03() - m.m00(), pxY = m.m13() - m.m10(), pxZ = m.m23() - m.m20(), d2 = m.m33() - m.m30();
- float nyX = m.m03() + m.m01(), nyY = m.m13() + m.m11(), nyZ = m.m23() + m.m21();
- float pyX = m.m03() - m.m01(), pyY = m.m13() - m.m11(), pyZ = m.m23() - m.m21(), d3 = m.m33() - m.m31();
- // bottom left
- nxnyX = nyY * nxZ - nyZ * nxY;
- nxnyY = nyZ * nxX - nyX * nxZ;
- nxnyZ = nyX * nxY - nyY * nxX;
- // bottom right
- pxnyX = pxY * nyZ - pxZ * nyY;
- pxnyY = pxZ * nyX - pxX * nyZ;
- pxnyZ = pxX * nyY - pxY * nyX;
- // top left
- nxpyX = nxY * pyZ - nxZ * pyY;
- nxpyY = nxZ * pyX - nxX * pyZ;
- nxpyZ = nxX * pyY - nxY * pyX;
- // top right
- pxpyX = pyY * pxZ - pyZ * pxY;
- pxpyY = pyZ * pxX - pyX * pxZ;
- pxpyZ = pyX * pxY - pyY * pxX;
- // compute origin
- float pxnxX, pxnxY, pxnxZ;
- pxnxX = pxY * nxZ - pxZ * nxY;
- pxnxY = pxZ * nxX - pxX * nxZ;
- pxnxZ = pxX * nxY - pxY * nxX;
- float invDot = 1.0f / (nxX * pxpyX + nxY * pxpyY + nxZ * pxpyZ);
- cx = (-pxpyX * d1 - nxpyX * d2 - pxnxX * d3) * invDot;
- cy = (-pxpyY * d1 - nxpyY * d2 - pxnxY * d3) * invDot;
- cz = (-pxpyZ * d1 - nxpyZ * d2 - pxnxZ * d3) * invDot;
- return this;
- }
-
- /**
- * Store the eye/origin of the perspective frustum in the given
- * The parameters
- * By default, {@link java.lang.Math} methods will be used by all other JOML classes. In order to use the approximations in this class, start the JVM with the parameter
- * There are two algorithms for approximating sin/cos:
- *
- * m00 m10 m20
- * That FloatBuffer is expected to hold the values in column-major order.
- *
- * The buffer's position will not be changed by this method.
- *
- * @param buffer
- * the {@link FloatBuffer} to read the matrix values from
- */
- public Matrix3f(FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- }
-
- /**
- * Create a new {@link Matrix3f} and initialize its three columns using the supplied vectors.
- *
- * @param col0
- * the first column
- * @param col1
- * the second column
- * @param col2
- * the third column
- */
- public Matrix3f(Vector3fc col0, Vector3fc col1, Vector3fc col2) {
- set(col0, col1, col2);
- }
-
- public float m00() {
- return m00;
- }
- public float m01() {
- return m01;
- }
- public float m02() {
- return m02;
- }
- public float m10() {
- return m10;
- }
- public float m11() {
- return m11;
- }
- public float m12() {
- return m12;
- }
- public float m20() {
- return m20;
- }
- public float m21() {
- return m21;
- }
- public float m22() {
- return m22;
- }
-
- /**
- * Set the value of the matrix element at column 0 and row 0.
- *
- * @param m00
- * the new value
- * @return this
- */
- public Matrix3f m00(float m00) {
- this.m00 = m00;
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 1.
- *
- * @param m01
- * the new value
- * @return this
- */
- public Matrix3f m01(float m01) {
- this.m01 = m01;
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 2.
- *
- * @param m02
- * the new value
- * @return this
- */
- public Matrix3f m02(float m02) {
- this.m02 = m02;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 0.
- *
- * @param m10
- * the new value
- * @return this
- */
- public Matrix3f m10(float m10) {
- this.m10 = m10;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 1.
- *
- * @param m11
- * the new value
- * @return this
- */
- public Matrix3f m11(float m11) {
- this.m11 = m11;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 2.
- *
- * @param m12
- * the new value
- * @return this
- */
- public Matrix3f m12(float m12) {
- this.m12 = m12;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 0.
- *
- * @param m20
- * the new value
- * @return this
- */
- public Matrix3f m20(float m20) {
- this.m20 = m20;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 1.
- *
- * @param m21
- * the new value
- * @return this
- */
- public Matrix3f m21(float m21) {
- this.m21 = m21;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 2.
- *
- * @param m22
- * the new value
- * @return this
- */
- public Matrix3f m22(float m22) {
- this.m22 = m22;
- return this;
- }
-
- /**
- * Set the value of the matrix element at column 0 and row 0.
- *
- * @param m00
- * the new value
- * @return this
- */
- Matrix3f _m00(float m00) {
- this.m00 = m00;
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 1.
- *
- * @param m01
- * the new value
- * @return this
- */
- Matrix3f _m01(float m01) {
- this.m01 = m01;
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 2.
- *
- * @param m02
- * the new value
- * @return this
- */
- Matrix3f _m02(float m02) {
- this.m02 = m02;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 0.
- *
- * @param m10
- * the new value
- * @return this
- */
- Matrix3f _m10(float m10) {
- this.m10 = m10;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 1.
- *
- * @param m11
- * the new value
- * @return this
- */
- Matrix3f _m11(float m11) {
- this.m11 = m11;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 2.
- *
- * @param m12
- * the new value
- * @return this
- */
- Matrix3f _m12(float m12) {
- this.m12 = m12;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 0.
- *
- * @param m20
- * the new value
- * @return this
- */
- Matrix3f _m20(float m20) {
- this.m20 = m20;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 1.
- *
- * @param m21
- * the new value
- * @return this
- */
- Matrix3f _m21(float m21) {
- this.m21 = m21;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 2.
- *
- * @param m22
- * the new value
- * @return this
- */
- Matrix3f _m22(float m22) {
- this.m22 = m22;
- return this;
- }
-
- /**
- * Set the elements of this matrix to the ones in
- * This method is equivalent to calling:
- * Reference: http://www.euclideanspace.com/
- *
- * @see #rotation(Quaternionfc)
- *
- * @param q
- * the {@link Quaternionfc}
- * @return this
- */
- public Matrix3f set(Quaternionfc q) {
- return rotation(q);
- }
-
- /**
- * Multiply this matrix by the supplied
- * If
- * If
- * m00, m10, m20
- * 0, 3, 6
- * This method creates a new {@link DecimalFormat} on every invocation with the format string "
- * This is the reverse method of {@link #set(Matrix3fc)} and allows to obtain
- * intermediate calculation results when chaining multiple transformations.
- *
- * @see #set(Matrix3fc)
- *
- * @param dest
- * the destination matrix
- * @return the passed in destination
- */
- public Matrix3f get(Matrix3f dest) {
- return dest.set(this);
- }
-
- public Matrix4f get(Matrix4f dest) {
- return dest.set(this);
- }
-
- public AxisAngle4f getRotation(AxisAngle4f dest) {
- return dest.set(this);
- }
-
- public Quaternionf getUnnormalizedRotation(Quaternionf dest) {
- return dest.setFromUnnormalized(this);
- }
-
- public Quaternionf getNormalizedRotation(Quaternionf dest) {
- return dest.setFromNormalized(this);
- }
-
- public FloatBuffer get(FloatBuffer buffer) {
- return get(buffer.position(), buffer);
- }
-
- public FloatBuffer get(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.put(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer get(ByteBuffer buffer) {
- return get(buffer.position(), buffer);
- }
-
- public ByteBuffer get(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.put(this, index, buffer);
- return buffer;
- }
-
- public FloatBuffer get3x4(FloatBuffer buffer) {
- return get3x4(buffer.position(), buffer);
- }
-
- public FloatBuffer get3x4(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.put3x4(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer get3x4(ByteBuffer buffer) {
- return get3x4(buffer.position(), buffer);
- }
-
- public ByteBuffer get3x4(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.put3x4(this, index, buffer);
- return buffer;
- }
-
- public FloatBuffer getTransposed(FloatBuffer buffer) {
- return getTransposed(buffer.position(), buffer);
- }
-
- public FloatBuffer getTransposed(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.putTransposed(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer getTransposed(ByteBuffer buffer) {
- return getTransposed(buffer.position(), buffer);
- }
-
- public ByteBuffer getTransposed(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.putTransposed(this, index, buffer);
- return buffer;
- }
-
- public Matrix3fc getToAddress(long address) {
- if (Options.NO_UNSAFE)
- throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
- MemUtil.MemUtilUnsafe.put(this, address);
- return this;
- }
-
- public float[] get(float[] arr, int offset) {
- MemUtil.INSTANCE.copy(this, arr, offset);
- return arr;
- }
-
- public float[] get(float[] arr) {
- return get(arr, 0);
- }
-
- /**
- * Set the values of this matrix by reading 9 float values from the given {@link FloatBuffer} in column-major order,
- * starting at its current position.
- *
- * The FloatBuffer is expected to contain the values in column-major order.
- *
- * The position of the FloatBuffer will not be changed by this method.
- *
- * @param buffer
- * the FloatBuffer to read the matrix values from in column-major order
- * @return this
- */
- public Matrix3f set(FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- return this;
- }
-
- /**
- * Set the values of this matrix by reading 9 float values from the given {@link ByteBuffer} in column-major order,
- * starting at its current position.
- *
- * The ByteBuffer is expected to contain the values in column-major order.
- *
- * The position of the ByteBuffer will not be changed by this method.
- *
- * @param buffer
- * the ByteBuffer to read the matrix values from in column-major order
- * @return this
- */
- public Matrix3f set(ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- return this;
- }
-
- /**
- * Set the values of this matrix by reading 9 float values from the given {@link FloatBuffer} in column-major order,
- * starting at the specified absolute buffer position/index.
- *
- * The FloatBuffer is expected to contain the values in column-major order.
- *
- * The position of the FloatBuffer will not be changed by this method.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * the FloatBuffer to read the matrix values from in column-major order
- * @return this
- */
- public Matrix3f set(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- return this;
- }
-
- /**
- * Set the values of this matrix by reading 9 float values from the given {@link ByteBuffer} in column-major order,
- * starting at the specified absolute buffer position/index.
- *
- * The ByteBuffer is expected to contain the values in column-major order.
- *
- * The position of the ByteBuffer will not be changed by this method.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * the ByteBuffer to read the matrix values from in column-major order
- * @return this
- */
- public Matrix3f set(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- return this;
- }
- /**
- * Set the values of this matrix by reading 9 float values from off-heap memory in column-major order,
- * starting at the given address.
- *
- * This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
- *
- * This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
- *
- * @param address
- * the off-heap memory address to read the matrix values from in column-major order
- * @return this
- */
- public Matrix3f setFromAddress(long address) {
- if (Options.NO_UNSAFE)
- throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
- MemUtil.MemUtilUnsafe.get(this, address);
- return this;
- }
-
- /**
- * Set all values within this matrix to zero.
- *
- * @return this
- */
- public Matrix3f zero() {
- MemUtil.INSTANCE.zero(this);
- return this;
- }
-
- /**
- * Set this matrix to the identity.
- *
- * @return this
- */
- public Matrix3f identity() {
- MemUtil.INSTANCE.identity(this);
- return this;
- }
-
- public Matrix3f scale(Vector3fc xyz, Matrix3f dest) {
- return scale(xyz.x(), xyz.y(), xyz.z(), dest);
- }
-
- /**
- * Apply scaling to this matrix by scaling the base axes by the given
- * If
- * If
- * If
- * If
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional scaling.
- *
- * In order to post-multiply a scaling transformation directly to a
- * matrix, use {@link #scale(float) scale()} instead.
- *
- * @see #scale(float)
- *
- * @param factor
- * the scale factor in x, y and z
- * @return this
- */
- public Matrix3f scaling(float factor) {
- MemUtil.INSTANCE.zero(this);
- m00 = factor;
- m11 = factor;
- m22 = factor;
- return this;
- }
-
- /**
- * Set this matrix to be a simple scale matrix.
- *
- * @param x
- * the scale in x
- * @param y
- * the scale in y
- * @param z
- * the scale in z
- * @return this
- */
- public Matrix3f scaling(float x, float y, float z) {
- MemUtil.INSTANCE.zero(this);
- m00 = x;
- m11 = y;
- m22 = z;
- return this;
- }
-
- /**
- * Set this matrix to be a simple scale matrix which scales the base axes by
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional scaling.
- *
- * In order to post-multiply a scaling transformation directly to a
- * matrix use {@link #scale(Vector3fc) scale()} instead.
- *
- * @see #scale(Vector3fc)
- *
- * @param xyz
- * the scale in x, y and z respectively
- * @return this
- */
- public Matrix3f scaling(Vector3fc xyz) {
- return scaling(xyz.x(), xyz.y(), xyz.z());
- }
-
- /**
- * Set this matrix to a rotation matrix which rotates the given radians about a given axis.
- *
- * The axis described by the
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional rotation.
- *
- * In order to post-multiply a rotation transformation directly to a
- * matrix, use {@link #rotate(float, Vector3fc) rotate()} instead.
- *
- * @see #rotate(float, Vector3fc)
- *
- * @param angle
- * the angle in radians
- * @param axis
- * the axis to rotate about (needs to be {@link Vector3f#normalize() normalized})
- * @return this
- */
- public Matrix3f rotation(float angle, Vector3fc axis) {
- return rotation(angle, axis.x(), axis.y(), axis.z());
- }
-
- /**
- * Set this matrix to a rotation transformation using the given {@link AxisAngle4f}.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional rotation.
- *
- * In order to apply the rotation transformation to an existing transformation,
- * use {@link #rotate(AxisAngle4f) rotate()} instead.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(AxisAngle4f)
- *
- * @param axisAngle
- * the {@link AxisAngle4f} (needs to be {@link AxisAngle4f#normalize() normalized})
- * @return this
- */
- public Matrix3f rotation(AxisAngle4f axisAngle) {
- return rotation(axisAngle.angle, axisAngle.x, axisAngle.y, axisAngle.z);
- }
-
- /**
- * Set this matrix to a rotation matrix which rotates the given radians about a given axis.
- *
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional rotation.
- *
- * In order to apply the rotation transformation to an existing transformation,
- * use {@link #rotate(float, float, float, float) rotate()} instead.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- *
- * @param angle
- * the angle in radians
- * @param x
- * the x-component of the rotation axis
- * @param y
- * the y-component of the rotation axis
- * @param z
- * the z-component of the rotation axis
- * @return this
- */
- public Matrix3f rotation(float angle, float x, float y, float z) {
- float sin = Math.sin(angle);
- float cos = Math.cosFromSin(sin, angle);
- float C = 1.0f - cos;
- float xy = x * y, xz = x * z, yz = y * z;
- m00 = cos + x * x * C;
- m10 = xy * C - z * sin;
- m20 = xz * C + y * sin;
- m01 = xy * C + z * sin;
- m11 = cos + y * y * C;
- m21 = yz * C - x * sin;
- m02 = xz * C - y * sin;
- m12 = yz * C + x * sin;
- m22 = cos + z * z * C;
- return this;
- }
-
- /**
- * Set this matrix to a rotation transformation about the X axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix3f rotationX(float ang) {
- float sin, cos;
- sin = Math.sin(ang);
- cos = Math.cosFromSin(sin, ang);
- m00 = 1.0f;
- m01 = 0.0f;
- m02 = 0.0f;
- m10 = 0.0f;
- m11 = cos;
- m12 = sin;
- m20 = 0.0f;
- m21 = -sin;
- m22 = cos;
- return this;
- }
-
- /**
- * Set this matrix to a rotation transformation about the Y axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix3f rotationY(float ang) {
- float sin, cos;
- sin = Math.sin(ang);
- cos = Math.cosFromSin(sin, ang);
- m00 = cos;
- m01 = 0.0f;
- m02 = -sin;
- m10 = 0.0f;
- m11 = 1.0f;
- m12 = 0.0f;
- m20 = sin;
- m21 = 0.0f;
- m22 = cos;
- return this;
- }
-
- /**
- * Set this matrix to a rotation transformation about the Z axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix3f rotationZ(float ang) {
- float sin, cos;
- sin = Math.sin(ang);
- cos = Math.cosFromSin(sin, ang);
- m00 = cos;
- m01 = sin;
- m02 = 0.0f;
- m10 = -sin;
- m11 = cos;
- m12 = 0.0f;
- m20 = 0.0f;
- m21 = 0.0f;
- m22 = 1.0f;
- return this;
- }
-
- /**
- * Set this matrix to a rotation of
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional rotation.
- *
- * In order to apply the rotation transformation to an existing transformation,
- * use {@link #rotate(Quaternionfc) rotate()} instead.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @return this
- */
- public Matrix3f rotation(Quaternionfc quat) {
- float w2 = quat.w() * quat.w();
- float x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y();
- float z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw;
- float xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz;
- float yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz;
- float xw = quat.x() * quat.w(), dxw = xw + xw;
- m00 = w2 + x2 - z2 - y2;
- m01 = dxy + dzw;
- m02 = dxz - dyw;
- m10 = -dzw + dxy;
- m11 = y2 - z2 + w2 - x2;
- m12 = dyz + dxw;
- m20 = dyw + dxz;
- m21 = dyz - dxw;
- m22 = z2 - y2 - x2 + w2;
- return this;
- }
-
- public Vector3f transform(Vector3f v) {
- return v.mul(this);
- }
-
- public Vector3f transform(Vector3fc v, Vector3f dest) {
- return v.mul(this, dest);
- }
-
- public Vector3f transform(float x, float y, float z, Vector3f dest) {
- return dest.set(Math.fma(m00, x, Math.fma(m10, y, m20 * z)),
- Math.fma(m01, x, Math.fma(m11, y, m21 * z)),
- Math.fma(m02, x, Math.fma(m12, y, m22 * z)));
- }
-
- public Vector3f transformTranspose(Vector3f v) {
- return v.mulTranspose(this);
- }
-
- public Vector3f transformTranspose(Vector3fc v, Vector3f dest) {
- return v.mulTranspose(this, dest);
- }
-
- public Vector3f transformTranspose(float x, float y, float z, Vector3f dest) {
- return dest.set(Math.fma(m00, x, Math.fma(m01, y, m02 * z)),
- Math.fma(m10, x, Math.fma(m11, y, m12 * z)),
- Math.fma(m20, x, Math.fma(m21, y, m22 * z)));
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeFloat(m00);
- out.writeFloat(m01);
- out.writeFloat(m02);
- out.writeFloat(m10);
- out.writeFloat(m11);
- out.writeFloat(m12);
- out.writeFloat(m20);
- out.writeFloat(m21);
- out.writeFloat(m22);
- }
-
- public void readExternal(ObjectInput in) throws IOException {
- m00 = in.readFloat();
- m01 = in.readFloat();
- m02 = in.readFloat();
- m10 = in.readFloat();
- m11 = in.readFloat();
- m12 = in.readFloat();
- m20 = in.readFloat();
- m21 = in.readFloat();
- m22 = in.readFloat();
- }
-
- public Matrix3f rotateX(float ang, Matrix3f dest) {
- float sin, cos;
- sin = Math.sin(ang);
- cos = Math.cosFromSin(sin, ang);
- float rm11 = cos;
- float rm21 = -sin;
- float rm12 = sin;
- float rm22 = cos;
-
- // add temporaries for dependent values
- float nm10 = m10 * rm11 + m20 * rm12;
- float nm11 = m11 * rm11 + m21 * rm12;
- float nm12 = m12 * rm11 + m22 * rm12;
- // set non-dependent values directly
- dest.m20 = m10 * rm21 + m20 * rm22;
- dest.m21 = m11 * rm21 + m21 * rm22;
- dest.m22 = m12 * rm21 + m22 * rm22;
- // set other values
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m00 = m00;
- dest.m01 = m01;
- dest.m02 = m02;
- return dest;
- }
-
- /**
- * Apply rotation about the X axis to this matrix by rotating the given amount of radians.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix3f rotateX(float ang) {
- return rotateX(ang, this);
- }
-
- public Matrix3f rotateY(float ang, Matrix3f dest) {
- float sin, cos;
- sin = Math.sin(ang);
- cos = Math.cosFromSin(sin, ang);
- float rm00 = cos;
- float rm20 = sin;
- float rm02 = -sin;
- float rm22 = cos;
-
- // add temporaries for dependent values
- float nm00 = m00 * rm00 + m20 * rm02;
- float nm01 = m01 * rm00 + m21 * rm02;
- float nm02 = m02 * rm00 + m22 * rm02;
- // set non-dependent values directly
- dest.m20 = m00 * rm20 + m20 * rm22;
- dest.m21 = m01 * rm20 + m21 * rm22;
- dest.m22 = m02 * rm20 + m22 * rm22;
- // set other values
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = m10;
- dest.m11 = m11;
- dest.m12 = m12;
- return dest;
- }
-
- /**
- * Apply rotation about the Y axis to this matrix by rotating the given amount of radians.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix3f rotateY(float ang) {
- return rotateY(ang, this);
- }
-
- public Matrix3f rotateZ(float ang, Matrix3f dest) {
- float sin, cos;
- sin = Math.sin(ang);
- cos = Math.cosFromSin(sin, ang);
- float rm00 = cos;
- float rm10 = -sin;
- float rm01 = sin;
- float rm11 = cos;
-
- // add temporaries for dependent values
- float nm00 = m00 * rm00 + m10 * rm01;
- float nm01 = m01 * rm00 + m11 * rm01;
- float nm02 = m02 * rm00 + m12 * rm01;
- // set non-dependent values directly
- dest.m10 = m00 * rm10 + m10 * rm11;
- dest.m11 = m01 * rm10 + m11 * rm11;
- dest.m12 = m02 * rm10 + m12 * rm11;
- // set other values
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m20 = m20;
- dest.m21 = m21;
- dest.m22 = m22;
- return dest;
- }
-
- /**
- * Apply rotation about the Z axis to this matrix by rotating the given amount of radians.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix3f rotateZ(float ang) {
- return rotateZ(ang, this);
- }
-
- /**
- * Apply rotation of
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @return this
- */
- public Matrix3f rotate(float ang, float x, float y, float z) {
- return rotate(ang, x, y, z, this);
- }
-
- public Matrix3f rotate(float ang, float x, float y, float z, Matrix3f dest) {
- float s = Math.sin(ang);
- float c = Math.cosFromSin(s, ang);
- float C = 1.0f - c;
-
- // rotation matrix elements:
- // m30, m31, m32, m03, m13, m23 = 0
- float xx = x * x, xy = x * y, xz = x * z;
- float yy = y * y, yz = y * z;
- float zz = z * z;
- float rm00 = xx * C + c;
- float rm01 = xy * C + z * s;
- float rm02 = xz * C - y * s;
- float rm10 = xy * C - z * s;
- float rm11 = yy * C + c;
- float rm12 = yz * C + x * s;
- float rm20 = xz * C + y * s;
- float rm21 = yz * C - x * s;
- float rm22 = zz * C + c;
-
- // add temporaries for dependent values
- float nm00 = m00 * rm00 + m10 * rm01 + m20 * rm02;
- float nm01 = m01 * rm00 + m11 * rm01 + m21 * rm02;
- float nm02 = m02 * rm00 + m12 * rm01 + m22 * rm02;
- float nm10 = m00 * rm10 + m10 * rm11 + m20 * rm12;
- float nm11 = m01 * rm10 + m11 * rm11 + m21 * rm12;
- float nm12 = m02 * rm10 + m12 * rm11 + m22 * rm12;
- // set non-dependent values directly
- dest.m20 = m00 * rm20 + m10 * rm21 + m20 * rm22;
- dest.m21 = m01 * rm20 + m11 * rm21 + m21 * rm22;
- dest.m22 = m02 * rm20 + m12 * rm21 + m22 * rm22;
- // set other values
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- return dest;
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians
- * about the specified
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotation(float, float, float, float) rotation()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(float, float, float, float)
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotateLocal(float ang, float x, float y, float z, Matrix3f dest) {
- float s = Math.sin(ang);
- float c = Math.cosFromSin(s, ang);
- float C = 1.0f - c;
- float xx = x * x, xy = x * y, xz = x * z;
- float yy = y * y, yz = y * z;
- float zz = z * z;
- float lm00 = xx * C + c;
- float lm01 = xy * C + z * s;
- float lm02 = xz * C - y * s;
- float lm10 = xy * C - z * s;
- float lm11 = yy * C + c;
- float lm12 = yz * C + x * s;
- float lm20 = xz * C + y * s;
- float lm21 = yz * C - x * s;
- float lm22 = zz * C + c;
- float nm00 = lm00 * m00 + lm10 * m01 + lm20 * m02;
- float nm01 = lm01 * m00 + lm11 * m01 + lm21 * m02;
- float nm02 = lm02 * m00 + lm12 * m01 + lm22 * m02;
- float nm10 = lm00 * m10 + lm10 * m11 + lm20 * m12;
- float nm11 = lm01 * m10 + lm11 * m11 + lm21 * m12;
- float nm12 = lm02 * m10 + lm12 * m11 + lm22 * m12;
- float nm20 = lm00 * m20 + lm10 * m21 + lm20 * m22;
- float nm21 = lm01 * m20 + lm11 * m21 + lm21 * m22;
- float nm22 = lm02 * m20 + lm12 * m21 + lm22 * m22;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m20 = nm20;
- dest.m21 = nm21;
- dest.m22 = nm22;
- return dest;
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians
- * about the specified
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotation(float, float, float, float) rotation()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(float, float, float, float)
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @return this
- */
- public Matrix3f rotateLocal(float ang, float x, float y, float z) {
- return rotateLocal(ang, x, y, z, this);
- }
-
- /**
- * Pre-multiply a rotation around the X axis to this matrix by rotating the given amount of radians
- * about the X axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationX(float) rotationX()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationX(float)
- *
- * @param ang
- * the angle in radians to rotate about the X axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotateLocalX(float ang, Matrix3f dest) {
- float sin = Math.sin(ang);
- float cos = Math.cosFromSin(sin, ang);
- float nm01 = cos * m01 - sin * m02;
- float nm02 = sin * m01 + cos * m02;
- float nm11 = cos * m11 - sin * m12;
- float nm12 = sin * m11 + cos * m12;
- float nm21 = cos * m21 - sin * m22;
- float nm22 = sin * m21 + cos * m22;
- dest.m00 = m00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = m10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m20 = m20;
- dest.m21 = nm21;
- dest.m22 = nm22;
- return dest;
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians about the X axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationX(float) rotationX()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationX(float)
- *
- * @param ang
- * the angle in radians to rotate about the X axis
- * @return this
- */
- public Matrix3f rotateLocalX(float ang) {
- return rotateLocalX(ang, this);
- }
-
- /**
- * Pre-multiply a rotation around the Y axis to this matrix by rotating the given amount of radians
- * about the Y axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationY(float) rotationY()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationY(float)
- *
- * @param ang
- * the angle in radians to rotate about the Y axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotateLocalY(float ang, Matrix3f dest) {
- float sin = Math.sin(ang);
- float cos = Math.cosFromSin(sin, ang);
- float nm00 = cos * m00 + sin * m02;
- float nm02 = -sin * m00 + cos * m02;
- float nm10 = cos * m10 + sin * m12;
- float nm12 = -sin * m10 + cos * m12;
- float nm20 = cos * m20 + sin * m22;
- float nm22 = -sin * m20 + cos * m22;
- dest.m00 = nm00;
- dest.m01 = m01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = m11;
- dest.m12 = nm12;
- dest.m20 = nm20;
- dest.m21 = m21;
- dest.m22 = nm22;
- return dest;
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians about the Y axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationY(float) rotationY()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationY(float)
- *
- * @param ang
- * the angle in radians to rotate about the Y axis
- * @return this
- */
- public Matrix3f rotateLocalY(float ang) {
- return rotateLocalY(ang, this);
- }
-
- /**
- * Pre-multiply a rotation around the Z axis to this matrix by rotating the given amount of radians
- * about the Z axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationZ(float) rotationZ()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationZ(float)
- *
- * @param ang
- * the angle in radians to rotate about the Z axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotateLocalZ(float ang, Matrix3f dest) {
- float sin = Math.sin(ang);
- float cos = Math.cosFromSin(sin, ang);
- float nm00 = cos * m00 - sin * m01;
- float nm01 = sin * m00 + cos * m01;
- float nm10 = cos * m10 - sin * m11;
- float nm11 = sin * m10 + cos * m11;
- float nm20 = cos * m20 - sin * m21;
- float nm21 = sin * m20 + cos * m21;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = m02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = m12;
- dest.m20 = nm20;
- dest.m21 = nm21;
- dest.m22 = m22;
- return dest;
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians about the Z axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationZ(float) rotationY()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationY(float)
- *
- * @param ang
- * the angle in radians to rotate about the Z axis
- * @return this
- */
- public Matrix3f rotateLocalZ(float ang) {
- return rotateLocalZ(ang, this);
- }
-
- /**
- * Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @return this
- */
- public Matrix3f rotate(Quaternionfc quat) {
- return rotate(quat, this);
- }
-
- /**
- * Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix and store
- * the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotate(Quaternionfc quat, Matrix3f dest) {
- float w2 = quat.w() * quat.w(), x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y(), z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw, xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz, yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz, xw = quat.x() * quat.w(), dxw = xw + xw;
- float rm00 = w2 + x2 - z2 - y2;
- float rm01 = dxy + dzw;
- float rm02 = dxz - dyw;
- float rm10 = dxy - dzw;
- float rm11 = y2 - z2 + w2 - x2;
- float rm12 = dyz + dxw;
- float rm20 = dyw + dxz;
- float rm21 = dyz - dxw;
- float rm22 = z2 - y2 - x2 + w2;
- float nm00 = m00 * rm00 + m10 * rm01 + m20 * rm02;
- float nm01 = m01 * rm00 + m11 * rm01 + m21 * rm02;
- float nm02 = m02 * rm00 + m12 * rm01 + m22 * rm02;
- float nm10 = m00 * rm10 + m10 * rm11 + m20 * rm12;
- float nm11 = m01 * rm10 + m11 * rm11 + m21 * rm12;
- float nm12 = m02 * rm10 + m12 * rm11 + m22 * rm12;
- dest.m20 = m00 * rm20 + m10 * rm21 + m20 * rm22;
- dest.m21 = m01 * rm20 + m11 * rm21 + m21 * rm22;
- dest.m22 = m02 * rm20 + m12 * rm21 + m22 * rm22;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- return dest;
- }
-
- /**
- * Pre-multiply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix and store
- * the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without pre-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotateLocal(Quaternionfc quat, Matrix3f dest) {
- float w2 = quat.w() * quat.w(), x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y(), z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw, xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz, yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz, xw = quat.x() * quat.w(), dxw = xw + xw;
- float lm00 = w2 + x2 - z2 - y2;
- float lm01 = dxy + dzw;
- float lm02 = dxz - dyw;
- float lm10 = dxy - dzw;
- float lm11 = y2 - z2 + w2 - x2;
- float lm12 = dyz + dxw;
- float lm20 = dyw + dxz;
- float lm21 = dyz - dxw;
- float lm22 = z2 - y2 - x2 + w2;
- float nm00 = lm00 * m00 + lm10 * m01 + lm20 * m02;
- float nm01 = lm01 * m00 + lm11 * m01 + lm21 * m02;
- float nm02 = lm02 * m00 + lm12 * m01 + lm22 * m02;
- float nm10 = lm00 * m10 + lm10 * m11 + lm20 * m12;
- float nm11 = lm01 * m10 + lm11 * m11 + lm21 * m12;
- float nm12 = lm02 * m10 + lm12 * m11 + lm22 * m12;
- float nm20 = lm00 * m20 + lm10 * m21 + lm20 * m22;
- float nm21 = lm01 * m20 + lm11 * m21 + lm21 * m22;
- float nm22 = lm02 * m20 + lm12 * m21 + lm22 * m22;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m20 = nm20;
- dest.m21 = nm21;
- dest.m22 = nm22;
- return dest;
- }
-
- /**
- * Pre-multiply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without pre-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @return this
- */
- public Matrix3f rotateLocal(Quaternionfc quat) {
- return rotateLocal(quat, this);
- }
-
- /**
- * Apply a rotation transformation, rotating about the given {@link AxisAngle4f}, to this matrix.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(AxisAngle4f)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- * @see #rotation(AxisAngle4f)
- *
- * @param axisAngle
- * the {@link AxisAngle4f} (needs to be {@link AxisAngle4f#normalize() normalized})
- * @return this
- */
- public Matrix3f rotate(AxisAngle4f axisAngle) {
- return rotate(axisAngle.angle, axisAngle.x, axisAngle.y, axisAngle.z);
- }
-
- /**
- * Apply a rotation transformation, rotating about the given {@link AxisAngle4f} and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(AxisAngle4f)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- * @see #rotation(AxisAngle4f)
- *
- * @param axisAngle
- * the {@link AxisAngle4f} (needs to be {@link AxisAngle4f#normalize() normalized})
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotate(AxisAngle4f axisAngle, Matrix3f dest) {
- return rotate(axisAngle.angle, axisAngle.x, axisAngle.y, axisAngle.z, dest);
- }
-
- /**
- * Apply a rotation transformation, rotating the given radians about the specified axis, to this matrix.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(float, Vector3fc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- * @see #rotation(float, Vector3fc)
- *
- * @param angle
- * the angle in radians
- * @param axis
- * the rotation axis (needs to be {@link Vector3f#normalize() normalized})
- * @return this
- */
- public Matrix3f rotate(float angle, Vector3fc axis) {
- return rotate(angle, axis.x(), axis.y(), axis.z());
- }
-
- /**
- * Apply a rotation transformation, rotating the given radians about the specified axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(float, Vector3fc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- * @see #rotation(float, Vector3fc)
- *
- * @param angle
- * the angle in radians
- * @param axis
- * the rotation axis (needs to be {@link Vector3f#normalize() normalized})
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotate(float angle, Vector3fc axis, Matrix3f dest) {
- return rotate(angle, axis.x(), axis.y(), axis.z(), dest);
- }
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * In order to set the matrix to a lookalong transformation without post-multiplying it,
- * use {@link #setLookAlong(Vector3fc, Vector3fc) setLookAlong()}.
- *
- * @see #lookAlong(float, float, float, float, float, float)
- * @see #setLookAlong(Vector3fc, Vector3fc)
- *
- * @param dir
- * the direction in space to look along
- * @param up
- * the direction of 'up'
- * @return this
- */
- public Matrix3f lookAlong(Vector3fc dir, Vector3fc up) {
- return lookAlong(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z(), this);
- }
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * In order to set the matrix to a lookalong transformation without post-multiplying it,
- * use {@link #setLookAlong(Vector3fc, Vector3fc) setLookAlong()}.
- *
- * @see #lookAlong(float, float, float, float, float, float)
- * @see #setLookAlong(Vector3fc, Vector3fc)
- *
- * @param dir
- * the direction in space to look along
- * @param up
- * the direction of 'up'
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f lookAlong(Vector3fc dir, Vector3fc up, Matrix3f dest) {
- return lookAlong(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z(), dest);
- }
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * In order to set the matrix to a lookalong transformation without post-multiplying it,
- * use {@link #setLookAlong(float, float, float, float, float, float) setLookAlong()}
- *
- * @see #setLookAlong(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f lookAlong(float dirX, float dirY, float dirZ,
- float upX, float upY, float upZ, Matrix3f dest) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= -invDirLength;
- dirY *= -invDirLength;
- dirZ *= -invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirY * leftZ - dirZ * leftY;
- float upnY = dirZ * leftX - dirX * leftZ;
- float upnZ = dirX * leftY - dirY * leftX;
-
- // calculate right matrix elements
- float rm00 = leftX;
- float rm01 = upnX;
- float rm02 = dirX;
- float rm10 = leftY;
- float rm11 = upnY;
- float rm12 = dirY;
- float rm20 = leftZ;
- float rm21 = upnZ;
- float rm22 = dirZ;
-
- // perform optimized matrix multiplication
- // introduce temporaries for dependent results
- float nm00 = m00 * rm00 + m10 * rm01 + m20 * rm02;
- float nm01 = m01 * rm00 + m11 * rm01 + m21 * rm02;
- float nm02 = m02 * rm00 + m12 * rm01 + m22 * rm02;
- float nm10 = m00 * rm10 + m10 * rm11 + m20 * rm12;
- float nm11 = m01 * rm10 + m11 * rm11 + m21 * rm12;
- float nm12 = m02 * rm10 + m12 * rm11 + m22 * rm12;
- dest.m20 = m00 * rm20 + m10 * rm21 + m20 * rm22;
- dest.m21 = m01 * rm20 + m11 * rm21 + m21 * rm22;
- dest.m22 = m02 * rm20 + m12 * rm21 + m22 * rm22;
- // set the rest of the matrix elements
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- return dest;
- }
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * In order to set the matrix to a lookalong transformation without post-multiplying it,
- * use {@link #setLookAlong(float, float, float, float, float, float) setLookAlong()}
- *
- * @see #setLookAlong(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix3f lookAlong(float dirX, float dirY, float dirZ,
- float upX, float upY, float upZ) {
- return lookAlong(dirX, dirY, dirZ, upX, upY, upZ, this);
- }
-
- /**
- * Set this matrix to a rotation transformation to make
- * In order to apply the lookalong transformation to any previous existing transformation,
- * use {@link #lookAlong(Vector3fc, Vector3fc)}.
- *
- * @see #setLookAlong(Vector3fc, Vector3fc)
- * @see #lookAlong(Vector3fc, Vector3fc)
- *
- * @param dir
- * the direction in space to look along
- * @param up
- * the direction of 'up'
- * @return this
- */
- public Matrix3f setLookAlong(Vector3fc dir, Vector3fc up) {
- return setLookAlong(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z());
- }
-
- /**
- * Set this matrix to a rotation transformation to make
- * In order to apply the lookalong transformation to any previous existing transformation,
- * use {@link #lookAlong(float, float, float, float, float, float) lookAlong()}
- *
- * @see #setLookAlong(float, float, float, float, float, float)
- * @see #lookAlong(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix3f setLookAlong(float dirX, float dirY, float dirZ,
- float upX, float upY, float upZ) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= -invDirLength;
- dirY *= -invDirLength;
- dirZ *= -invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirY * leftZ - dirZ * leftY;
- float upnY = dirZ * leftX - dirX * leftZ;
- float upnZ = dirX * leftY - dirY * leftX;
-
- m00 = leftX;
- m01 = upnX;
- m02 = dirX;
- m10 = leftY;
- m11 = upnY;
- m12 = dirY;
- m20 = leftZ;
- m21 = upnZ;
- m22 = dirZ;
-
- return this;
- }
-
- public Vector3f getRow(int row, Vector3f dest) throws IndexOutOfBoundsException {
- switch (row) {
- case 0:
- return dest.set(m00, m10, m20);
- case 1:
- return dest.set(m01, m11, m21);
- case 2:
- return dest.set(m02, m12, m22);
- default:
- throw new IndexOutOfBoundsException();
- }
- }
-
- /**
- * Set the row at the given
- * The normal matrix of
- * Please note that, if
- * The normal matrix of
- * Please note that, if
- * The cofactor matrix can be used instead of {@link #normal()} to transform normals
- * when the orientation of the normals with respect to the surface should be preserved.
- *
- * @return this
- */
- public Matrix3f cofactor() {
- return cofactor(this);
- }
-
- /**
- * Compute the cofactor matrix of
- * The cofactor matrix can be used instead of {@link #normal(Matrix3f)} to transform normals
- * when the orientation of the normals with respect to the surface should be preserved.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f cofactor(Matrix3f dest) {
- float nm00 = m11 * m22 - m21 * m12;
- float nm01 = m20 * m12 - m10 * m22;
- float nm02 = m10 * m21 - m20 * m11;
- float nm10 = m21 * m02 - m01 * m22;
- float nm11 = m00 * m22 - m20 * m02;
- float nm12 = m20 * m01 - m00 * m21;
- float nm20 = m01 * m12 - m11 * m02;
- float nm21 = m02 * m10 - m12 * m00;
- float nm22 = m00 * m11 - m10 * m01;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m20 = nm20;
- dest.m21 = nm21;
- dest.m22 = nm22;
- return dest;
- }
-
- public Vector3f getScale(Vector3f dest) {
- return dest.set(Math.sqrt(m00 * m00 + m01 * m01 + m02 * m02),
- Math.sqrt(m10 * m10 + m11 * m11 + m12 * m12),
- Math.sqrt(m20 * m20 + m21 * m21 + m22 * m22));
- }
-
- public Vector3f positiveZ(Vector3f dir) {
- dir.x = m10 * m21 - m11 * m20;
- dir.y = m20 * m01 - m21 * m00;
- dir.z = m00 * m11 - m01 * m10;
- return dir.normalize(dir);
- }
-
- public Vector3f normalizedPositiveZ(Vector3f dir) {
- dir.x = m02;
- dir.y = m12;
- dir.z = m22;
- return dir;
- }
-
- public Vector3f positiveX(Vector3f dir) {
- dir.x = m11 * m22 - m12 * m21;
- dir.y = m02 * m21 - m01 * m22;
- dir.z = m01 * m12 - m02 * m11;
- return dir.normalize(dir);
- }
-
- public Vector3f normalizedPositiveX(Vector3f dir) {
- dir.x = m00;
- dir.y = m10;
- dir.z = m20;
- return dir;
- }
-
- public Vector3f positiveY(Vector3f dir) {
- dir.x = m12 * m20 - m10 * m22;
- dir.y = m00 * m22 - m02 * m20;
- dir.z = m02 * m10 - m00 * m12;
- return dir.normalize(dir);
- }
-
- public Vector3f normalizedPositiveY(Vector3f dir) {
- dir.x = m01;
- dir.y = m11;
- dir.z = m21;
- return dir;
- }
-
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Float.floatToIntBits(m00);
- result = prime * result + Float.floatToIntBits(m01);
- result = prime * result + Float.floatToIntBits(m02);
- result = prime * result + Float.floatToIntBits(m10);
- result = prime * result + Float.floatToIntBits(m11);
- result = prime * result + Float.floatToIntBits(m12);
- result = prime * result + Float.floatToIntBits(m20);
- result = prime * result + Float.floatToIntBits(m21);
- result = prime * result + Float.floatToIntBits(m22);
- return result;
- }
-
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Matrix3f other = (Matrix3f) obj;
- if (Float.floatToIntBits(m00) != Float.floatToIntBits(other.m00))
- return false;
- if (Float.floatToIntBits(m01) != Float.floatToIntBits(other.m01))
- return false;
- if (Float.floatToIntBits(m02) != Float.floatToIntBits(other.m02))
- return false;
- if (Float.floatToIntBits(m10) != Float.floatToIntBits(other.m10))
- return false;
- if (Float.floatToIntBits(m11) != Float.floatToIntBits(other.m11))
- return false;
- if (Float.floatToIntBits(m12) != Float.floatToIntBits(other.m12))
- return false;
- if (Float.floatToIntBits(m20) != Float.floatToIntBits(other.m20))
- return false;
- if (Float.floatToIntBits(m21) != Float.floatToIntBits(other.m21))
- return false;
- if (Float.floatToIntBits(m22) != Float.floatToIntBits(other.m22))
- return false;
- return true;
- }
-
- public boolean equals(Matrix3fc m, float delta) {
- if (this == m)
- return true;
- if (m == null)
- return false;
- if (!(m instanceof Matrix3f))
- return false;
- if (!Runtime.equals(m00, m.m00(), delta))
- return false;
- if (!Runtime.equals(m01, m.m01(), delta))
- return false;
- if (!Runtime.equals(m02, m.m02(), delta))
- return false;
- if (!Runtime.equals(m10, m.m10(), delta))
- return false;
- if (!Runtime.equals(m11, m.m11(), delta))
- return false;
- if (!Runtime.equals(m12, m.m12(), delta))
- return false;
- if (!Runtime.equals(m20, m.m20(), delta))
- return false;
- if (!Runtime.equals(m21, m.m21(), delta))
- return false;
- if (!Runtime.equals(m22, m.m22(), delta))
- return false;
- return true;
- }
-
- /**
- * Exchange the values of
- * If
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying it,
- * use {@link #rotationTowards(Vector3fc, Vector3fc) rotationTowards()}.
- *
- * This method is equivalent to calling:
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying it,
- * use {@link #rotationTowards(Vector3fc, Vector3fc) rotationTowards()}.
- *
- * This method is equivalent to calling:
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying it,
- * use {@link #rotationTowards(float, float, float, float, float, float) rotationTowards()}.
- *
- * This method is equivalent to calling:
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying it,
- * use {@link #rotationTowards(float, float, float, float, float, float) rotationTowards()}.
- *
- * This method is equivalent to calling:
- * In order to apply the rotation transformation to a previous existing transformation,
- * use {@link #rotateTowards(float, float, float, float, float, float) rotateTowards}.
- *
- * This method is equivalent to calling:
- * In order to apply the rotation transformation to a previous existing transformation,
- * use {@link #rotateTowards(float, float, float, float, float, float) rotateTowards}.
- *
- * This method is equivalent to calling:
- * If
- * The oblique transformation is defined as:
- *
- * If
- * The oblique transformation is defined as:
- *
- * If
- * If
- * This method can be used to build a reflection transformation based on the orientation of a mirror object in the scene.
- * It is assumed that the default mirror plane's normal is
- * If
- * This method can be used to build a reflection transformation based on the orientation of a mirror object in the scene.
- * It is assumed that the default mirror plane's normal is
- * This {@link Matrix3fStack} class inherits from {@link Matrix3f}, so the current/top matrix is always the
- * {@link Matrix3fStack}/{@link Matrix3f} itself. This affects all operations in {@link Matrix3f} that take another
- * {@link Matrix3f} as parameter. If a {@link Matrix3fStack} is used as argument to those methods, the effective
- * argument will always be the current matrix of the matrix stack.
- *
- * @author Kai Burjack
- */
-public class Matrix3fStack extends Matrix3f {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix3fStack(int) constructor}.
- */
- private Matrix3f[] mats;
-
- /**
- * The index of the "current" matrix within {@link #mats}.
- */
- private int curr;
-
- /**
- * Create a new {@link Matrix3fStack} of the given size.
- *
- * Initially the stack pointer is at zero and the current matrix is set to identity.
- *
- * @param stackSize
- * the size of the stack. This must be at least 1, in which case the {@link Matrix3fStack} simply only consists of
- * Invoking this constructor from client code will result in an inconsistent state of the
- * created {@link Matrix3fStack} instance.
- */
- public Matrix3fStack() {
- /* Empty! */
- }
-
- /**
- * Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
- *
- * @return this
- */
- public Matrix3fStack clear() {
- curr = 0;
- identity();
- return this;
- }
-
- /**
- * Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
- *
- * @return this
- */
- public Matrix3fStack pushMatrix() {
- if (curr == mats.length) {
- throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
- }
- mats[curr++].set(this);
- return this;
- }
-
- /**
- * Decrement the stack pointer by one.
- *
- * This will effectively dispose of the current matrix.
- *
- * @return this
- */
- public Matrix3fStack popMatrix() {
- if (curr == 0) {
- throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
- }
- set(mats[--curr]);
- return this;
- }
-
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + curr;
- for (int i = 0; i < curr; i++) {
- result = prime * result + mats[i].hashCode();
- }
- return result;
- }
-
- /*
- * Contract between Matrix3f and Matrix3fStack:
- *
- * - Matrix3f.equals(Matrix3fStack) is true iff all the 9 matrix elements are equal
- * - Matrix3fStack.equals(Matrix3f) is true iff all the 9 matrix elements are equal
- * - Matrix3fStack.equals(Matrix3fStack) is true iff all 9 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
- * - everything else is inequal
- */
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!super.equals(obj))
- return false;
- if (obj instanceof Matrix3fStack) {
- Matrix3fStack other = (Matrix3fStack) obj;
- if (curr != other.curr)
- return false;
- for (int i = 0; i < curr; i++) {
- if (!mats[i].equals(other.mats[i]))
- return false;
- }
- }
- return true;
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- super.writeExternal(out);
- out.writeInt(curr);
- for (int i = 0; i < curr; i++) {
- out.writeObject(mats[i]);
- }
- }
-
- public void readExternal(ObjectInput in) throws IOException {
- super.readExternal(in);
- curr = in.readInt();
- mats = new Matrix3fStack[curr];
- for (int i = 0; i < curr; i++) {
- Matrix3f m = new Matrix3f();
- m.readExternal(in);
- mats[i] = m;
- }
- }
-
- public Object clone() throws CloneNotSupportedException {
- Matrix3fStack cloned = (Matrix3fStack) super.clone();
- Matrix3f[] clonedMats = new Matrix3f[mats.length];
- for (int i = 0; i < mats.length; i++)
- clonedMats[i] = (Matrix3f) mats[i].clone();
- cloned.mats = clonedMats;
- return cloned;
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix3fc.java b/src/main/java/com/jozufozu/flywheel/util/joml/Matrix3fc.java
deleted file mode 100644
index 1e42fa041..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix3fc.java
+++ /dev/null
@@ -1,2169 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2016-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.util.*;
-
-
-/**
- * Interface to a read-only view of a 3x3 matrix of single-precision floats.
- *
- * @author Kai Burjack
- */
-public interface Matrix3fc {
-
- /**
- * Return the value of the matrix element at column 0 and row 0.
- *
- * @return the value of the matrix element
- */
- float m00();
-
- /**
- * Return the value of the matrix element at column 0 and row 1.
- *
- * @return the value of the matrix element
- */
- float m01();
-
- /**
- * Return the value of the matrix element at column 0 and row 2.
- *
- * @return the value of the matrix element
- */
- float m02();
-
- /**
- * Return the value of the matrix element at column 1 and row 0.
- *
- * @return the value of the matrix element
- */
- float m10();
-
- /**
- * Return the value of the matrix element at column 1 and row 1.
- *
- * @return the value of the matrix element
- */
- float m11();
-
- /**
- * Return the value of the matrix element at column 1 and row 2.
- *
- * @return the value of the matrix element
- */
- float m12();
-
- /**
- * Return the value of the matrix element at column 2 and row 0.
- *
- * @return the value of the matrix element
- */
- float m20();
-
- /**
- * Return the value of the matrix element at column 2 and row 1.
- *
- * @return the value of the matrix element
- */
- float m21();
-
- /**
- * Return the value of the matrix element at column 2 and row 2.
- *
- * @return the value of the matrix element
- */
- float m22();
-
- /**
- * Multiply this matrix by the supplied
- * If
- * If
- * This method assumes that the three column vectors of this matrix are not normalized and
- * thus allows to ignore any additional scaling factor that is applied to the matrix.
- *
- * @see Quaternionf#setFromUnnormalized(Matrix3fc)
- *
- * @param dest
- * the destination {@link Quaternionf}
- * @return the passed in destination
- */
- Quaternionf getUnnormalizedRotation(Quaternionf dest);
-
- /**
- * Get the current values of
- * This method assumes that the three column vectors of this matrix are normalized.
- *
- * @see Quaternionf#setFromNormalized(Matrix3fc)
- *
- * @param dest
- * the destination {@link Quaternionf}
- * @return the passed in destination
- */
- Quaternionf getNormalizedRotation(Quaternionf dest);
-
- /**
- * Store this matrix in column-major order into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the matrix is stored, use {@link #get(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get(int, FloatBuffer)
- *
- * @param buffer
- * will receive the values of this matrix in column-major order at its current position
- * @return the passed in buffer
- */
- FloatBuffer get(FloatBuffer buffer);
-
- /**
- * Store this matrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of this matrix in column-major order
- * @return the passed in buffer
- */
- FloatBuffer get(int index, FloatBuffer buffer);
-
- /**
- * Store this matrix in column-major order into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the matrix is stored, use {@link #get(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get(int, ByteBuffer)
- *
- * @param buffer
- * will receive the values of this matrix in column-major order at its current position
- * @return the passed in buffer
- */
- ByteBuffer get(ByteBuffer buffer);
-
- /**
- * Store this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of this matrix in column-major order
- * @return the passed in buffer
- */
- ByteBuffer get(int index, ByteBuffer buffer);
-
- /**
- * Store this matrix as 3x4 matrix in column-major order into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}, with the m03, m13 and m23 components being zero.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the matrix is stored, use {@link #get3x4(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get3x4(int, FloatBuffer)
- *
- * @param buffer
- * will receive the values of this 3x3 matrix as 3x4 matrix in column-major order at its current position
- * @return the passed in buffer
- */
- FloatBuffer get3x4(FloatBuffer buffer);
-
- /**
- * Store this matrix as 3x4 matrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index, with the m03, m13 and m23 components being zero.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of this 3x3 matrix as 3x4 matrix in column-major order
- * @return the passed in buffer
- */
- FloatBuffer get3x4(int index, FloatBuffer buffer);
-
- /**
- * Store this matrix as 3x4 matrix in column-major order into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}, with the m03, m13 and m23 components being zero.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the matrix is stored, use {@link #get3x4(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get3x4(int, ByteBuffer)
- *
- * @param buffer
- * will receive the values of this 3x3 matrix as 3x4 matrix in column-major order at its current position
- * @return the passed in buffer
- */
- ByteBuffer get3x4(ByteBuffer buffer);
-
- /**
- * Store this matrix as 3x4 matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index, with the m03, m13 and m23 components being zero.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of this 3x3 matrix as 3x4 matrix in column-major order
- * @return the passed in buffer
- */
- ByteBuffer get3x4(int index, ByteBuffer buffer);
-
- /**
- * Store the transpose of this matrix in column-major order into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the matrix is stored, use {@link #getTransposed(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #getTransposed(int, FloatBuffer)
- *
- * @param buffer
- * will receive the values of this matrix in column-major order at its current position
- * @return the passed in buffer
- */
- FloatBuffer getTransposed(FloatBuffer buffer);
-
- /**
- * Store the transpose of this matrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of this matrix in column-major order
- * @return the passed in buffer
- */
- FloatBuffer getTransposed(int index, FloatBuffer buffer);
-
- /**
- * Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the matrix is stored, use {@link #getTransposed(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #getTransposed(int, ByteBuffer)
- *
- * @param buffer
- * will receive the values of this matrix in column-major order at its current position
- * @return the passed in buffer
- */
- ByteBuffer getTransposed(ByteBuffer buffer);
-
- /**
- * Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of this matrix in column-major order
- * @return the passed in buffer
- */
- ByteBuffer getTransposed(int index, ByteBuffer buffer);
-
- /**
- * Store this matrix in column-major order at the given off-heap address.
- *
- * This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
- *
- * This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
- *
- * @param address
- * the off-heap address where to store this matrix
- * @return this
- */
- Matrix3fc getToAddress(long address);
-
- /**
- * Store this matrix into the supplied float array in column-major order at the given offset.
- *
- * @param arr
- * the array to write the matrix values into
- * @param offset
- * the offset into the array
- * @return the passed in array
- */
- float[] get(float[] arr, int offset);
-
- /**
- * Store this matrix into the supplied float array in column-major order.
- *
- * In order to specify an explicit offset into the array, use the method {@link #get(float[], int)}.
- *
- * @see #get(float[], int)
- *
- * @param arr
- * the array to write the matrix values into
- * @return the passed in array
- */
- float[] get(float[] arr);
-
- /**
- * Apply scaling to
- * If
- * If
- * If
- * If
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateX(float ang, Matrix3f dest);
-
- /**
- * Apply rotation about the Y axis to this matrix by rotating the given amount of radians
- * and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateY(float ang, Matrix3f dest);
-
- /**
- * Apply rotation about the Z axis to this matrix by rotating the given amount of radians
- * and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateZ(float ang, Matrix3f dest);
-
- /**
- * Apply rotation of
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotate(float ang, float x, float y, float z, Matrix3f dest);
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians
- * about the specified
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateLocal(float ang, float x, float y, float z, Matrix3f dest);
-
- /**
- * Pre-multiply a rotation around the X axis to this matrix by rotating the given amount of radians
- * about the X axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians to rotate about the X axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateLocalX(float ang, Matrix3f dest);
-
- /**
- * Pre-multiply a rotation around the Y axis to this matrix by rotating the given amount of radians
- * about the Y axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians to rotate about the Y axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateLocalY(float ang, Matrix3f dest);
-
- /**
- * Pre-multiply a rotation around the Z axis to this matrix by rotating the given amount of radians
- * about the Z axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians to rotate about the Z axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateLocalZ(float ang, Matrix3f dest);
-
- /**
- * Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix and store
- * the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotate(Quaternionfc quat, Matrix3f dest);
-
- /**
- * Pre-multiply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix and store
- * the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateLocal(Quaternionfc quat, Matrix3f dest);
-
- /**
- * Apply a rotation transformation, rotating about the given {@link AxisAngle4f} and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float, Matrix3f)
- *
- * @param axisAngle
- * the {@link AxisAngle4f} (needs to be {@link AxisAngle4f#normalize() normalized})
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotate(AxisAngle4f axisAngle, Matrix3f dest);
-
- /**
- * Apply a rotation transformation, rotating the given radians about the specified axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float, Matrix3f)
- *
- * @param angle
- * the angle in radians
- * @param axis
- * the rotation axis (needs to be {@link Vector3f#normalize() normalized})
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotate(float angle, Vector3fc axis, Matrix3f dest);
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * If
- * The normal matrix of
- * The cofactor matrix can be used instead of {@link #normal(Matrix3f)} to transform normals
- * when the orientation of the normals with respect to the surface should be preserved.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f cofactor(Matrix3f dest);
-
- /**
- * Get the scaling factors of
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * If
- * If
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * This method assumes that
- * The Euler angles are always returned as the angle around X in the {@link Vector3f#x} field, the angle around Y in the {@link Vector3f#y}
- * field and the angle around Z in the {@link Vector3f#z} field of the supplied {@link Vector3f} instance.
- *
- * Note that the returned Euler angles must be applied in the order
- * Reference: http://en.wikipedia.org/
- *
- * @param dest
- * will hold the extracted Euler angles
- * @return dest
- */
- Vector3f getEulerAnglesXYZ(Vector3f dest);
-
- /**
- * Extract the Euler angles from the rotation represented by
- * This method assumes that
- * The Euler angles are always returned as the angle around X in the {@link Vector3f#x} field, the angle around Y in the {@link Vector3f#y}
- * field and the angle around Z in the {@link Vector3f#z} field of the supplied {@link Vector3f} instance.
- *
- * Note that the returned Euler angles must be applied in the order
- * Reference: http://en.wikipedia.org/
- *
- * @param dest
- * will hold the extracted Euler angles
- * @return dest
- */
- Vector3f getEulerAnglesZYX(Vector3f dest);
-
- /**
- * Apply an oblique projection transformation to this matrix with the given values for
- * If
- * The oblique transformation is defined as:
- *
- * Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
- * and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
- * data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
- *
- * @param m
- * the other matrix
- * @param delta
- * the allowed maximum difference
- * @return
- * If
- * This method can be used to build a reflection transformation based on the orientation of a mirror object in the scene.
- * It is assumed that the default mirror plane's normal is
- * If
- * If
- * m00 m10 m20 m30
- * The matrix layout will be:
- * That FloatBuffer is expected to hold the values in column-major order.
- *
- * The buffer's position will not be changed by this method.
- *
- * @param buffer
- * the {@link FloatBuffer} to read the matrix values from
- */
- public Matrix4f(FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- determineProperties();
- }
-
- /**
- * Create a new {@link Matrix4f} and initialize its four columns using the supplied vectors.
- *
- * @param col0
- * the first column
- * @param col1
- * the second column
- * @param col2
- * the third column
- * @param col3
- * the fourth column
- */
- public Matrix4f(Vector4fc col0, Vector4fc col1, Vector4fc col2, Vector4fc col3) {
- set(col0, col1, col2, col3);
- }
-
- Matrix4f _properties(int properties) {
- this.properties = properties;
- return this;
- }
-
- /**
- * Assume the given properties about this matrix.
- *
- * Use one or multiple of 0, {@link Matrix4fc#PROPERTY_IDENTITY},
- * {@link Matrix4fc#PROPERTY_TRANSLATION}, {@link Matrix4fc#PROPERTY_AFFINE},
- * {@link Matrix4fc#PROPERTY_PERSPECTIVE}, {@link Matrix4fc#PROPERTY_ORTHONORMAL}.
- *
- * @param properties
- * bitset of the properties to assume about this matrix
- * @return this
- */
- public Matrix4f assume(int properties) {
- this._properties(properties);
- return this;
- }
-
- /**
- * Compute and set the matrix properties returned by {@link #properties()} based
- * on the current matrix element values.
- *
- * @return this
- */
- public Matrix4f determineProperties() {
- int properties = 0;
- if (m03() == 0.0f && m13() == 0.0f) {
- if (m23() == 0.0f && m33() == 1.0f) {
- properties |= PROPERTY_AFFINE;
- if (m00() == 1.0f && m01() == 0.0f && m02() == 0.0f && m10() == 0.0f && m11() == 1.0f && m12() == 0.0f
- && m20() == 0.0f && m21() == 0.0f && m22() == 1.0f) {
- properties |= PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL;
- if (m30() == 0.0f && m31() == 0.0f && m32() == 0.0f)
- properties |= PROPERTY_IDENTITY;
- }
- /*
- * We do not determine orthogonality, since it would require arbitrary epsilons
- * and is rather expensive (6 dot products) in the worst case.
- */
- } else if (m01() == 0.0f && m02() == 0.0f && m10() == 0.0f && m12() == 0.0f && m20() == 0.0f && m21() == 0.0f
- && m30() == 0.0f && m31() == 0.0f && m33() == 0.0f) {
- properties |= PROPERTY_PERSPECTIVE;
- }
- }
- this.properties = properties;
- return this;
- }
-
- public int properties() {
- return properties;
- }
-
- public float m00() {
- return m00;
- }
- public float m01() {
- return m01;
- }
- public float m02() {
- return m02;
- }
- public float m03() {
- return m03;
- }
- public float m10() {
- return m10;
- }
- public float m11() {
- return m11;
- }
- public float m12() {
- return m12;
- }
- public float m13() {
- return m13;
- }
- public float m20() {
- return m20;
- }
- public float m21() {
- return m21;
- }
- public float m22() {
- return m22;
- }
- public float m23() {
- return m23;
- }
- public float m30() {
- return m30;
- }
- public float m31() {
- return m31;
- }
- public float m32() {
- return m32;
- }
- public float m33() {
- return m33;
- }
-
- /**
- * Set the value of the matrix element at column 0 and row 0.
- *
- * @param m00
- * the new value
- * @return this
- */
- public Matrix4f m00(float m00) {
- this.m00 = m00;
- properties &= ~PROPERTY_ORTHONORMAL;
- if (m00 != 1.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_TRANSLATION);
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 1.
- *
- * @param m01
- * the new value
- * @return this
- */
- public Matrix4f m01(float m01) {
- this.m01 = m01;
- properties &= ~PROPERTY_ORTHONORMAL;
- if (m01 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE | PROPERTY_TRANSLATION);
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 2.
- *
- * @param m02
- * the new value
- * @return this
- */
- public Matrix4f m02(float m02) {
- this.m02 = m02;
- properties &= ~PROPERTY_ORTHONORMAL;
- if (m02 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE | PROPERTY_TRANSLATION);
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 3.
- *
- * @param m03
- * the new value
- * @return this
- */
- public Matrix4f m03(float m03) {
- this.m03 = m03;
- if (m03 != 0.0f)
- properties = 0;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 0.
- *
- * @param m10
- * the new value
- * @return this
- */
- public Matrix4f m10(float m10) {
- this.m10 = m10;
- properties &= ~PROPERTY_ORTHONORMAL;
- if (m10 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE | PROPERTY_TRANSLATION);
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 1.
- *
- * @param m11
- * the new value
- * @return this
- */
- public Matrix4f m11(float m11) {
- this.m11 = m11;
- properties &= ~PROPERTY_ORTHONORMAL;
- if (m11 != 1.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_TRANSLATION);
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 2.
- *
- * @param m12
- * the new value
- * @return this
- */
- public Matrix4f m12(float m12) {
- this.m12 = m12;
- properties &= ~PROPERTY_ORTHONORMAL;
- if (m12 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE | PROPERTY_TRANSLATION);
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 3.
- *
- * @param m13
- * the new value
- * @return this
- */
- public Matrix4f m13(float m13) {
- this.m13 = m13;
- if (m13 != 0.0f)
- properties = 0;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 0.
- *
- * @param m20
- * the new value
- * @return this
- */
- public Matrix4f m20(float m20) {
- this.m20 = m20;
- properties &= ~PROPERTY_ORTHONORMAL;
- if (m20 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE | PROPERTY_TRANSLATION);
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 1.
- *
- * @param m21
- * the new value
- * @return this
- */
- public Matrix4f m21(float m21) {
- this.m21 = m21;
- properties &= ~PROPERTY_ORTHONORMAL;
- if (m21 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE | PROPERTY_TRANSLATION);
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 2.
- *
- * @param m22
- * the new value
- * @return this
- */
- public Matrix4f m22(float m22) {
- this.m22 = m22;
- properties &= ~PROPERTY_ORTHONORMAL;
- if (m22 != 1.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_TRANSLATION);
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 3.
- *
- * @param m23
- * the new value
- * @return this
- */
- public Matrix4f m23(float m23) {
- this.m23 = m23;
- if (m23 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_AFFINE | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL);
- return this;
- }
- /**
- * Set the value of the matrix element at column 3 and row 0.
- *
- * @param m30
- * the new value
- * @return this
- */
- public Matrix4f m30(float m30) {
- this.m30 = m30;
- if (m30 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE);
- return this;
- }
- /**
- * Set the value of the matrix element at column 3 and row 1.
- *
- * @param m31
- * the new value
- * @return this
- */
- public Matrix4f m31(float m31) {
- this.m31 = m31;
- if (m31 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE);
- return this;
- }
- /**
- * Set the value of the matrix element at column 3 and row 2.
- *
- * @param m32
- * the new value
- * @return this
- */
- public Matrix4f m32(float m32) {
- this.m32 = m32;
- if (m32 != 0.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE);
- return this;
- }
- /**
- * Set the value of the matrix element at column 3 and row 3.
- *
- * @param m33
- * the new value
- * @return this
- */
- public Matrix4f m33(float m33) {
- this.m33 = m33;
- if (m33 != 0.0f)
- properties &= ~(PROPERTY_PERSPECTIVE);
- if (m33 != 1.0f)
- properties &= ~(PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL | PROPERTY_AFFINE);
- return this;
- }
-
- /**
- * Set the value of the matrix element at column 0 and row 0 without updating the properties of the matrix.
- *
- * @param m00
- * the new value
- * @return this
- */
- Matrix4f _m00(float m00) {
- this.m00 = m00;
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 1 without updating the properties of the matrix.
- *
- * @param m01
- * the new value
- * @return this
- */
- Matrix4f _m01(float m01) {
- this.m01 = m01;
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 2 without updating the properties of the matrix.
- *
- * @param m02
- * the new value
- * @return this
- */
- Matrix4f _m02(float m02) {
- this.m02 = m02;
- return this;
- }
- /**
- * Set the value of the matrix element at column 0 and row 3 without updating the properties of the matrix.
- *
- * @param m03
- * the new value
- * @return this
- */
- Matrix4f _m03(float m03) {
- this.m03 = m03;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 0 without updating the properties of the matrix.
- *
- * @param m10
- * the new value
- * @return this
- */
- Matrix4f _m10(float m10) {
- this.m10 = m10;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 1 without updating the properties of the matrix.
- *
- * @param m11
- * the new value
- * @return this
- */
- Matrix4f _m11(float m11) {
- this.m11 = m11;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 2 without updating the properties of the matrix.
- *
- * @param m12
- * the new value
- * @return this
- */
- Matrix4f _m12(float m12) {
- this.m12 = m12;
- return this;
- }
- /**
- * Set the value of the matrix element at column 1 and row 3 without updating the properties of the matrix.
- *
- * @param m13
- * the new value
- * @return this
- */
- Matrix4f _m13(float m13) {
- this.m13 = m13;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 0 without updating the properties of the matrix.
- *
- * @param m20
- * the new value
- * @return this
- */
- Matrix4f _m20(float m20) {
- this.m20 = m20;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 1 without updating the properties of the matrix.
- *
- * @param m21
- * the new value
- * @return this
- */
- Matrix4f _m21(float m21) {
- this.m21 = m21;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 2 without updating the properties of the matrix.
- *
- * @param m22
- * the new value
- * @return this
- */
- Matrix4f _m22(float m22) {
- this.m22 = m22;
- return this;
- }
- /**
- * Set the value of the matrix element at column 2 and row 3 without updating the properties of the matrix.
- *
- * @param m23
- * the new value
- * @return this
- */
- Matrix4f _m23(float m23) {
- this.m23 = m23;
- return this;
- }
- /**
- * Set the value of the matrix element at column 3 and row 0 without updating the properties of the matrix.
- *
- * @param m30
- * the new value
- * @return this
- */
- Matrix4f _m30(float m30) {
- this.m30 = m30;
- return this;
- }
- /**
- * Set the value of the matrix element at column 3 and row 1 without updating the properties of the matrix.
- *
- * @param m31
- * the new value
- * @return this
- */
- Matrix4f _m31(float m31) {
- this.m31 = m31;
- return this;
- }
- /**
- * Set the value of the matrix element at column 3 and row 2 without updating the properties of the matrix.
- *
- * @param m32
- * the new value
- * @return this
- */
- Matrix4f _m32(float m32) {
- this.m32 = m32;
- return this;
- }
-
- /**
- * Set the value of the matrix element at column 3 and row 3 without updating the properties of the matrix.
- *
- * @param m33
- * the new value
- * @return this
- */
- Matrix4f _m33(float m33) {
- this.m33 = m33;
- return this;
- }
-
- /**
- * Reset this matrix to the identity.
- *
- * Please note that if a call to {@link #identity()} is immediately followed by a call to:
- * {@link #translate(float, float, float) translate},
- * {@link #rotate(float, float, float, float) rotate},
- * {@link #scale(float, float, float) scale},
- * {@link #perspective(float, float, float, float) perspective},
- * {@link #frustum(float, float, float, float, float, float) frustum},
- * {@link #ortho(float, float, float, float, float, float) ortho},
- * {@link #ortho2D(float, float, float, float) ortho2D},
- * {@link #lookAt(float, float, float, float, float, float, float, float, float) lookAt},
- * {@link #lookAlong(float, float, float, float, float, float) lookAlong},
- * or any of their overloads, then the call to {@link #identity()} can be omitted and the subsequent call replaced with:
- * {@link #translation(float, float, float) translation},
- * {@link #rotation(float, float, float, float) rotation},
- * {@link #scaling(float, float, float) scaling},
- * {@link #setPerspective(float, float, float, float) setPerspective},
- * {@link #setFrustum(float, float, float, float, float, float) setFrustum},
- * {@link #setOrtho(float, float, float, float, float, float) setOrtho},
- * {@link #setOrtho2D(float, float, float, float) setOrtho2D},
- * {@link #setLookAt(float, float, float, float, float, float, float, float, float) setLookAt},
- * {@link #setLookAlong(float, float, float, float, float, float) setLookAlong},
- * or any of their overloads.
- *
- * @return this
- */
- public Matrix4f identity() {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return this;
- return
- _m00(1.0f).
- _m01(0.0f).
- _m02(0.0f).
- _m03(0.0f).
- _m10(0.0f).
- _m11(1.0f).
- _m12(0.0f).
- _m13(0.0f).
- _m20(0.0f).
- _m21(0.0f).
- _m22(1.0f).
- _m23(0.0f).
- _m30(0.0f).
- _m31(0.0f).
- _m32(0.0f).
- _m33(1.0f).
- _properties(PROPERTY_IDENTITY | PROPERTY_AFFINE | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Store the values of the given matrix
- * This method is equivalent to calling:
- * Reference: http://www.euclideanspace.com/
- *
- * @see #rotation(Quaternionfc)
- *
- * @param q
- * the {@link Quaternionfc}
- * @return this
- */
- public Matrix4f set(Quaternionfc q) {
- return rotation(q);
- }
-
- /**
- * Set the upper left 3x3 submatrix of this {@link Matrix4f} to that of the given {@link Matrix4f}
- * and don't change the other elements.
- *
- * @param mat
- * the {@link Matrix4f}
- * @return this
- */
- public Matrix4f set3x3(Matrix4f mat) {
- MemUtil.INSTANCE.copy3x3(mat, this);
- return _properties(properties & mat.properties & ~(PROPERTY_PERSPECTIVE));
- }
-
- /**
- * Set the upper 4x3 submatrix of this {@link Matrix4f} to the upper 4x3 submatrix of the given {@link Matrix4f}
- * and don't change the other elements.
- *
- * @param mat
- * the {@link Matrix4f}
- * @return this
- */
- public Matrix4f set4x3(Matrix4f mat) {
- MemUtil.INSTANCE.copy4x3(mat, this);
- return _properties(properties & mat.properties & ~(PROPERTY_PERSPECTIVE));
- }
-
- /**
- * Multiply this matrix by the supplied
- * If
- * If
- * This method neither assumes nor checks for any matrix properties of
- * If
- * If
- * If
- * This method assumes that
- * This method will not modify either the last row of
- * If
- * If
- * This method assumes that the given
- * If
- * This method assumes that
- * This method will not modify either the last row of
- * If
- * If
- * The matrix
- * The results will look like this:
- * The results will look like this:
- * The results will look like this:
- * The results will look like this:
- * The FloatBuffer is expected to contain the values in column-major order.
- *
- * The position of the FloatBuffer will not be changed by this method.
- *
- * @param buffer
- * the FloatBuffer to read the matrix values from in column-major order
- * @return this
- */
- public Matrix4f set(FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- return determineProperties();
- }
-
- /**
- * Set the values of this matrix by reading 16 float values from the given {@link ByteBuffer} in column-major order,
- * starting at its current position.
- *
- * The ByteBuffer is expected to contain the values in column-major order.
- *
- * The position of the ByteBuffer will not be changed by this method.
- *
- * @param buffer
- * the ByteBuffer to read the matrix values from in column-major order
- * @return this
- */
- public Matrix4f set(ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- return determineProperties();
- }
-
- /**
- * Set the values of this matrix by reading 16 float values from the given {@link FloatBuffer} in column-major order,
- * starting at the specified absolute buffer position/index.
- *
- * The FloatBuffer is expected to contain the values in column-major order.
- *
- * The position of the FloatBuffer will not be changed by this method.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * the FloatBuffer to read the matrix values from in column-major order
- * @return this
- */
- public Matrix4f set(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- return determineProperties();
- }
-
- /**
- * Set the values of this matrix by reading 16 float values from the given {@link ByteBuffer} in column-major order,
- * starting at the specified absolute buffer position/index.
- *
- * The ByteBuffer is expected to contain the values in column-major order.
- *
- * The position of the ByteBuffer will not be changed by this method.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * the ByteBuffer to read the matrix values from in column-major order
- * @return this
- */
- public Matrix4f set(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- return determineProperties();
- }
-
- /**
- * Set the values of this matrix by reading 16 float values from the given {@link FloatBuffer} in row-major order,
- * starting at its current position.
- *
- * The FloatBuffer is expected to contain the values in row-major order.
- *
- * The position of the FloatBuffer will not be changed by this method.
- *
- * @param buffer
- * the FloatBuffer to read the matrix values from in row-major order
- * @return this
- */
- public Matrix4f setTransposed(FloatBuffer buffer) {
- MemUtil.INSTANCE.getTransposed(this, buffer.position(), buffer);
- return determineProperties();
- }
-
- /**
- * Set the values of this matrix by reading 16 float values from the given {@link ByteBuffer} in row-major order,
- * starting at its current position.
- *
- * The ByteBuffer is expected to contain the values in row-major order.
- *
- * The position of the ByteBuffer will not be changed by this method.
- *
- * @param buffer
- * the ByteBuffer to read the matrix values from in row-major order
- * @return this
- */
- public Matrix4f setTransposed(ByteBuffer buffer) {
- MemUtil.INSTANCE.getTransposed(this, buffer.position(), buffer);
- return determineProperties();
- }
-
- /**
- * Set the values of this matrix by reading 16 float values from off-heap memory in column-major order,
- * starting at the given address.
- *
- * This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
- *
- * This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
- *
- * @param address
- * the off-heap memory address to read the matrix values from in column-major order
- * @return this
- */
- public Matrix4f setFromAddress(long address) {
- if (Options.NO_UNSAFE)
- throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
- MemUtil.MemUtilUnsafe.get(this, address);
- return determineProperties();
- }
-
- /**
- * Set the values of this matrix by reading 16 float values from off-heap memory in row-major order,
- * starting at the given address.
- *
- * This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
- *
- * This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
- *
- * @param address
- * the off-heap memory address to read the matrix values from in row-major order
- * @return this
- */
- public Matrix4f setTransposedFromAddress(long address) {
- if (Options.NO_UNSAFE)
- throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
- MemUtil.MemUtilUnsafe.getTransposed(this, address);
- return determineProperties();
- }
-
- /**
- * Set the four columns of this matrix to the supplied vectors, respectively.
- *
- * @param col0
- * the first column
- * @param col1
- * the second column
- * @param col2
- * the third column
- * @param col3
- * the fourth column
- * @return this
- */
- public Matrix4f set(Vector4fc col0, Vector4fc col1, Vector4fc col2, Vector4fc col3) {
- return
- _m00(col0.x()).
- _m01(col0.y()).
- _m02(col0.z()).
- _m03(col0.w()).
- _m10(col1.x()).
- _m11(col1.y()).
- _m12(col1.z()).
- _m13(col1.w()).
- _m20(col2.x()).
- _m21(col2.y()).
- _m22(col2.z()).
- _m23(col2.w()).
- _m30(col3.x()).
- _m31(col3.y()).
- _m32(col3.z()).
- _m33(col3.w()).
- determineProperties();
- }
-
- public float determinant() {
- if ((properties & PROPERTY_AFFINE) != 0)
- return determinantAffine();
- return (m00() * m11() - m01() * m10()) * (m22() * m33() - m23() * m32())
- + (m02() * m10() - m00() * m12()) * (m21() * m33() - m23() * m31())
- + (m00() * m13() - m03() * m10()) * (m21() * m32() - m22() * m31())
- + (m01() * m12() - m02() * m11()) * (m20() * m33() - m23() * m30())
- + (m03() * m11() - m01() * m13()) * (m20() * m32() - m22() * m30())
- + (m02() * m13() - m03() * m12()) * (m20() * m31() - m21() * m30());
- }
-
- public float determinant3x3() {
- return (m00() * m11() - m01() * m10()) * m22()
- + (m02() * m10() - m00() * m12()) * m21()
- + (m01() * m12() - m02() * m11()) * m20();
- }
-
- public float determinantAffine() {
- return (m00() * m11() - m01() * m10()) * m22()
- + (m02() * m10() - m00() * m12()) * m21()
- + (m01() * m12() - m02() * m11()) * m20();
- }
-
- public Matrix4f invert(Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0) {
- return dest.identity();
- } else if ((properties & PROPERTY_TRANSLATION) != 0)
- return invertTranslation(dest);
- else if ((properties & PROPERTY_ORTHONORMAL) != 0)
- return invertOrthonormal(dest);
- else if ((properties & PROPERTY_AFFINE) != 0)
- return invertAffine(dest);
- else if ((properties & PROPERTY_PERSPECTIVE) != 0)
- return invertPerspective(dest);
- return invertGeneric(dest);
- }
- private Matrix4f invertTranslation(Matrix4f dest) {
- if (dest != this)
- dest.set(this);
- return dest._m30(-m30())._m31(-m31())._m32(-m32())._properties(PROPERTY_AFFINE | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL);
- }
- private Matrix4f invertOrthonormal(Matrix4f dest) {
- float nm30 = -(m00() * m30() + m01() * m31() + m02() * m32());
- float nm31 = -(m10() * m30() + m11() * m31() + m12() * m32());
- float nm32 = -(m20() * m30() + m21() * m31() + m22() * m32());
- float m01 = this.m01();
- float m02 = this.m02();
- float m12 = this.m12();
- return dest
- ._m00(m00())
- ._m01(m10())
- ._m02(m20())
- ._m03(0.0f)
- ._m10(m01)
- ._m11(m11())
- ._m12(m21())
- ._m13(0.0f)
- ._m20(m02)
- ._m21(m12)
- ._m22(m22())
- ._m23(0.0f)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
- private Matrix4f invertGeneric(Matrix4f dest) {
- if (this != dest)
- return invertGenericNonThis(dest);
- return invertGenericThis(dest);
- }
- private Matrix4f invertGenericNonThis(Matrix4f dest) {
- float a = m00() * m11() - m01() * m10();
- float b = m00() * m12() - m02() * m10();
- float c = m00() * m13() - m03() * m10();
- float d = m01() * m12() - m02() * m11();
- float e = m01() * m13() - m03() * m11();
- float f = m02() * m13() - m03() * m12();
- float g = m20() * m31() - m21() * m30();
- float h = m20() * m32() - m22() * m30();
- float i = m20() * m33() - m23() * m30();
- float j = m21() * m32() - m22() * m31();
- float k = m21() * m33() - m23() * m31();
- float l = m22() * m33() - m23() * m32();
- float det = a * l - b * k + c * j + d * i - e * h + f * g;
- det = 1.0f / det;
- return dest
- ._m00(Math.fma( m11(), l, Math.fma(-m12(), k, m13() * j)) * det)
- ._m01(Math.fma(-m01(), l, Math.fma( m02(), k, -m03() * j)) * det)
- ._m02(Math.fma( m31(), f, Math.fma(-m32(), e, m33() * d)) * det)
- ._m03(Math.fma(-m21(), f, Math.fma( m22(), e, -m23() * d)) * det)
- ._m10(Math.fma(-m10(), l, Math.fma( m12(), i, -m13() * h)) * det)
- ._m11(Math.fma( m00(), l, Math.fma(-m02(), i, m03() * h)) * det)
- ._m12(Math.fma(-m30(), f, Math.fma( m32(), c, -m33() * b)) * det)
- ._m13(Math.fma( m20(), f, Math.fma(-m22(), c, m23() * b)) * det)
- ._m20(Math.fma( m10(), k, Math.fma(-m11(), i, m13() * g)) * det)
- ._m21(Math.fma(-m00(), k, Math.fma( m01(), i, -m03() * g)) * det)
- ._m22(Math.fma( m30(), e, Math.fma(-m31(), c, m33() * a)) * det)
- ._m23(Math.fma(-m20(), e, Math.fma( m21(), c, -m23() * a)) * det)
- ._m30(Math.fma(-m10(), j, Math.fma( m11(), h, -m12() * g)) * det)
- ._m31(Math.fma( m00(), j, Math.fma(-m01(), h, m02() * g)) * det)
- ._m32(Math.fma(-m30(), d, Math.fma( m31(), b, -m32() * a)) * det)
- ._m33(Math.fma( m20(), d, Math.fma(-m21(), b, m22() * a)) * det)
- ._properties(0);
- }
- private Matrix4f invertGenericThis(Matrix4f dest) {
- float a = m00() * m11() - m01() * m10();
- float b = m00() * m12() - m02() * m10();
- float c = m00() * m13() - m03() * m10();
- float d = m01() * m12() - m02() * m11();
- float e = m01() * m13() - m03() * m11();
- float f = m02() * m13() - m03() * m12();
- float g = m20() * m31() - m21() * m30();
- float h = m20() * m32() - m22() * m30();
- float i = m20() * m33() - m23() * m30();
- float j = m21() * m32() - m22() * m31();
- float k = m21() * m33() - m23() * m31();
- float l = m22() * m33() - m23() * m32();
- float det = a * l - b * k + c * j + d * i - e * h + f * g;
- det = 1.0f / det;
- float nm00 = Math.fma( m11(), l, Math.fma(-m12(), k, m13() * j)) * det;
- float nm01 = Math.fma(-m01(), l, Math.fma( m02(), k, -m03() * j)) * det;
- float nm02 = Math.fma( m31(), f, Math.fma(-m32(), e, m33() * d)) * det;
- float nm03 = Math.fma(-m21(), f, Math.fma( m22(), e, -m23() * d)) * det;
- float nm10 = Math.fma(-m10(), l, Math.fma( m12(), i, -m13() * h)) * det;
- float nm11 = Math.fma( m00(), l, Math.fma(-m02(), i, m03() * h)) * det;
- float nm12 = Math.fma(-m30(), f, Math.fma( m32(), c, -m33() * b)) * det;
- float nm13 = Math.fma( m20(), f, Math.fma(-m22(), c, m23() * b)) * det;
- float nm20 = Math.fma( m10(), k, Math.fma(-m11(), i, m13() * g)) * det;
- float nm21 = Math.fma(-m00(), k, Math.fma( m01(), i, -m03() * g)) * det;
- float nm22 = Math.fma( m30(), e, Math.fma(-m31(), c, m33() * a)) * det;
- float nm23 = Math.fma(-m20(), e, Math.fma( m21(), c, -m23() * a)) * det;
- float nm30 = Math.fma(-m10(), j, Math.fma( m11(), h, -m12() * g)) * det;
- float nm31 = Math.fma( m00(), j, Math.fma(-m01(), h, m02() * g)) * det;
- float nm32 = Math.fma(-m30(), d, Math.fma( m31(), b, -m32() * a)) * det;
- float nm33 = Math.fma( m20(), d, Math.fma(-m21(), b, m22() * a)) * det;
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(nm33)
- ._properties(0);
- }
-
- /**
- * Invert this matrix.
- *
- * If
- * This method can be used to quickly obtain the inverse of a perspective projection matrix when being obtained via {@link #perspective(float, float, float, float) perspective()}.
- *
- * @see #perspective(float, float, float, float)
- *
- * @param dest
- * will hold the inverse of
- * This method can be used to quickly obtain the inverse of a perspective projection matrix when being obtained via {@link #perspective(float, float, float, float) perspective()}.
- *
- * @see #perspective(float, float, float, float)
- *
- * @return this
- */
- public Matrix4f invertPerspective() {
- return invertPerspective(this);
- }
-
- /**
- * If
- * This method can be used to quickly obtain the inverse of a perspective projection matrix.
- *
- * If this matrix represents a symmetric perspective frustum transformation, as obtained via {@link #perspective(float, float, float, float) perspective()}, then
- * {@link #invertPerspective(Matrix4f)} should be used instead.
- *
- * @see #frustum(float, float, float, float, float, float)
- * @see #invertPerspective(Matrix4f)
- *
- * @param dest
- * will hold the inverse of
- * This method can be used to quickly obtain the inverse of a perspective projection matrix.
- *
- * If this matrix represents a symmetric perspective frustum transformation, as obtained via {@link #perspective(float, float, float, float) perspective()}, then
- * {@link #invertPerspective()} should be used instead.
- *
- * @see #frustum(float, float, float, float, float, float)
- * @see #invertPerspective()
- *
- * @return this
- */
- public Matrix4f invertFrustum() {
- return invertFrustum(this);
- }
-
- public Matrix4f invertOrtho(Matrix4f dest) {
- float invM00 = 1.0f / m00();
- float invM11 = 1.0f / m11();
- float invM22 = 1.0f / m22();
- return dest
- .set(invM00, 0, 0, 0,
- 0, invM11, 0, 0,
- 0, 0, invM22, 0,
- -m30() * invM00, -m31() * invM11, -m32() * invM22, 1)
- ._properties(PROPERTY_AFFINE | (this.properties & PROPERTY_ORTHONORMAL));
- }
-
- /**
- * Invert
- * This method can be used to quickly obtain the inverse of an orthographic projection matrix.
- *
- * @return this
- */
- public Matrix4f invertOrtho() {
- return invertOrtho(this);
- }
-
- /**
- * If
- * This method can be used to quickly obtain the inverse of the combination of the view and projection matrices, when both were obtained
- * via the common methods {@link #perspective(float, float, float, float) perspective()} and {@link #lookAt(float, float, float, float, float, float, float, float, float) lookAt()} or
- * other methods, that build affine matrices, such as {@link #translate(float, float, float) translate} and {@link #rotate(float, float, float, float)}, except for {@link #scale(float, float, float) scale()}.
- *
- * For the special cases of the matrices
- * All other matrix elements are left unchanged.
- *
- * @return this
- */
- public Matrix4f transpose3x3() {
- return transpose3x3(this);
- }
-
- public Matrix4f transpose3x3(Matrix4f dest) {
- float nm10 = m01(), nm20 = m02(), nm21 = m12();
- return dest
- ._m00(m00())
- ._m01(m10())
- ._m02(m20())
- ._m10(nm10)
- ._m11(m11())
- ._m12(m21())
- ._m20(nm20)
- ._m21(nm21)
- ._m22(m22())
- ._properties(this.properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- public Matrix3f transpose3x3(Matrix3f dest) {
- return dest
- ._m00(m00())
- ._m01(m10())
- ._m02(m20())
- ._m10(m01())
- ._m11(m11())
- ._m12(m21())
- ._m20(m02())
- ._m21(m12())
- ._m22(m22());
- }
-
- /**
- * Transpose this matrix.
- *
- * @return this
- */
- public Matrix4f transpose() {
- return transpose(this);
- }
-
- /**
- * Set this matrix to be a simple translation matrix.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional translation.
- *
- * In order to post-multiply a translation transformation directly to a
- * matrix, use {@link #translate(float, float, float) translate()} instead.
- *
- * @see #translate(float, float, float)
- *
- * @param x
- * the offset to translate in x
- * @param y
- * the offset to translate in y
- * @param z
- * the offset to translate in z
- * @return this
- */
- public Matrix4f translation(float x, float y, float z) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- return this._m30(x)._m31(y)._m32(z)._properties(PROPERTY_AFFINE | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set this matrix to be a simple translation matrix.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional translation.
- *
- * In order to post-multiply a translation transformation directly to a
- * matrix, use {@link #translate(Vector3fc) translate()} instead.
- *
- * @see #translate(float, float, float)
- *
- * @param offset
- * the offsets in x, y and z to translate
- * @return this
- */
- public Matrix4f translation(Vector3fc offset) {
- return translation(offset.x(), offset.y(), offset.z());
- }
-
- /**
- * Set only the translation components
- * Note that this will only work properly for orthogonal matrices (without any perspective).
- *
- * To build a translation matrix instead, use {@link #translation(float, float, float)}.
- * To apply a translation, use {@link #translate(float, float, float)}.
- *
- * @see #translation(float, float, float)
- * @see #translate(float, float, float)
- *
- * @param x
- * the offset to translate in x
- * @param y
- * the offset to translate in y
- * @param z
- * the offset to translate in z
- * @return this
- */
- public Matrix4f setTranslation(float x, float y, float z) {
- return this._m30(x)._m31(y)._m32(z)._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY));
- }
-
- /**
- * Set only the translation components
- * Note that this will only work properly for orthogonal matrices (without any perspective).
- *
- * To build a translation matrix instead, use {@link #translation(Vector3fc)}.
- * To apply a translation, use {@link #translate(Vector3fc)}.
- *
- * @see #translation(Vector3fc)
- * @see #translate(Vector3fc)
- *
- * @param xyz
- * the units to translate in
- * This method creates a new {@link DecimalFormat} on every invocation with the format string "
- * This is the reverse method of {@link #set(Matrix4fc)} and allows to obtain
- * intermediate calculation results when chaining multiple transformations.
- *
- * @see #set(Matrix4fc)
- *
- * @param dest
- * the destination matrix
- * @return the passed in destination
- */
- public Matrix4f get(Matrix4f dest) {
- return dest.set(this);
- }
-
- public Matrix3f get3x3(Matrix3f dest) {
- return dest.set(this);
- }
-
- public AxisAngle4f getRotation(AxisAngle4f dest) {
- return dest.set(this);
- }
-
- public Quaternionf getUnnormalizedRotation(Quaternionf dest) {
- return dest.setFromUnnormalized(this);
- }
-
- public Quaternionf getNormalizedRotation(Quaternionf dest) {
- return dest.setFromNormalized(this);
- }
-
- public FloatBuffer get(FloatBuffer buffer) {
- MemUtil.INSTANCE.put(this, buffer.position(), buffer);
- return buffer;
- }
-
- public FloatBuffer get(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.put(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer get(ByteBuffer buffer) {
- MemUtil.INSTANCE.put(this, buffer.position(), buffer);
- return buffer;
- }
-
- public ByteBuffer get(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.put(this, index, buffer);
- return buffer;
- }
-
- public FloatBuffer get4x3(FloatBuffer buffer) {
- MemUtil.INSTANCE.put4x3(this, buffer.position(), buffer);
- return buffer;
- }
-
- public FloatBuffer get4x3(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.put4x3(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer get4x3(ByteBuffer buffer) {
- MemUtil.INSTANCE.put4x3(this, buffer.position(), buffer);
- return buffer;
- }
-
- public ByteBuffer get4x3(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.put4x3(this, index, buffer);
- return buffer;
- }
-
- public FloatBuffer get3x4(FloatBuffer buffer) {
- MemUtil.INSTANCE.put3x4(this, buffer.position(), buffer);
- return buffer;
- }
-
- public FloatBuffer get3x4(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.put3x4(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer get3x4(ByteBuffer buffer) {
- MemUtil.INSTANCE.put3x4(this, buffer.position(), buffer);
- return buffer;
- }
-
- public ByteBuffer get3x4(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.put3x4(this, index, buffer);
- return buffer;
- }
-
- public FloatBuffer getTransposed(FloatBuffer buffer) {
- MemUtil.INSTANCE.putTransposed(this, buffer.position(), buffer);
- return buffer;
- }
-
- public FloatBuffer getTransposed(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.putTransposed(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer getTransposed(ByteBuffer buffer) {
- MemUtil.INSTANCE.putTransposed(this, buffer.position(), buffer);
- return buffer;
- }
-
- public ByteBuffer getTransposed(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.putTransposed(this, index, buffer);
- return buffer;
- }
-
- public FloatBuffer get4x3Transposed(FloatBuffer buffer) {
- MemUtil.INSTANCE.put4x3Transposed(this, buffer.position(), buffer);
- return buffer;
- }
-
- public FloatBuffer get4x3Transposed(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.put4x3Transposed(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer get4x3Transposed(ByteBuffer buffer) {
- MemUtil.INSTANCE.put4x3Transposed(this, buffer.position(), buffer);
- return buffer;
- }
-
- public ByteBuffer get4x3Transposed(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.put4x3Transposed(this, index, buffer);
- return buffer;
- }
- public Matrix4fc getToAddress(long address) {
- if (Options.NO_UNSAFE)
- throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
- MemUtil.MemUtilUnsafe.put(this, address);
- return this;
- }
-
- public float[] get(float[] arr, int offset) {
- MemUtil.INSTANCE.copy(this, arr, offset);
- return arr;
- }
-
- public float[] get(float[] arr) {
- MemUtil.INSTANCE.copy(this, arr, 0);
- return arr;
- }
-
- /**
- * Set all the values within this matrix to
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional scaling.
- *
- * In order to post-multiply a scaling transformation directly to a
- * matrix, use {@link #scale(float) scale()} instead.
- *
- * @see #scale(float)
- *
- * @param factor
- * the scale factor in x, y and z
- * @return this
- */
- public Matrix4f scaling(float factor) {
- return scaling(factor, factor, factor);
- }
-
- /**
- * Set this matrix to be a simple scale matrix.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional scaling.
- *
- * In order to post-multiply a scaling transformation directly to a
- * matrix, use {@link #scale(float, float, float) scale()} instead.
- *
- * @see #scale(float, float, float)
- *
- * @param x
- * the scale in x
- * @param y
- * the scale in y
- * @param z
- * the scale in z
- * @return this
- */
- public Matrix4f scaling(float x, float y, float z) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- boolean one = Math.absEqualsOne(x) && Math.absEqualsOne(y) && Math.absEqualsOne(z);
- return this
- ._m00(x)
- ._m11(y)
- ._m22(z)
- ._properties(PROPERTY_AFFINE | (one ? PROPERTY_ORTHONORMAL : 0));
- }
-
- /**
- * Set this matrix to be a simple scale matrix which scales the base axes by
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional scaling.
- *
- * In order to post-multiply a scaling transformation directly to a
- * matrix use {@link #scale(Vector3fc) scale()} instead.
- *
- * @see #scale(Vector3fc)
- *
- * @param xyz
- * the scale in x, y and z respectively
- * @return this
- */
- public Matrix4f scaling(Vector3fc xyz) {
- return scaling(xyz.x(), xyz.y(), xyz.z());
- }
-
- /**
- * Set this matrix to a rotation matrix which rotates the given radians about a given axis.
- *
- * The axis described by the
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional rotation.
- *
- * In order to post-multiply a rotation transformation directly to a
- * matrix, use {@link #rotate(float, Vector3fc) rotate()} instead.
- *
- * @see #rotate(float, Vector3fc)
- *
- * @param angle
- * the angle in radians
- * @param axis
- * the axis to rotate about (needs to be {@link Vector3f#normalize() normalized})
- * @return this
- */
- public Matrix4f rotation(float angle, Vector3fc axis) {
- return rotation(angle, axis.x(), axis.y(), axis.z());
- }
-
- /**
- * Set this matrix to a rotation transformation using the given {@link AxisAngle4f}.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional rotation.
- *
- * In order to apply the rotation transformation to an existing transformation,
- * use {@link #rotate(AxisAngle4f) rotate()} instead.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(AxisAngle4f)
- *
- * @param axisAngle
- * the {@link AxisAngle4f} (needs to be {@link AxisAngle4f#normalize() normalized})
- * @return this
- */
- public Matrix4f rotation(AxisAngle4f axisAngle) {
- return rotation(axisAngle.angle, axisAngle.x, axisAngle.y, axisAngle.z);
- }
-
- /**
- * Set this matrix to a rotation matrix which rotates the given radians about a given axis.
- *
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional rotation.
- *
- * In order to apply the rotation transformation to an existing transformation,
- * use {@link #rotate(float, float, float, float) rotate()} instead.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- *
- * @param angle
- * the angle in radians
- * @param x
- * the x-component of the rotation axis
- * @param y
- * the y-component of the rotation axis
- * @param z
- * the z-component of the rotation axis
- * @return this
- */
- public Matrix4f rotation(float angle, float x, float y, float z) {
- if (y == 0.0f && z == 0.0f && Math.absEqualsOne(x))
- return rotationX(x * angle);
- else if (x == 0.0f && z == 0.0f && Math.absEqualsOne(y))
- return rotationY(y * angle);
- else if (x == 0.0f && y == 0.0f && Math.absEqualsOne(z))
- return rotationZ(z * angle);
- return rotationInternal(angle, x, y, z);
- }
- private Matrix4f rotationInternal(float angle, float x, float y, float z) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float C = 1.0f - cos, xy = x * y, xz = x * z, yz = y * z;
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- return this
- ._m00(cos + x * x * C)
- ._m10(xy * C - z * sin)
- ._m20(xz * C + y * sin)
- ._m01(xy * C + z * sin)
- ._m11(cos + y * y * C)
- ._m21(yz * C - x * sin)
- ._m02(xz * C - y * sin)
- ._m12(yz * C + x * sin)
- ._m22(cos + z * z * C)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set this matrix to a rotation transformation about the X axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix4f rotationX(float ang) {
- float sin = Math.sin(ang), cos = Math.cosFromSin(sin, ang);
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m11(cos)._m12(sin)._m21(-sin)._m22(cos)._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- /**
- * Set this matrix to a rotation transformation about the Y axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix4f rotationY(float ang) {
- float sin = Math.sin(ang), cos = Math.cosFromSin(sin, ang);
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00(cos)._m02(-sin)._m20(sin)._m22(cos)._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- /**
- * Set this matrix to a rotation transformation about the Z axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix4f rotationZ(float ang) {
- float sin = Math.sin(ang), cos = Math.cosFromSin(sin, ang);
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- return this._m00(cos)._m01(sin)._m10(-sin)._m11(cos)._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set this matrix to a rotation transformation about the Z axis to align the local
- * The vector
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * @param angleX
- * the angle to rotate about X
- * @param angleY
- * the angle to rotate about Y
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix4f setRotationXYZ(float angleX, float angleY, float angleZ) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float nm01 = -sinX * -sinY;
- float nm02 = cosX * -sinY;
- return this
- ._m20(sinY)
- ._m21(-sinX * cosY)
- ._m22(cosX * cosY)
- ._m00(cosY * cosZ)
- ._m01(nm01 * cosZ + cosX * sinZ)
- ._m02(nm02 * cosZ + sinX * sinZ)
- ._m10(cosY * -sinZ)
- ._m11(nm01 * -sinZ + cosX * cosZ)
- ._m12(nm02 * -sinZ + sinX * cosZ)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Set only the upper left 3x3 submatrix of this matrix to a rotation of
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * @param angleZ
- * the angle to rotate about Z
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @return this
- */
- public Matrix4f setRotationZYX(float angleZ, float angleY, float angleX) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float nm20 = cosZ * sinY, nm21 = sinZ * sinY;
- return this
- ._m00(cosZ * cosY)
- ._m01(sinZ * cosY)
- ._m02(-sinY)
- ._m10(-sinZ * cosX + nm20 * sinX)
- ._m11(cosZ * cosX + nm21 * sinX)
- ._m12(cosY * sinX)
- ._m20(-sinZ * -sinX + nm20 * cosX)
- ._m21(cosZ * -sinX + nm21 * cosX)
- ._m22(cosY * cosX)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Set only the upper left 3x3 submatrix of this matrix to a rotation of
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix4f setRotationYXZ(float angleY, float angleX, float angleZ) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float nm10 = sinY * sinX, nm12 = cosY * sinX;
- return this
- ._m20(sinY * cosX)
- ._m21(-sinX)
- ._m22(cosY * cosX)
- ._m00(cosY * cosZ + nm10 * sinZ)
- ._m01(cosX * sinZ)
- ._m02(-sinY * cosZ + nm12 * sinZ)
- ._m10(cosY * -sinZ + nm10 * cosZ)
- ._m11(cosX * cosZ)
- ._m12(-sinY * -sinZ + nm12 * cosZ)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Set this matrix to the rotation transformation of the given {@link Quaternionfc}.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * The resulting matrix can be multiplied against another transformation
- * matrix to obtain an additional rotation.
- *
- * In order to apply the rotation transformation to an existing transformation,
- * use {@link #rotate(Quaternionfc) rotate()} instead.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @return this
- */
- public Matrix4f rotation(Quaternionfc quat) {
- float w2 = quat.w() * quat.w();
- float x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y();
- float z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw;
- float xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz;
- float yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz;
- float xw = quat.x() * quat.w(), dxw = xw + xw;
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- return this
- ._m00(w2 + x2 - z2 - y2)
- ._m01(dxy + dzw)
- ._m02(dxz - dyw)
- ._m10(-dzw + dxy)
- ._m11(y2 - z2 + w2 - x2)
- ._m12(dyz + dxw)
- ._m20(dyw + dxz)
- ._m21(dyz - dxw)
- ._m22(z2 - y2 - x2 + w2)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set
- * When transforming a vector by the resulting matrix the scaling transformation will be applied first, then the rotation and
- * at last the translation.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When transforming a vector by the resulting matrix the scaling transformation will be applied first, then the rotation and
- * at last the translation.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When transforming a vector by the resulting matrix the scaling transformation will be applied first, then the rotation and
- * at last the translation.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When transforming a vector by the resulting matrix the scaling transformation will be applied first, then the rotation and
- * at last the translation.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * This method is equivalent to calling:
- * This method is equivalent to calling:
- * This method is equivalent to calling:
- * When transforming a vector by the resulting matrix the transformation described by
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When transforming a vector by the resulting matrix the transformation described by
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When transforming a vector by the resulting matrix the rotation - and possibly scaling - transformation will be applied first and then the translation.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When transforming a vector by the resulting matrix the rotation - and possibly scaling - transformation will be applied first and then the translation.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * When transforming a vector by the resulting matrix the scaling transformation will be applied first, then the rotation and
- * at last the translation.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * This method is equivalent to calling:
- * This method is equivalent to calling:
- * If
- * If
- * Individual scaling of all three axes can be applied using {@link #scale(float, float, float)}.
- *
- * @see #scale(float, float, float)
- *
- * @param xyz
- * the factor for all components
- * @return this
- */
- public Matrix4f scale(float xyz) {
- return scale(xyz, xyz, xyz);
- }
-
- public Matrix4f scaleXY(float x, float y, Matrix4f dest) {
- return scale(x, y, 1.0f, dest);
- }
-
- /**
- * Apply scaling to this matrix by scaling the X axis by
- * If
- * If
- * If
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * If
- * If
- * If
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix4f rotateX(float ang) {
- return rotateX(ang, this);
- }
-
- public Matrix4f rotateY(float ang, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotationY(ang);
- else if ((properties & PROPERTY_TRANSLATION) != 0) {
- float x = m30(), y = m31(), z = m32();
- return dest.rotationY(ang).setTranslation(x, y, z);
- }
- return rotateYInternal(ang, dest);
- }
- private Matrix4f rotateYInternal(float ang, Matrix4f dest) {
- float sin = Math.sin(ang);
- float cos = Math.cosFromSin(sin, ang);
- // add temporaries for dependent values
- float nm00 = Math.fma(m00(), cos, m20() * -sin);
- float nm01 = Math.fma(m01(), cos, m21() * -sin);
- float nm02 = Math.fma(m02(), cos, m22() * -sin);
- float nm03 = Math.fma(m03(), cos, m23() * -sin);
- // set non-dependent values directly
- return dest
- ._m20(Math.fma(m00(), sin, m20() * cos))
- ._m21(Math.fma(m01(), sin, m21() * cos))
- ._m22(Math.fma(m02(), sin, m22() * cos))
- ._m23(Math.fma(m03(), sin, m23() * cos))
- // set other values
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(m10())
- ._m11(m11())
- ._m12(m12())
- ._m13(m13())
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation about the Y axis to this matrix by rotating the given amount of radians.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix4f rotateY(float ang) {
- return rotateY(ang, this);
- }
-
- public Matrix4f rotateZ(float ang, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotationZ(ang);
- else if ((properties & PROPERTY_TRANSLATION) != 0) {
- float x = m30(), y = m31(), z = m32();
- return dest.rotationZ(ang).setTranslation(x, y, z);
- }
- return rotateZInternal(ang, dest);
- }
- private Matrix4f rotateZInternal(float ang, Matrix4f dest) {
- float sin = Math.sin(ang);
- float cos = Math.cosFromSin(sin, ang);
- return rotateTowardsXY(sin, cos, dest);
- }
-
- /**
- * Apply rotation about the Z axis to this matrix by rotating the given amount of radians.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @return this
- */
- public Matrix4f rotateZ(float ang) {
- return rotateZ(ang, this);
- }
-
- /**
- * Apply rotation about the Z axis to align the local
- * If
- * The vector
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method assumes that
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method assumes that
- * If
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method assumes that
- * If
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without post-multiplying the rotation
- * transformation, use {@link #rotation(float, float, float, float) rotation()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(float, float, float, float)
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotate(float ang, float x, float y, float z, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotation(ang, x, y, z);
- else if ((properties & PROPERTY_TRANSLATION) != 0)
- return rotateTranslation(ang, x, y, z, dest);
- else if ((properties & PROPERTY_AFFINE) != 0)
- return rotateAffine(ang, x, y, z, dest);
- return rotateGeneric(ang, x, y, z, dest);
- }
- private Matrix4f rotateGeneric(float ang, float x, float y, float z, Matrix4f dest) {
- if (y == 0.0f && z == 0.0f && Math.absEqualsOne(x))
- return rotateX(x * ang, dest);
- else if (x == 0.0f && z == 0.0f && Math.absEqualsOne(y))
- return rotateY(y * ang, dest);
- else if (x == 0.0f && y == 0.0f && Math.absEqualsOne(z))
- return rotateZ(z * ang, dest);
- return rotateGenericInternal(ang, x, y, z, dest);
- }
- private Matrix4f rotateGenericInternal(float ang, float x, float y, float z, Matrix4f dest) {
- float s = Math.sin(ang);
- float c = Math.cosFromSin(s, ang);
- float C = 1.0f - c;
- float xx = x * x, xy = x * y, xz = x * z;
- float yy = y * y, yz = y * z;
- float zz = z * z;
- float rm00 = xx * C + c;
- float rm01 = xy * C + z * s;
- float rm02 = xz * C - y * s;
- float rm10 = xy * C - z * s;
- float rm11 = yy * C + c;
- float rm12 = yz * C + x * s;
- float rm20 = xz * C + y * s;
- float rm21 = yz * C - x * s;
- float rm22 = zz * C + c;
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02;
- float nm03 = m03() * rm00 + m13() * rm01 + m23() * rm02;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12;
- float nm13 = m03() * rm10 + m13() * rm11 + m23() * rm12;
- return dest
- ._m20(m00() * rm20 + m10() * rm21 + m20() * rm22)
- ._m21(m01() * rm20 + m11() * rm21 + m21() * rm22)
- ._m22(m02() * rm20 + m12() * rm21 + m22() * rm22)
- ._m23(m03() * rm20 + m13() * rm21 + m23() * rm22)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation to this matrix by rotating the given amount of radians
- * about the specified
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without post-multiplying the rotation
- * transformation, use {@link #rotation(float, float, float, float) rotation()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(float, float, float, float)
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @return this
- */
- public Matrix4f rotate(float ang, float x, float y, float z) {
- return rotate(ang, x, y, z, this);
- }
-
- /**
- * Apply rotation to this matrix, which is assumed to only contain a translation, by rotating the given amount of radians
- * about the specified
- * This method assumes
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without post-multiplying the rotation
- * transformation, use {@link #rotation(float, float, float, float) rotation()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(float, float, float, float)
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateTranslation(float ang, float x, float y, float z, Matrix4f dest) {
- float tx = m30(), ty = m31(), tz = m32();
- if (y == 0.0f && z == 0.0f && Math.absEqualsOne(x))
- return dest.rotationX(x * ang).setTranslation(tx, ty, tz);
- else if (x == 0.0f && z == 0.0f && Math.absEqualsOne(y))
- return dest.rotationY(y * ang).setTranslation(tx, ty, tz);
- else if (x == 0.0f && y == 0.0f && Math.absEqualsOne(z))
- return dest.rotationZ(z * ang).setTranslation(tx, ty, tz);
- return rotateTranslationInternal(ang, x, y, z, dest);
- }
- private Matrix4f rotateTranslationInternal(float ang, float x, float y, float z, Matrix4f dest) {
- float s = Math.sin(ang);
- float c = Math.cosFromSin(s, ang);
- float C = 1.0f - c;
- float xx = x * x, xy = x * y, xz = x * z;
- float yy = y * y, yz = y * z;
- float zz = z * z;
- float rm00 = xx * C + c;
- float rm01 = xy * C + z * s;
- float rm02 = xz * C - y * s;
- float rm10 = xy * C - z * s;
- float rm11 = yy * C + c;
- float rm12 = yz * C + x * s;
- float rm20 = xz * C + y * s;
- float rm21 = yz * C - x * s;
- float rm22 = zz * C + c;
- return dest
- ._m20(rm20)
- ._m21(rm21)
- ._m22(rm22)
- ._m23(0.0f)
- ._m00(rm00)
- ._m01(rm01)
- ._m02(rm02)
- ._m03(0.0f)
- ._m10(rm10)
- ._m11(rm11)
- ._m12(rm12)
- ._m13(0.0f)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(1.0f)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation to this {@link #isAffine() affine} matrix by rotating the given amount of radians
- * about the specified
- * This method assumes
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without post-multiplying the rotation
- * transformation, use {@link #rotation(float, float, float, float) rotation()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(float, float, float, float)
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateAffine(float ang, float x, float y, float z, Matrix4f dest) {
- if (y == 0.0f && z == 0.0f && Math.absEqualsOne(x))
- return rotateX(x * ang, dest);
- else if (x == 0.0f && z == 0.0f && Math.absEqualsOne(y))
- return rotateY(y * ang, dest);
- else if (x == 0.0f && y == 0.0f && Math.absEqualsOne(z))
- return rotateZ(z * ang, dest);
- return rotateAffineInternal(ang, x, y, z, dest);
- }
- private Matrix4f rotateAffineInternal(float ang, float x, float y, float z, Matrix4f dest) {
- float s = Math.sin(ang);
- float c = Math.cosFromSin(s, ang);
- float C = 1.0f - c;
- float xx = x * x, xy = x * y, xz = x * z;
- float yy = y * y, yz = y * z;
- float zz = z * z;
- float rm00 = xx * C + c;
- float rm01 = xy * C + z * s;
- float rm02 = xz * C - y * s;
- float rm10 = xy * C - z * s;
- float rm11 = yy * C + c;
- float rm12 = yz * C + x * s;
- float rm20 = xz * C + y * s;
- float rm21 = yz * C - x * s;
- float rm22 = zz * C + c;
- // add temporaries for dependent values
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12;
- // set non-dependent values directly
- return dest
- ._m20(m00() * rm20 + m10() * rm21 + m20() * rm22)
- ._m21(m01() * rm20 + m11() * rm21 + m21() * rm22)
- ._m22(m02() * rm20 + m12() * rm21 + m22() * rm22)
- ._m23(0.0f)
- // set other values
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(0.0f)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(0.0f)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(1.0f)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation to this {@link #isAffine() affine} matrix by rotating the given amount of radians
- * about the specified
- * This method assumes
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without post-multiplying the rotation
- * transformation, use {@link #rotation(float, float, float, float) rotation()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(float, float, float, float)
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @return this
- */
- public Matrix4f rotateAffine(float ang, float x, float y, float z) {
- return rotateAffine(ang, x, y, z, this);
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians
- * about the specified
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotation(float, float, float, float) rotation()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(float, float, float, float)
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateLocal(float ang, float x, float y, float z, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotation(ang, x, y, z);
- return rotateLocalGeneric(ang, x, y, z, dest);
- }
- private Matrix4f rotateLocalGeneric(float ang, float x, float y, float z, Matrix4f dest) {
- if (y == 0.0f && z == 0.0f && Math.absEqualsOne(x))
- return rotateLocalX(x * ang, dest);
- else if (x == 0.0f && z == 0.0f && Math.absEqualsOne(y))
- return rotateLocalY(y * ang, dest);
- else if (x == 0.0f && y == 0.0f && Math.absEqualsOne(z))
- return rotateLocalZ(z * ang, dest);
- return rotateLocalGenericInternal(ang, x, y, z, dest);
- }
- private Matrix4f rotateLocalGenericInternal(float ang, float x, float y, float z, Matrix4f dest) {
- float s = Math.sin(ang);
- float c = Math.cosFromSin(s, ang);
- float C = 1.0f - c;
- float xx = x * x, xy = x * y, xz = x * z;
- float yy = y * y, yz = y * z;
- float zz = z * z;
- float lm00 = xx * C + c;
- float lm01 = xy * C + z * s;
- float lm02 = xz * C - y * s;
- float lm10 = xy * C - z * s;
- float lm11 = yy * C + c;
- float lm12 = yz * C + x * s;
- float lm20 = xz * C + y * s;
- float lm21 = yz * C - x * s;
- float lm22 = zz * C + c;
- float nm00 = lm00 * m00() + lm10 * m01() + lm20 * m02();
- float nm01 = lm01 * m00() + lm11 * m01() + lm21 * m02();
- float nm02 = lm02 * m00() + lm12 * m01() + lm22 * m02();
- float nm10 = lm00 * m10() + lm10 * m11() + lm20 * m12();
- float nm11 = lm01 * m10() + lm11 * m11() + lm21 * m12();
- float nm12 = lm02 * m10() + lm12 * m11() + lm22 * m12();
- float nm20 = lm00 * m20() + lm10 * m21() + lm20 * m22();
- float nm21 = lm01 * m20() + lm11 * m21() + lm21 * m22();
- float nm22 = lm02 * m20() + lm12 * m21() + lm22 * m22();
- float nm30 = lm00 * m30() + lm10 * m31() + lm20 * m32();
- float nm31 = lm01 * m30() + lm11 * m31() + lm21 * m32();
- float nm32 = lm02 * m30() + lm12 * m31() + lm22 * m32();
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(m03())
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(m13())
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(m23())
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians
- * about the specified
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotation(float, float, float, float) rotation()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(float, float, float, float)
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @return this
- */
- public Matrix4f rotateLocal(float ang, float x, float y, float z) {
- return rotateLocal(ang, x, y, z, this);
- }
-
- /**
- * Pre-multiply a rotation around the X axis to this matrix by rotating the given amount of radians
- * about the X axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationX(float) rotationX()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationX(float)
- *
- * @param ang
- * the angle in radians to rotate about the X axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateLocalX(float ang, Matrix4f dest) {
- float sin = Math.sin(ang);
- float cos = Math.cosFromSin(sin, ang);
- float nm02 = sin * m01() + cos * m02();
- float nm12 = sin * m11() + cos * m12();
- float nm22 = sin * m21() + cos * m22();
- float nm32 = sin * m31() + cos * m32();
- return dest
- ._m00(m00())
- ._m01(cos * m01() - sin * m02())
- ._m02(nm02)
- ._m03(m03())
- ._m10(m10())
- ._m11(cos * m11() - sin * m12())
- ._m12(nm12)
- ._m13(m13())
- ._m20(m20())
- ._m21(cos * m21() - sin * m22())
- ._m22(nm22)
- ._m23(m23())
- ._m30(m30())
- ._m31(cos * m31() - sin * m32())
- ._m32(nm32)
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians about the X axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationX(float) rotationX()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationX(float)
- *
- * @param ang
- * the angle in radians to rotate about the X axis
- * @return this
- */
- public Matrix4f rotateLocalX(float ang) {
- return rotateLocalX(ang, this);
- }
-
- /**
- * Pre-multiply a rotation around the Y axis to this matrix by rotating the given amount of radians
- * about the Y axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationY(float) rotationY()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationY(float)
- *
- * @param ang
- * the angle in radians to rotate about the Y axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateLocalY(float ang, Matrix4f dest) {
- float sin = Math.sin(ang);
- float cos = Math.cosFromSin(sin, ang);
- float nm02 = -sin * m00() + cos * m02();
- float nm12 = -sin * m10() + cos * m12();
- float nm22 = -sin * m20() + cos * m22();
- float nm32 = -sin * m30() + cos * m32();
- return dest
- ._m00(cos * m00() + sin * m02())
- ._m01(m01())
- ._m02(nm02)
- ._m03(m03())
- ._m10(cos * m10() + sin * m12())
- ._m11(m11())
- ._m12(nm12)
- ._m13(m13())
- ._m20(cos * m20() + sin * m22())
- ._m21(m21())
- ._m22(nm22)
- ._m23(m23())
- ._m30(cos * m30() + sin * m32())
- ._m31(m31())
- ._m32(nm32)
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians about the Y axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationY(float) rotationY()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationY(float)
- *
- * @param ang
- * the angle in radians to rotate about the Y axis
- * @return this
- */
- public Matrix4f rotateLocalY(float ang) {
- return rotateLocalY(ang, this);
- }
-
- /**
- * Pre-multiply a rotation around the Z axis to this matrix by rotating the given amount of radians
- * about the Z axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationZ(float) rotationZ()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationZ(float)
- *
- * @param ang
- * the angle in radians to rotate about the Z axis
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateLocalZ(float ang, Matrix4f dest) {
- float sin = Math.sin(ang);
- float cos = Math.cosFromSin(sin, ang);
- float nm01 = sin * m00() + cos * m01();
- float nm11 = sin * m10() + cos * m11();
- float nm21 = sin * m20() + cos * m21();
- float nm31 = sin * m30() + cos * m31();
- return dest
- ._m00(cos * m00() - sin * m01())
- ._m01(nm01)
- ._m02(m02())
- ._m03(m03())
- ._m10(cos * m10() - sin * m11())
- ._m11(nm11)
- ._m12(m12())
- ._m13(m13())
- ._m20(cos * m20() - sin * m21())
- ._m21(nm21)
- ._m22(m22())
- ._m23(m23())
- ._m30(cos * m30() - sin * m31())
- ._m31(nm31)
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians about the Z axis.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation matrix without pre-multiplying the rotation
- * transformation, use {@link #rotationZ(float) rotationY()}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotationY(float)
- *
- * @param ang
- * the angle in radians to rotate about the Z axis
- * @return this
- */
- public Matrix4f rotateLocalZ(float ang) {
- return rotateLocalZ(ang, this);
- }
-
- /**
- * Apply a translation to this matrix by translating by the given number of
- * units in x, y and z.
- *
- * If
- * In order to set the matrix to a translation transformation without post-multiplying
- * it, use {@link #translation(Vector3fc)}.
- *
- * @see #translation(Vector3fc)
- *
- * @param offset
- * the number of units in x, y and z by which to translate
- * @return this
- */
- public Matrix4f translate(Vector3fc offset) {
- return translate(offset.x(), offset.y(), offset.z());
- }
-
- /**
- * Apply a translation to this matrix by translating by the given number of
- * units in x, y and z and store the result in
- * If
- * In order to set the matrix to a translation transformation without post-multiplying
- * it, use {@link #translation(Vector3fc)}.
- *
- * @see #translation(Vector3fc)
- *
- * @param offset
- * the number of units in x, y and z by which to translate
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f translate(Vector3fc offset, Matrix4f dest) {
- return translate(offset.x(), offset.y(), offset.z(), dest);
- }
-
- /**
- * Apply a translation to this matrix by translating by the given number of
- * units in x, y and z and store the result in
- * If
- * In order to set the matrix to a translation transformation without post-multiplying
- * it, use {@link #translation(float, float, float)}.
- *
- * @see #translation(float, float, float)
- *
- * @param x
- * the offset to translate in x
- * @param y
- * the offset to translate in y
- * @param z
- * the offset to translate in z
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f translate(float x, float y, float z, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.translation(x, y, z);
- return translateGeneric(x, y, z, dest);
- }
- private Matrix4f translateGeneric(float x, float y, float z, Matrix4f dest) {
- MemUtil.INSTANCE.copy(this, dest);
- return dest
- ._m30(Math.fma(m00(), x, Math.fma(m10(), y, Math.fma(m20(), z, m30()))))
- ._m31(Math.fma(m01(), x, Math.fma(m11(), y, Math.fma(m21(), z, m31()))))
- ._m32(Math.fma(m02(), x, Math.fma(m12(), y, Math.fma(m22(), z, m32()))))
- ._m33(Math.fma(m03(), x, Math.fma(m13(), y, Math.fma(m23(), z, m33()))))
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY));
- }
-
- /**
- * Apply a translation to this matrix by translating by the given number of
- * units in x, y and z.
- *
- * If
- * In order to set the matrix to a translation transformation without post-multiplying
- * it, use {@link #translation(float, float, float)}.
- *
- * @see #translation(float, float, float)
- *
- * @param x
- * the offset to translate in x
- * @param y
- * the offset to translate in y
- * @param z
- * the offset to translate in z
- * @return this
- */
- public Matrix4f translate(float x, float y, float z) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return translation(x, y, z);
- return translateGeneric(x, y, z);
- }
- private Matrix4f translateGeneric(float x, float y, float z) {
- return this
- ._m30(Math.fma(m00(), x, Math.fma(m10(), y, Math.fma(m20(), z, m30()))))
- ._m31(Math.fma(m01(), x, Math.fma(m11(), y, Math.fma(m21(), z, m31()))))
- ._m32(Math.fma(m02(), x, Math.fma(m12(), y, Math.fma(m22(), z, m32()))))
- ._m33(Math.fma(m03(), x, Math.fma(m13(), y, Math.fma(m23(), z, m33()))))
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY));
- }
-
- /**
- * Pre-multiply a translation to this matrix by translating by the given number of
- * units in x, y and z.
- *
- * If
- * In order to set the matrix to a translation transformation without pre-multiplying
- * it, use {@link #translation(Vector3fc)}.
- *
- * @see #translation(Vector3fc)
- *
- * @param offset
- * the number of units in x, y and z by which to translate
- * @return this
- */
- public Matrix4f translateLocal(Vector3fc offset) {
- return translateLocal(offset.x(), offset.y(), offset.z());
- }
-
- /**
- * Pre-multiply a translation to this matrix by translating by the given number of
- * units in x, y and z and store the result in
- * If
- * In order to set the matrix to a translation transformation without pre-multiplying
- * it, use {@link #translation(Vector3fc)}.
- *
- * @see #translation(Vector3fc)
- *
- * @param offset
- * the number of units in x, y and z by which to translate
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f translateLocal(Vector3fc offset, Matrix4f dest) {
- return translateLocal(offset.x(), offset.y(), offset.z(), dest);
- }
-
- /**
- * Pre-multiply a translation to this matrix by translating by the given number of
- * units in x, y and z and store the result in
- * If
- * In order to set the matrix to a translation transformation without pre-multiplying
- * it, use {@link #translation(float, float, float)}.
- *
- * @see #translation(float, float, float)
- *
- * @param x
- * the offset to translate in x
- * @param y
- * the offset to translate in y
- * @param z
- * the offset to translate in z
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f translateLocal(float x, float y, float z, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.translation(x, y, z);
- return translateLocalGeneric(x, y, z, dest);
- }
- private Matrix4f translateLocalGeneric(float x, float y, float z, Matrix4f dest) {
- float nm00 = m00() + x * m03();
- float nm01 = m01() + y * m03();
- float nm02 = m02() + z * m03();
- float nm10 = m10() + x * m13();
- float nm11 = m11() + y * m13();
- float nm12 = m12() + z * m13();
- float nm20 = m20() + x * m23();
- float nm21 = m21() + y * m23();
- float nm22 = m22() + z * m23();
- float nm30 = m30() + x * m33();
- float nm31 = m31() + y * m33();
- float nm32 = m32() + z * m33();
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(m03())
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(m13())
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(m23())
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY));
- }
-
- /**
- * Pre-multiply a translation to this matrix by translating by the given number of
- * units in x, y and z.
- *
- * If
- * In order to set the matrix to a translation transformation without pre-multiplying
- * it, use {@link #translation(float, float, float)}.
- *
- * @see #translation(float, float, float)
- *
- * @param x
- * the offset to translate in x
- * @param y
- * the offset to translate in y
- * @param z
- * the offset to translate in z
- * @return this
- */
- public Matrix4f translateLocal(float x, float y, float z) {
- return translateLocal(x, y, z, this);
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeFloat(m00());
- out.writeFloat(m01());
- out.writeFloat(m02());
- out.writeFloat(m03());
- out.writeFloat(m10());
- out.writeFloat(m11());
- out.writeFloat(m12());
- out.writeFloat(m13());
- out.writeFloat(m20());
- out.writeFloat(m21());
- out.writeFloat(m22());
- out.writeFloat(m23());
- out.writeFloat(m30());
- out.writeFloat(m31());
- out.writeFloat(m32());
- out.writeFloat(m33());
- }
-
- public void readExternal(ObjectInput in) throws IOException {
- this._m00(in.readFloat())
- ._m01(in.readFloat())
- ._m02(in.readFloat())
- ._m03(in.readFloat())
- ._m10(in.readFloat())
- ._m11(in.readFloat())
- ._m12(in.readFloat())
- ._m13(in.readFloat())
- ._m20(in.readFloat())
- ._m21(in.readFloat())
- ._m22(in.readFloat())
- ._m23(in.readFloat())
- ._m30(in.readFloat())
- ._m31(in.readFloat())
- ._m32(in.readFloat())
- ._m33(in.readFloat())
- .determineProperties();
- }
-
- /**
- * Apply an orthographic projection transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrtho(float, float, float, float, float, float, boolean) setOrtho()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrtho(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrtho(float, float, float, float, float, float) setOrtho()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrtho(float, float, float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest) {
- return ortho(left, right, bottom, top, zNear, zFar, false, dest);
- }
-
- /**
- * Apply an orthographic projection transformation for a right-handed coordinate system using the given NDC z range to this matrix.
- *
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrtho(float, float, float, float, float, float, boolean) setOrtho()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrtho(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrtho(float, float, float, float, float, float) setOrtho()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrtho(float, float, float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @return this
- */
- public Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar) {
- return ortho(left, right, bottom, top, zNear, zFar, false);
- }
-
- /**
- * Apply an orthographic projection transformation for a left-handed coordiante system
- * using the given NDC z range to this matrix and store the result in
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrthoLH(float, float, float, float, float, float, boolean) setOrthoLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoLH(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrthoLH(float, float, float, float, float, float) setOrthoLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoLH(float, float, float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f orthoLH(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest) {
- return orthoLH(left, right, bottom, top, zNear, zFar, false, dest);
- }
-
- /**
- * Apply an orthographic projection transformation for a left-handed coordiante system
- * using the given NDC z range to this matrix.
- *
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrthoLH(float, float, float, float, float, float, boolean) setOrthoLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoLH(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrthoLH(float, float, float, float, float, float) setOrthoLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoLH(float, float, float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @return this
- */
- public Matrix4f orthoLH(float left, float right, float bottom, float top, float zNear, float zFar) {
- return orthoLH(left, right, bottom, top, zNear, zFar, false);
- }
-
- /**
- * Set this matrix to be an orthographic projection transformation for a right-handed coordinate system
- * using the given NDC z range.
- *
- * In order to apply the orthographic projection to an already existing transformation,
- * use {@link #ortho(float, float, float, float, float, float, boolean) ortho()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #ortho(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * In order to apply the orthographic projection to an already existing transformation,
- * use {@link #ortho(float, float, float, float, float, float) ortho()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #ortho(float, float, float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @return this
- */
- public Matrix4f setOrtho(float left, float right, float bottom, float top, float zNear, float zFar) {
- return setOrtho(left, right, bottom, top, zNear, zFar, false);
- }
-
- /**
- * Set this matrix to be an orthographic projection transformation for a left-handed coordinate system
- * using the given NDC z range.
- *
- * In order to apply the orthographic projection to an already existing transformation,
- * use {@link #orthoLH(float, float, float, float, float, float, boolean) orthoLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #orthoLH(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * In order to apply the orthographic projection to an already existing transformation,
- * use {@link #orthoLH(float, float, float, float, float, float) orthoLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #orthoLH(float, float, float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @return this
- */
- public Matrix4f setOrthoLH(float left, float right, float bottom, float top, float zNear, float zFar) {
- return setOrthoLH(left, right, bottom, top, zNear, zFar, false);
- }
-
- /**
- * Apply a symmetric orthographic projection transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in
- * This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, boolean, Matrix4f) ortho()} with
- *
- * If
- * In order to set the matrix to a symmetric orthographic projection without post-multiplying it,
- * use {@link #setOrthoSymmetric(float, float, float, float, boolean) setOrthoSymmetric()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoSymmetric(float, float, float, float, boolean)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, Matrix4f) ortho()} with
- *
- * If
- * In order to set the matrix to a symmetric orthographic projection without post-multiplying it,
- * use {@link #setOrthoSymmetric(float, float, float, float) setOrthoSymmetric()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoSymmetric(float, float, float, float)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f orthoSymmetric(float width, float height, float zNear, float zFar, Matrix4f dest) {
- return orthoSymmetric(width, height, zNear, zFar, false, dest);
- }
-
- /**
- * Apply a symmetric orthographic projection transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix.
- *
- * This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, boolean) ortho()} with
- *
- * If
- * In order to set the matrix to a symmetric orthographic projection without post-multiplying it,
- * use {@link #setOrthoSymmetric(float, float, float, float, boolean) setOrthoSymmetric()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoSymmetric(float, float, float, float, boolean)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * This method is equivalent to calling {@link #ortho(float, float, float, float, float, float) ortho()} with
- *
- * If
- * In order to set the matrix to a symmetric orthographic projection without post-multiplying it,
- * use {@link #setOrthoSymmetric(float, float, float, float) setOrthoSymmetric()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoSymmetric(float, float, float, float)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @return this
- */
- public Matrix4f orthoSymmetric(float width, float height, float zNear, float zFar) {
- return orthoSymmetric(width, height, zNear, zFar, false, this);
- }
-
- /**
- * Apply a symmetric orthographic projection transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix and store the result in
- * This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, boolean, Matrix4f) orthoLH()} with
- *
- * If
- * In order to set the matrix to a symmetric orthographic projection without post-multiplying it,
- * use {@link #setOrthoSymmetricLH(float, float, float, float, boolean) setOrthoSymmetricLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoSymmetricLH(float, float, float, float, boolean)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, Matrix4f) orthoLH()} with
- *
- * If
- * In order to set the matrix to a symmetric orthographic projection without post-multiplying it,
- * use {@link #setOrthoSymmetricLH(float, float, float, float) setOrthoSymmetricLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoSymmetricLH(float, float, float, float)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f orthoSymmetricLH(float width, float height, float zNear, float zFar, Matrix4f dest) {
- return orthoSymmetricLH(width, height, zNear, zFar, false, dest);
- }
-
- /**
- * Apply a symmetric orthographic projection transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix.
- *
- * This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, boolean) orthoLH()} with
- *
- * If
- * In order to set the matrix to a symmetric orthographic projection without post-multiplying it,
- * use {@link #setOrthoSymmetricLH(float, float, float, float, boolean) setOrthoSymmetricLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoSymmetricLH(float, float, float, float, boolean)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float) orthoLH()} with
- *
- * If
- * In order to set the matrix to a symmetric orthographic projection without post-multiplying it,
- * use {@link #setOrthoSymmetricLH(float, float, float, float) setOrthoSymmetricLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoSymmetricLH(float, float, float, float)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @return this
- */
- public Matrix4f orthoSymmetricLH(float width, float height, float zNear, float zFar) {
- return orthoSymmetricLH(width, height, zNear, zFar, false, this);
- }
-
- /**
- * Set this matrix to be a symmetric orthographic projection transformation for a right-handed coordinate system using the given NDC z range.
- *
- * This method is equivalent to calling {@link #setOrtho(float, float, float, float, float, float, boolean) setOrtho()} with
- *
- * In order to apply the symmetric orthographic projection to an already existing transformation,
- * use {@link #orthoSymmetric(float, float, float, float, boolean) orthoSymmetric()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #orthoSymmetric(float, float, float, float, boolean)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * This method is equivalent to calling {@link #setOrtho(float, float, float, float, float, float) setOrtho()} with
- *
- * In order to apply the symmetric orthographic projection to an already existing transformation,
- * use {@link #orthoSymmetric(float, float, float, float) orthoSymmetric()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #orthoSymmetric(float, float, float, float)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @return this
- */
- public Matrix4f setOrthoSymmetric(float width, float height, float zNear, float zFar) {
- return setOrthoSymmetric(width, height, zNear, zFar, false);
- }
-
- /**
- * Set this matrix to be a symmetric orthographic projection transformation for a left-handed coordinate system using the given NDC z range.
- *
- * This method is equivalent to calling {@link #setOrtho(float, float, float, float, float, float, boolean) setOrtho()} with
- *
- * In order to apply the symmetric orthographic projection to an already existing transformation,
- * use {@link #orthoSymmetricLH(float, float, float, float, boolean) orthoSymmetricLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #orthoSymmetricLH(float, float, float, float, boolean)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * This method is equivalent to calling {@link #setOrthoLH(float, float, float, float, float, float) setOrthoLH()} with
- *
- * In order to apply the symmetric orthographic projection to an already existing transformation,
- * use {@link #orthoSymmetricLH(float, float, float, float) orthoSymmetricLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #orthoSymmetricLH(float, float, float, float)
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @return this
- */
- public Matrix4f setOrthoSymmetricLH(float width, float height, float zNear, float zFar) {
- return setOrthoSymmetricLH(width, height, zNear, zFar, false);
- }
-
- /**
- * Apply an orthographic projection transformation for a right-handed coordinate system to this matrix
- * and store the result in
- * This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, Matrix4f) ortho()} with
- *
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrtho2D(float, float, float, float) setOrtho()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #ortho(float, float, float, float, float, float, Matrix4f)
- * @see #setOrtho2D(float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f ortho2D(float left, float right, float bottom, float top, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setOrtho2D(left, right, bottom, top);
- return ortho2DGeneric(left, right, bottom, top, dest);
- }
- private Matrix4f ortho2DGeneric(float left, float right, float bottom, float top, Matrix4f dest) {
- // calculate right matrix elements
- float rm00 = 2.0f / (right - left);
- float rm11 = 2.0f / (top - bottom);
- float rm30 = (right + left) / (left - right);
- float rm31 = (top + bottom) / (bottom - top);
- // perform optimized multiplication
- // compute the last column first, because other columns do not depend on it
- dest._m30(m00() * rm30 + m10() * rm31 + m30())
- ._m31(m01() * rm30 + m11() * rm31 + m31())
- ._m32(m02() * rm30 + m12() * rm31 + m32())
- ._m33(m03() * rm30 + m13() * rm31 + m33())
- ._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m20(-m20())
- ._m21(-m21())
- ._m22(-m22())
- ._m23(-m23())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Apply an orthographic projection transformation for a right-handed coordinate system to this matrix.
- *
- * This method is equivalent to calling {@link #ortho(float, float, float, float, float, float) ortho()} with
- *
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrtho2D(float, float, float, float) setOrtho2D()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #ortho(float, float, float, float, float, float)
- * @see #setOrtho2D(float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @return this
- */
- public Matrix4f ortho2D(float left, float right, float bottom, float top) {
- return ortho2D(left, right, bottom, top, this);
- }
-
- /**
- * Apply an orthographic projection transformation for a left-handed coordinate system to this matrix and store the result in
- * This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, Matrix4f) orthoLH()} with
- *
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrtho2DLH(float, float, float, float) setOrthoLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #orthoLH(float, float, float, float, float, float, Matrix4f)
- * @see #setOrtho2DLH(float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f ortho2DLH(float left, float right, float bottom, float top, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setOrtho2DLH(left, right, bottom, top);
- return ortho2DLHGeneric(left, right, bottom, top, dest);
- }
- private Matrix4f ortho2DLHGeneric(float left, float right, float bottom, float top, Matrix4f dest) {
- // calculate right matrix elements
- float rm00 = 2.0f / (right - left);
- float rm11 = 2.0f / (top - bottom);
- float rm30 = (right + left) / (left - right);
- float rm31 = (top + bottom) / (bottom - top);
-
- // perform optimized multiplication
- // compute the last column first, because other columns do not depend on it
- dest._m30(m00() * rm30 + m10() * rm31 + m30())
- ._m31(m01() * rm30 + m11() * rm31 + m31())
- ._m32(m02() * rm30 + m12() * rm31 + m32())
- ._m33(m03() * rm30 + m13() * rm31 + m33())
- ._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m20(m20())
- ._m21(m21())
- ._m22(m22())
- ._m23(m23())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Apply an orthographic projection transformation for a left-handed coordinate system to this matrix.
- *
- * This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float) orthoLH()} with
- *
- * If
- * In order to set the matrix to an orthographic projection without post-multiplying it,
- * use {@link #setOrtho2DLH(float, float, float, float) setOrtho2DLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #orthoLH(float, float, float, float, float, float)
- * @see #setOrtho2DLH(float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @return this
- */
- public Matrix4f ortho2DLH(float left, float right, float bottom, float top) {
- return ortho2DLH(left, right, bottom, top, this);
- }
-
- /**
- * Set this matrix to be an orthographic projection transformation for a right-handed coordinate system.
- *
- * This method is equivalent to calling {@link #setOrtho(float, float, float, float, float, float) setOrtho()} with
- *
- * In order to apply the orthographic projection to an already existing transformation,
- * use {@link #ortho2D(float, float, float, float) ortho2D()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrtho(float, float, float, float, float, float)
- * @see #ortho2D(float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @return this
- */
- public Matrix4f setOrtho2D(float left, float right, float bottom, float top) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00(2.0f / (right - left))
- ._m11(2.0f / (top - bottom))
- ._m22(-1.0f)
- ._m30((right + left) / (left - right))
- ._m31((top + bottom) / (bottom - top))
- ._properties(PROPERTY_AFFINE);
- return this;
- }
-
- /**
- * Set this matrix to be an orthographic projection transformation for a left-handed coordinate system.
- *
- * This method is equivalent to calling {@link #setOrtho(float, float, float, float, float, float) setOrthoLH()} with
- *
- * In order to apply the orthographic projection to an already existing transformation,
- * use {@link #ortho2DLH(float, float, float, float) ortho2DLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setOrthoLH(float, float, float, float, float, float)
- * @see #ortho2DLH(float, float, float, float)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @return this
- */
- public Matrix4f setOrtho2DLH(float left, float right, float bottom, float top) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00(2.0f / (right - left))
- ._m11(2.0f / (top - bottom))
- ._m30((right + left) / (left - right))
- ._m31((top + bottom) / (bottom - top))
- ._properties(PROPERTY_AFFINE);
- return this;
- }
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * This is equivalent to calling
- * {@link #lookAt(Vector3fc, Vector3fc, Vector3fc) lookAt}
- * with
- * In order to set the matrix to a lookalong transformation without post-multiplying it,
- * use {@link #setLookAlong(Vector3fc, Vector3fc) setLookAlong()}.
- *
- * @see #lookAlong(float, float, float, float, float, float)
- * @see #lookAt(Vector3fc, Vector3fc, Vector3fc)
- * @see #setLookAlong(Vector3fc, Vector3fc)
- *
- * @param dir
- * the direction in space to look along
- * @param up
- * the direction of 'up'
- * @return this
- */
- public Matrix4f lookAlong(Vector3fc dir, Vector3fc up) {
- return lookAlong(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z(), this);
- }
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * This is equivalent to calling
- * {@link #lookAt(Vector3fc, Vector3fc, Vector3fc) lookAt}
- * with
- * In order to set the matrix to a lookalong transformation without post-multiplying it,
- * use {@link #setLookAlong(Vector3fc, Vector3fc) setLookAlong()}.
- *
- * @see #lookAlong(float, float, float, float, float, float)
- * @see #lookAt(Vector3fc, Vector3fc, Vector3fc)
- * @see #setLookAlong(Vector3fc, Vector3fc)
- *
- * @param dir
- * the direction in space to look along
- * @param up
- * the direction of 'up'
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f lookAlong(Vector3fc dir, Vector3fc up, Matrix4f dest) {
- return lookAlong(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z(), dest);
- }
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * This is equivalent to calling
- * {@link #lookAt(float, float, float, float, float, float, float, float, float) lookAt()}
- * with
- * In order to set the matrix to a lookalong transformation without post-multiplying it,
- * use {@link #setLookAlong(float, float, float, float, float, float) setLookAlong()}
- *
- * @see #lookAt(float, float, float, float, float, float, float, float, float)
- * @see #setLookAlong(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f lookAlong(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setLookAlong(dirX, dirY, dirZ, upX, upY, upZ);
- return lookAlongGeneric(dirX, dirY, dirZ, upX, upY, upZ, dest);
- }
-
- private Matrix4f lookAlongGeneric(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix4f dest) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= -invDirLength;
- dirY *= -invDirLength;
- dirZ *= -invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirY * leftZ - dirZ * leftY;
- float upnY = dirZ * leftX - dirX * leftZ;
- float upnZ = dirX * leftY - dirY * leftX;
- // perform optimized matrix multiplication
- // introduce temporaries for dependent results
- float nm00 = m00() * leftX + m10() * upnX + m20() * dirX;
- float nm01 = m01() * leftX + m11() * upnX + m21() * dirX;
- float nm02 = m02() * leftX + m12() * upnX + m22() * dirX;
- float nm03 = m03() * leftX + m13() * upnX + m23() * dirX;
- float nm10 = m00() * leftY + m10() * upnY + m20() * dirY;
- float nm11 = m01() * leftY + m11() * upnY + m21() * dirY;
- float nm12 = m02() * leftY + m12() * upnY + m22() * dirY;
- float nm13 = m03() * leftY + m13() * upnY + m23() * dirY;
- return dest
- ._m20(m00() * leftZ + m10() * upnZ + m20() * dirZ)
- ._m21(m01() * leftZ + m11() * upnZ + m21() * dirZ)
- ._m22(m02() * leftZ + m12() * upnZ + m22() * dirZ)
- ._m23(m03() * leftZ + m13() * upnZ + m23() * dirZ)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * This is equivalent to calling
- * {@link #lookAt(float, float, float, float, float, float, float, float, float) lookAt()}
- * with
- * In order to set the matrix to a lookalong transformation without post-multiplying it,
- * use {@link #setLookAlong(float, float, float, float, float, float) setLookAlong()}
- *
- * @see #lookAt(float, float, float, float, float, float, float, float, float)
- * @see #setLookAlong(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix4f lookAlong(float dirX, float dirY, float dirZ,
- float upX, float upY, float upZ) {
- return lookAlong(dirX, dirY, dirZ, upX, upY, upZ, this);
- }
-
- /**
- * Set this matrix to a rotation transformation to make
- * This is equivalent to calling
- * {@link #setLookAt(Vector3fc, Vector3fc, Vector3fc) setLookAt()}
- * with
- * In order to apply the lookalong transformation to any previous existing transformation,
- * use {@link #lookAlong(Vector3fc, Vector3fc)}.
- *
- * @see #setLookAlong(Vector3fc, Vector3fc)
- * @see #lookAlong(Vector3fc, Vector3fc)
- *
- * @param dir
- * the direction in space to look along
- * @param up
- * the direction of 'up'
- * @return this
- */
- public Matrix4f setLookAlong(Vector3fc dir, Vector3fc up) {
- return setLookAlong(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z());
- }
-
- /**
- * Set this matrix to a rotation transformation to make
- * This is equivalent to calling
- * {@link #setLookAt(float, float, float, float, float, float, float, float, float)
- * setLookAt()} with
- * In order to apply the lookalong transformation to any previous existing transformation,
- * use {@link #lookAlong(float, float, float, float, float, float) lookAlong()}
- *
- * @see #setLookAlong(float, float, float, float, float, float)
- * @see #lookAlong(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix4f setLookAlong(float dirX, float dirY, float dirZ,
- float upX, float upY, float upZ) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= -invDirLength;
- dirY *= -invDirLength;
- dirZ *= -invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- this._m00(leftX)
- ._m01(dirY * leftZ - dirZ * leftY)
- ._m02(dirX)
- ._m03(0.0f)
- ._m10(leftY)
- ._m11(dirZ * leftX - dirX * leftZ)
- ._m12(dirY)
- ._m13(0.0f)
- ._m20(leftZ)
- ._m21(dirX * leftY - dirY * leftX)
- ._m22(dirZ)
- ._m23(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- /**
- * Set this matrix to be a "lookat" transformation for a right-handed coordinate system, that aligns
- *
- * In order to not make use of vectors to specify
- * In order to apply the lookat transformation to a previous existing transformation,
- * use {@link #lookAt(Vector3fc, Vector3fc, Vector3fc) lookAt()}.
- *
- * @see #setLookAt(float, float, float, float, float, float, float, float, float)
- * @see #lookAt(Vector3fc, Vector3fc, Vector3fc)
- *
- * @param eye
- * the position of the camera
- * @param center
- * the point in space to look at
- * @param up
- * the direction of 'up'
- * @return this
- */
- public Matrix4f setLookAt(Vector3fc eye, Vector3fc center, Vector3fc up) {
- return setLookAt(eye.x(), eye.y(), eye.z(), center.x(), center.y(), center.z(), up.x(), up.y(), up.z());
- }
-
- /**
- * Set this matrix to be a "lookat" transformation for a right-handed coordinate system,
- * that aligns
- * In order to apply the lookat transformation to a previous existing transformation,
- * use {@link #lookAt(float, float, float, float, float, float, float, float, float) lookAt}.
- *
- * @see #setLookAt(Vector3fc, Vector3fc, Vector3fc)
- * @see #lookAt(float, float, float, float, float, float, float, float, float)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix4f setLookAt(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ) {
- // Compute direction from position to lookAt
- float dirX, dirY, dirZ;
- dirX = eyeX - centerX;
- dirY = eyeY - centerY;
- dirZ = eyeZ - centerZ;
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= invDirLength;
- dirY *= invDirLength;
- dirZ *= invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirY * leftZ - dirZ * leftY;
- float upnY = dirZ * leftX - dirX * leftZ;
- float upnZ = dirX * leftY - dirY * leftX;
- return this
- ._m00(leftX)
- ._m01(upnX)
- ._m02(dirX)
- ._m03(0.0f)
- ._m10(leftY)
- ._m11(upnY)
- ._m12(dirY)
- ._m13(0.0f)
- ._m20(leftZ)
- ._m21(upnZ)
- ._m22(dirZ)
- ._m23(0.0f)
- ._m30(-(leftX * eyeX + leftY * eyeY + leftZ * eyeZ))
- ._m31(-(upnX * eyeX + upnY * eyeY + upnZ * eyeZ))
- ._m32(-(dirX * eyeX + dirY * eyeY + dirZ * eyeZ))
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
- * that aligns
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAt(Vector3fc, Vector3fc, Vector3fc)}.
- *
- * @see #lookAt(float, float, float, float, float, float, float, float, float)
- * @see #setLookAlong(Vector3fc, Vector3fc)
- *
- * @param eye
- * the position of the camera
- * @param center
- * the point in space to look at
- * @param up
- * the direction of 'up'
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f lookAt(Vector3fc eye, Vector3fc center, Vector3fc up, Matrix4f dest) {
- return lookAt(eye.x(), eye.y(), eye.z(), center.x(), center.y(), center.z(), up.x(), up.y(), up.z(), dest);
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
- * that aligns
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAt(Vector3fc, Vector3fc, Vector3fc)}.
- *
- * @see #lookAt(float, float, float, float, float, float, float, float, float)
- * @see #setLookAlong(Vector3fc, Vector3fc)
- *
- * @param eye
- * the position of the camera
- * @param center
- * the point in space to look at
- * @param up
- * the direction of 'up'
- * @return this
- */
- public Matrix4f lookAt(Vector3fc eye, Vector3fc center, Vector3fc up) {
- return lookAt(eye.x(), eye.y(), eye.z(), center.x(), center.y(), center.z(), up.x(), up.y(), up.z(), this);
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
- * that aligns
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAt(float, float, float, float, float, float, float, float, float) setLookAt()}.
- *
- * @see #lookAt(Vector3fc, Vector3fc, Vector3fc)
- * @see #setLookAt(float, float, float, float, float, float, float, float, float)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f lookAt(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setLookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
- else if ((properties & PROPERTY_PERSPECTIVE) != 0)
- return lookAtPerspective(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ, dest);
- return lookAtGeneric(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ, dest);
- }
- private Matrix4f lookAtGeneric(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ, Matrix4f dest) {
- // Compute direction from position to lookAt
- float dirX, dirY, dirZ;
- dirX = eyeX - centerX;
- dirY = eyeY - centerY;
- dirZ = eyeZ - centerZ;
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= invDirLength;
- dirY *= invDirLength;
- dirZ *= invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirY * leftZ - dirZ * leftY;
- float upnY = dirZ * leftX - dirX * leftZ;
- float upnZ = dirX * leftY - dirY * leftX;
-
- // calculate right matrix elements
- float rm30 = -(leftX * eyeX + leftY * eyeY + leftZ * eyeZ);
- float rm31 = -(upnX * eyeX + upnY * eyeY + upnZ * eyeZ);
- float rm32 = -(dirX * eyeX + dirY * eyeY + dirZ * eyeZ);
- // introduce temporaries for dependent results
- float nm00 = m00() * leftX + m10() * upnX + m20() * dirX;
- float nm01 = m01() * leftX + m11() * upnX + m21() * dirX;
- float nm02 = m02() * leftX + m12() * upnX + m22() * dirX;
- float nm03 = m03() * leftX + m13() * upnX + m23() * dirX;
- float nm10 = m00() * leftY + m10() * upnY + m20() * dirY;
- float nm11 = m01() * leftY + m11() * upnY + m21() * dirY;
- float nm12 = m02() * leftY + m12() * upnY + m22() * dirY;
- float nm13 = m03() * leftY + m13() * upnY + m23() * dirY;
-
- // perform optimized matrix multiplication
- // compute last column first, because others do not depend on it
- return dest
- ._m30(m00() * rm30 + m10() * rm31 + m20() * rm32 + m30())
- ._m31(m01() * rm30 + m11() * rm31 + m21() * rm32 + m31())
- ._m32(m02() * rm30 + m12() * rm31 + m22() * rm32 + m32())
- ._m33(m03() * rm30 + m13() * rm31 + m23() * rm32 + m33())
- ._m20(m00() * leftZ + m10() * upnZ + m20() * dirZ)
- ._m21(m01() * leftZ + m11() * upnZ + m21() * dirZ)
- ._m22(m02() * leftZ + m12() * upnZ + m22() * dirZ)
- ._m23(m03() * leftZ + m13() * upnZ + m23() * dirZ)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
- * that aligns
- * This method assumes
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAt(float, float, float, float, float, float, float, float, float) setLookAt()}.
- *
- * @see #setLookAt(float, float, float, float, float, float, float, float, float)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f lookAtPerspective(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ, Matrix4f dest) {
- // Compute direction from position to lookAt
- float dirX, dirY, dirZ;
- dirX = eyeX - centerX;
- dirY = eyeY - centerY;
- dirZ = eyeZ - centerZ;
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= invDirLength;
- dirY *= invDirLength;
- dirZ *= invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirY * leftZ - dirZ * leftY;
- float upnY = dirZ * leftX - dirX * leftZ;
- float upnZ = dirX * leftY - dirY * leftX;
- float rm30 = -(leftX * eyeX + leftY * eyeY + leftZ * eyeZ);
- float rm31 = -(upnX * eyeX + upnY * eyeY + upnZ * eyeZ);
- float rm32 = -(dirX * eyeX + dirY * eyeY + dirZ * eyeZ);
- float nm10 = m00() * leftY;
- float nm20 = m00() * leftZ;
- float nm21 = m11() * upnZ;
- float nm30 = m00() * rm30;
- float nm31 = m11() * rm31;
- float nm32 = m22() * rm32 + m32();
- float nm33 = m23() * rm32;
- return dest
- ._m00(m00() * leftX)
- ._m01(m11() * upnX)
- ._m02(m22() * dirX)
- ._m03(m23() * dirX)
- ._m10(nm10)
- ._m11(m11() * upnY)
- ._m12(m22() * dirY)
- ._m13(m23() * dirY)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(m22() * dirZ)
- ._m23(m23() * dirZ)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(nm33)
- ._properties(0);
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
- * that aligns
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAt(float, float, float, float, float, float, float, float, float) setLookAt()}.
- *
- * @see #lookAt(Vector3fc, Vector3fc, Vector3fc)
- * @see #setLookAt(float, float, float, float, float, float, float, float, float)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix4f lookAt(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ) {
- return lookAt(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ, this);
- }
-
- /**
- * Set this matrix to be a "lookat" transformation for a left-handed coordinate system, that aligns
- *
- * In order to not make use of vectors to specify
- * In order to apply the lookat transformation to a previous existing transformation,
- * use {@link #lookAtLH(Vector3fc, Vector3fc, Vector3fc) lookAt()}.
- *
- * @see #setLookAtLH(float, float, float, float, float, float, float, float, float)
- * @see #lookAtLH(Vector3fc, Vector3fc, Vector3fc)
- *
- * @param eye
- * the position of the camera
- * @param center
- * the point in space to look at
- * @param up
- * the direction of 'up'
- * @return this
- */
- public Matrix4f setLookAtLH(Vector3fc eye, Vector3fc center, Vector3fc up) {
- return setLookAtLH(eye.x(), eye.y(), eye.z(), center.x(), center.y(), center.z(), up.x(), up.y(), up.z());
- }
-
- /**
- * Set this matrix to be a "lookat" transformation for a left-handed coordinate system,
- * that aligns
- * In order to apply the lookat transformation to a previous existing transformation,
- * use {@link #lookAtLH(float, float, float, float, float, float, float, float, float) lookAtLH}.
- *
- * @see #setLookAtLH(Vector3fc, Vector3fc, Vector3fc)
- * @see #lookAtLH(float, float, float, float, float, float, float, float, float)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix4f setLookAtLH(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ) {
- // Compute direction from position to lookAt
- float dirX, dirY, dirZ;
- dirX = centerX - eyeX;
- dirY = centerY - eyeY;
- dirZ = centerZ - eyeZ;
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= invDirLength;
- dirY *= invDirLength;
- dirZ *= invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirY * leftZ - dirZ * leftY;
- float upnY = dirZ * leftX - dirX * leftZ;
- float upnZ = dirX * leftY - dirY * leftX;
- this._m00(leftX)
- ._m01(upnX)
- ._m02(dirX)
- ._m03(0.0f)
- ._m10(leftY)
- ._m11(upnY)
- ._m12(dirY)
- ._m13(0.0f)
- ._m20(leftZ)
- ._m21(upnZ)
- ._m22(dirZ)
- ._m23(0.0f)
- ._m30(-(leftX * eyeX + leftY * eyeY + leftZ * eyeZ))
- ._m31(-(upnX * eyeX + upnY * eyeY + upnZ * eyeZ))
- ._m32(-(dirX * eyeX + dirY * eyeY + dirZ * eyeZ))
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
- * that aligns
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAtLH(Vector3fc, Vector3fc, Vector3fc)}.
- *
- * @see #lookAtLH(float, float, float, float, float, float, float, float, float)
- *
- * @param eye
- * the position of the camera
- * @param center
- * the point in space to look at
- * @param up
- * the direction of 'up'
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f lookAtLH(Vector3fc eye, Vector3fc center, Vector3fc up, Matrix4f dest) {
- return lookAtLH(eye.x(), eye.y(), eye.z(), center.x(), center.y(), center.z(), up.x(), up.y(), up.z(), dest);
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
- * that aligns
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAtLH(Vector3fc, Vector3fc, Vector3fc)}.
- *
- * @see #lookAtLH(float, float, float, float, float, float, float, float, float)
- *
- * @param eye
- * the position of the camera
- * @param center
- * the point in space to look at
- * @param up
- * the direction of 'up'
- * @return this
- */
- public Matrix4f lookAtLH(Vector3fc eye, Vector3fc center, Vector3fc up) {
- return lookAtLH(eye.x(), eye.y(), eye.z(), center.x(), center.y(), center.z(), up.x(), up.y(), up.z(), this);
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
- * that aligns
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAtLH(float, float, float, float, float, float, float, float, float) setLookAtLH()}.
- *
- * @see #lookAtLH(Vector3fc, Vector3fc, Vector3fc)
- * @see #setLookAtLH(float, float, float, float, float, float, float, float, float)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f lookAtLH(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setLookAtLH(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ);
- else if ((properties & PROPERTY_PERSPECTIVE) != 0)
- return lookAtPerspectiveLH(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ, dest);
- return lookAtLHGeneric(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ, dest);
- }
- private Matrix4f lookAtLHGeneric(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ, Matrix4f dest) {
- // Compute direction from position to lookAt
- float dirX, dirY, dirZ;
- dirX = centerX - eyeX;
- dirY = centerY - eyeY;
- dirZ = centerZ - eyeZ;
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= invDirLength;
- dirY *= invDirLength;
- dirZ *= invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirY * leftZ - dirZ * leftY;
- float upnY = dirZ * leftX - dirX * leftZ;
- float upnZ = dirX * leftY - dirY * leftX;
-
- // calculate right matrix elements
- float rm30 = -(leftX * eyeX + leftY * eyeY + leftZ * eyeZ);
- float rm31 = -(upnX * eyeX + upnY * eyeY + upnZ * eyeZ);
- float rm32 = -(dirX * eyeX + dirY * eyeY + dirZ * eyeZ);
- // introduce temporaries for dependent results
- float nm00 = m00() * leftX + m10() * upnX + m20() * dirX;
- float nm01 = m01() * leftX + m11() * upnX + m21() * dirX;
- float nm02 = m02() * leftX + m12() * upnX + m22() * dirX;
- float nm03 = m03() * leftX + m13() * upnX + m23() * dirX;
- float nm10 = m00() * leftY + m10() * upnY + m20() * dirY;
- float nm11 = m01() * leftY + m11() * upnY + m21() * dirY;
- float nm12 = m02() * leftY + m12() * upnY + m22() * dirY;
- float nm13 = m03() * leftY + m13() * upnY + m23() * dirY;
-
- // perform optimized matrix multiplication
- // compute last column first, because others do not depend on it
- return dest
- ._m30(m00() * rm30 + m10() * rm31 + m20() * rm32 + m30())
- ._m31(m01() * rm30 + m11() * rm31 + m21() * rm32 + m31())
- ._m32(m02() * rm30 + m12() * rm31 + m22() * rm32 + m32())
- ._m33(m03() * rm30 + m13() * rm31 + m23() * rm32 + m33())
- ._m20(m00() * leftZ + m10() * upnZ + m20() * dirZ)
- ._m21(m01() * leftZ + m11() * upnZ + m21() * dirZ)
- ._m22(m02() * leftZ + m12() * upnZ + m22() * dirZ)
- ._m23(m03() * leftZ + m13() * upnZ + m23() * dirZ)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
- * that aligns
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAtLH(float, float, float, float, float, float, float, float, float) setLookAtLH()}.
- *
- * @see #lookAtLH(Vector3fc, Vector3fc, Vector3fc)
- * @see #setLookAtLH(float, float, float, float, float, float, float, float, float)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix4f lookAtLH(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ) {
- return lookAtLH(eyeX, eyeY, eyeZ, centerX, centerY, centerZ, upX, upY, upZ, this);
- }
-
- /**
- * Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
- * that aligns
- * This method assumes
- * If
- * In order to set the matrix to a lookat transformation without post-multiplying it,
- * use {@link #setLookAtLH(float, float, float, float, float, float, float, float, float) setLookAtLH()}.
- *
- * @see #setLookAtLH(float, float, float, float, float, float, float, float, float)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f lookAtPerspectiveLH(float eyeX, float eyeY, float eyeZ,
- float centerX, float centerY, float centerZ,
- float upX, float upY, float upZ, Matrix4f dest) {
- // Compute direction from position to lookAt
- float dirX, dirY, dirZ;
- dirX = centerX - eyeX;
- dirY = centerY - eyeY;
- dirZ = centerZ - eyeZ;
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= invDirLength;
- dirY *= invDirLength;
- dirZ *= invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * dirZ - upZ * dirY;
- leftY = upZ * dirX - upX * dirZ;
- leftZ = upX * dirY - upY * dirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirY * leftZ - dirZ * leftY;
- float upnY = dirZ * leftX - dirX * leftZ;
- float upnZ = dirX * leftY - dirY * leftX;
-
- // calculate right matrix elements
- float rm30 = -(leftX * eyeX + leftY * eyeY + leftZ * eyeZ);
- float rm31 = -(upnX * eyeX + upnY * eyeY + upnZ * eyeZ);
- float rm32 = -(dirX * eyeX + dirY * eyeY + dirZ * eyeZ);
-
- float nm00 = m00() * leftX;
- float nm01 = m11() * upnX;
- float nm02 = m22() * dirX;
- float nm03 = m23() * dirX;
- float nm10 = m00() * leftY;
- float nm11 = m11() * upnY;
- float nm12 = m22() * dirY;
- float nm13 = m23() * dirY;
- float nm20 = m00() * leftZ;
- float nm21 = m11() * upnZ;
- float nm22 = m22() * dirZ;
- float nm23 = m23() * dirZ;
- float nm30 = m00() * rm30;
- float nm31 = m11() * rm31;
- float nm32 = m22() * rm32 + m32();
- float nm33 = m23() * rm32;
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(nm33)
- ._properties(0);
- }
-
- /**
- * This method is equivalent to calling:
- * If
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspective(float, float, float, float, boolean) setPerspective}.
- *
- * @see #setPerspective(float, float, float, float, boolean)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspective(float, float, float, float) setPerspective}.
- *
- * @see #setPerspective(float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspective(float, float, float, float, boolean) setPerspective}.
- *
- * @see #setPerspective(float, float, float, float, boolean)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspective(float, float, float, float) setPerspective}.
- *
- * @see #setPerspective(float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveRect(float, float, float, float, boolean) setPerspectiveRect}.
- *
- * @see #setPerspectiveRect(float, float, float, float, boolean)
- *
- * @param width
- * the width of the near frustum plane
- * @param height
- * the height of the near frustum plane
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveRect(float, float, float, float) setPerspectiveRect}.
- *
- * @see #setPerspectiveRect(float, float, float, float)
- *
- * @param width
- * the width of the near frustum plane
- * @param height
- * the height of the near frustum plane
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveRect(float, float, float, float, boolean) setPerspectiveRect}.
- *
- * @see #setPerspectiveRect(float, float, float, float, boolean)
- *
- * @param width
- * the width of the near frustum plane
- * @param height
- * the height of the near frustum plane
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveRect(float, float, float, float) setPerspectiveRect}.
- *
- * @see #setPerspectiveRect(float, float, float, float)
- *
- * @param width
- * the width of the near frustum plane
- * @param height
- * the height of the near frustum plane
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveOffCenter(float, float, float, float, float, float, boolean) setPerspectiveOffCenter}.
- *
- * @see #setPerspectiveOffCenter(float, float, float, float, float, float, boolean)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param offAngleX
- * the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param offAngleY
- * the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveOffCenter(float, float, float, float, float, float) setPerspectiveOffCenter}.
- *
- * @see #setPerspectiveOffCenter(float, float, float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param offAngleX
- * the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param offAngleY
- * the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveOffCenter(float, float, float, float, float, float, boolean) setPerspectiveOffCenter}.
- *
- * @see #setPerspectiveOffCenter(float, float, float, float, float, float, boolean)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param offAngleX
- * the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param offAngleY
- * the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveOffCenter(float, float, float, float, float, float) setPerspectiveOffCenter}.
- *
- * @see #setPerspectiveOffCenter(float, float, float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param offAngleX
- * the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param offAngleY
- * the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveOffCenterFov(float, float, float, float, float, float, boolean) setPerspectiveOffCenterFov}.
- *
- * @see #setPerspectiveOffCenterFov(float, float, float, float, float, float, boolean)
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveOffCenterFov(float, float, float, float, float, float) setPerspectiveOffCenterFov}.
- *
- * @see #setPerspectiveOffCenterFov(float, float, float, float, float, float)
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveOffCenterFovLH(float, float, float, float, float, float, boolean) setPerspectiveOffCenterFovLH}.
- *
- * @see #setPerspectiveOffCenterFovLH(float, float, float, float, float, float, boolean)
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveOffCenterFovLH(float, float, float, float, float, float) setPerspectiveOffCenterFovLH}.
- *
- * @see #setPerspectiveOffCenterFovLH(float, float, float, float, float, float)
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspective(float, float, float, float, boolean) perspective()}.
- *
- * @see #perspective(float, float, float, float, boolean)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspective(float, float, float, float) perspective()}.
- *
- * @see #perspective(float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveRect(float, float, float, float, boolean) perspectiveRect()}.
- *
- * @see #perspectiveRect(float, float, float, float, boolean)
- *
- * @param width
- * the width of the near frustum plane
- * @param height
- * the height of the near frustum plane
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveRect(float, float, float, float) perspectiveRect()}.
- *
- * @see #perspectiveRect(float, float, float, float)
- *
- * @param width
- * the width of the near frustum plane
- * @param height
- * the height of the near frustum plane
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveOffCenter(float, float, float, float, float, float) perspectiveOffCenter()}.
- *
- * @see #perspectiveOffCenter(float, float, float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param offAngleX
- * the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param offAngleY
- * the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveOffCenter(float, float, float, float, float, float) perspectiveOffCenter()}.
- *
- * @see #perspectiveOffCenter(float, float, float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param offAngleX
- * the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param offAngleY
- * the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveOffCenterFov(float, float, float, float, float, float) perspectiveOffCenterFov()}.
- *
- * @see #perspectiveOffCenterFov(float, float, float, float, float, float)
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveOffCenterFov(float, float, float, float, float, float, boolean) perspectiveOffCenterFov()}.
- *
- * @see #perspectiveOffCenterFov(float, float, float, float, float, float, boolean)
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveOffCenterFovLH(float, float, float, float, float, float) perspectiveOffCenterFovLH()}.
- *
- * @see #perspectiveOffCenterFovLH(float, float, float, float, float, float)
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * The given angles
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveOffCenterFovLH(float, float, float, float, float, float, boolean) perspectiveOffCenterFovLH()}.
- *
- * @see #perspectiveOffCenterFovLH(float, float, float, float, float, float, boolean)
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveLH(float, float, float, float, boolean) setPerspectiveLH}.
- *
- * @see #setPerspectiveLH(float, float, float, float, boolean)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveLH(float, float, float, float, boolean) setPerspectiveLH}.
- *
- * @see #setPerspectiveLH(float, float, float, float, boolean)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveLH(float, float, float, float) setPerspectiveLH}.
- *
- * @see #setPerspectiveLH(float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setPerspectiveLH(float, float, float, float) setPerspectiveLH}.
- *
- * @see #setPerspectiveLH(float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveLH(float, float, float, float, boolean) perspectiveLH()}.
- *
- * @see #perspectiveLH(float, float, float, float, boolean)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective projection transformation to an existing transformation,
- * use {@link #perspectiveLH(float, float, float, float) perspectiveLH()}.
- *
- * @see #perspectiveLH(float, float, float, float)
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setFrustum(float, float, float, float, float, float, boolean) setFrustum()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setFrustum(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setFrustum(float, float, float, float, float, float) setFrustum()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setFrustum(float, float, float, float, float, float)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setFrustum(float, float, float, float, float, float, boolean) setFrustum()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setFrustum(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setFrustum(float, float, float, float, float, float) setFrustum()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setFrustum(float, float, float, float, float, float)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective frustum transformation to an existing transformation,
- * use {@link #frustum(float, float, float, float, float, float, boolean) frustum()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #frustum(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective frustum transformation to an existing transformation,
- * use {@link #frustum(float, float, float, float, float, float) frustum()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #frustum(float, float, float, float, float, float)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setFrustumLH(float, float, float, float, float, float, boolean) setFrustumLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setFrustumLH(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setFrustumLH(float, float, float, float, float, float, boolean) setFrustumLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setFrustumLH(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setFrustumLH(float, float, float, float, float, float) setFrustumLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setFrustumLH(float, float, float, float, float, float)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * In order to set the matrix to a perspective frustum transformation without post-multiplying,
- * use {@link #setFrustumLH(float, float, float, float, float, float) setFrustumLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #setFrustumLH(float, float, float, float, float, float)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective frustum transformation to an existing transformation,
- * use {@link #frustumLH(float, float, float, float, float, float, boolean) frustumLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #frustumLH(float, float, float, float, float, float, boolean)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * In order to apply the perspective frustum transformation to an existing transformation,
- * use {@link #frustumLH(float, float, float, float, float, float) frustumLH()}.
- *
- * Reference: http://www.songho.ca
- *
- * @see #frustumLH(float, float, float, float, float, float)
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * See: https://en.wikipedia.org/
- *
- * Reference: http://ksimek.github.io/
- *
- * @param alphaX
- * specifies the focal length and scale along the X axis
- * @param alphaY
- * specifies the focal length and scale along the Y axis
- * @param gamma
- * the skew coefficient between the X and Y axis (may be
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotate(Quaternionfc quat, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotation(quat);
- else if ((properties & PROPERTY_TRANSLATION) != 0)
- return rotateTranslation(quat, dest);
- else if ((properties & PROPERTY_AFFINE) != 0)
- return rotateAffine(quat, dest);
- return rotateGeneric(quat, dest);
- }
- private Matrix4f rotateGeneric(Quaternionfc quat, Matrix4f dest) {
- float w2 = quat.w() * quat.w(), x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y(), z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw, xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz, yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz, xw = quat.x() * quat.w(), dxw = xw + xw;
- float rm00 = w2 + x2 - z2 - y2;
- float rm01 = dxy + dzw;
- float rm02 = dxz - dyw;
- float rm10 = -dzw + dxy;
- float rm11 = y2 - z2 + w2 - x2;
- float rm12 = dyz + dxw;
- float rm20 = dyw + dxz;
- float rm21 = dyz - dxw;
- float rm22 = z2 - y2 - x2 + w2;
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02;
- float nm03 = m03() * rm00 + m13() * rm01 + m23() * rm02;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12;
- float nm13 = m03() * rm10 + m13() * rm11 + m23() * rm12;
- return dest
- ._m20(m00() * rm20 + m10() * rm21 + m20() * rm22)
- ._m21(m01() * rm20 + m11() * rm21 + m21() * rm22)
- ._m22(m02() * rm20 + m12() * rm21 + m22() * rm22)
- ._m23(m03() * rm20 + m13() * rm21 + m23() * rm22)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply the rotation transformation of the given {@link Quaternionfc} to this matrix.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @return this
- */
- public Matrix4f rotate(Quaternionfc quat) {
- return rotate(quat, this);
- }
-
- /**
- * Apply the rotation transformation of the given {@link Quaternionfc} to this {@link #isAffine() affine} matrix and store
- * the result in
- * This method assumes
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateAffine(Quaternionfc quat, Matrix4f dest) {
- float w2 = quat.w() * quat.w(), x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y(), z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw, xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz, yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz, xw = quat.x() * quat.w(), dxw = xw + xw;
- float rm00 = w2 + x2 - z2 - y2;
- float rm01 = dxy + dzw;
- float rm02 = dxz - dyw;
- float rm10 = -dzw + dxy;
- float rm11 = y2 - z2 + w2 - x2;
- float rm12 = dyz + dxw;
- float rm20 = dyw + dxz;
- float rm21 = dyz - dxw;
- float rm22 = z2 - y2 - x2 + w2;
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12;
- return dest
- ._m20(m00() * rm20 + m10() * rm21 + m20() * rm22)
- ._m21(m01() * rm20 + m11() * rm21 + m21() * rm22)
- ._m22(m02() * rm20 + m12() * rm21 + m22() * rm22)
- ._m23(0.0f)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(0.0f)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(0.0f)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply the rotation transformation of the given {@link Quaternionfc} to this matrix.
- *
- * This method assumes
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @return this
- */
- public Matrix4f rotateAffine(Quaternionfc quat) {
- return rotateAffine(quat, this);
- }
-
- /**
- * Apply the rotation transformation of the given {@link Quaternionfc} to this matrix, which is assumed to only contain a translation, and store
- * the result in
- * This method assumes
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateTranslation(Quaternionfc quat, Matrix4f dest) {
- float w2 = quat.w() * quat.w(), x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y(), z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw, xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz, yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz, xw = quat.x() * quat.w(), dxw = xw + xw;
- float rm00 = w2 + x2 - z2 - y2;
- float rm01 = dxy + dzw;
- float rm02 = dxz - dyw;
- float rm10 = -dzw + dxy;
- float rm11 = y2 - z2 + w2 - x2;
- float rm12 = dyz + dxw;
- float rm20 = dyw + dxz;
- float rm21 = dyz - dxw;
- float rm22 = z2 - y2 - x2 + w2;
- return dest
- ._m20(rm20)
- ._m21(rm21)
- ._m22(rm22)
- ._m23(0.0f)
- ._m00(rm00)
- ._m01(rm01)
- ._m02(rm02)
- ._m03(0.0f)
- ._m10(rm10)
- ._m11(rm11)
- ._m12(rm12)
- ._m13(0.0f)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply the rotation transformation of the given {@link Quaternionfc} to this matrix while using
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param ox
- * the x coordinate of the rotation origin
- * @param oy
- * the y coordinate of the rotation origin
- * @param oz
- * the z coordinate of the rotation origin
- * @return this
- */
- public Matrix4f rotateAround(Quaternionfc quat, float ox, float oy, float oz) {
- return rotateAround(quat, ox, oy, oz, this);
- }
-
- public Matrix4f rotateAroundAffine(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest) {
- float w2 = quat.w() * quat.w(), x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y(), z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw, xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz, yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz, xw = quat.x() * quat.w(), dxw = xw + xw;
- float rm00 = w2 + x2 - z2 - y2;
- float rm01 = dxy + dzw;
- float rm02 = dxz - dyw;
- float rm10 = -dzw + dxy;
- float rm11 = y2 - z2 + w2 - x2;
- float rm12 = dyz + dxw;
- float rm20 = dyw + dxz;
- float rm21 = dyz - dxw;
- float rm22 = z2 - y2 - x2 + w2;
- float tm30 = m00() * ox + m10() * oy + m20() * oz + m30();
- float tm31 = m01() * ox + m11() * oy + m21() * oz + m31();
- float tm32 = m02() * ox + m12() * oy + m22() * oz + m32();
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12;
- dest._m20(m00() * rm20 + m10() * rm21 + m20() * rm22)
- ._m21(m01() * rm20 + m11() * rm21 + m21() * rm22)
- ._m22(m02() * rm20 + m12() * rm21 + m22() * rm22)
- ._m23(0.0f)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(0.0f)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(0.0f)
- ._m30(-nm00 * ox - nm10 * oy - m20() * oz + tm30)
- ._m31(-nm01 * ox - nm11 * oy - m21() * oz + tm31)
- ._m32(-nm02 * ox - nm12 * oy - m22() * oz + tm32)
- ._m33(1.0f)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- return dest;
- }
-
- public Matrix4f rotateAround(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return rotationAround(quat, ox, oy, oz);
- else if ((properties & PROPERTY_AFFINE) != 0)
- return rotateAroundAffine(quat, ox, oy, oz, dest);
- return rotateAroundGeneric(quat, ox, oy, oz, dest);
- }
- private Matrix4f rotateAroundGeneric(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest) {
- float w2 = quat.w() * quat.w(), x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y(), z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw, xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz, yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz, xw = quat.x() * quat.w(), dxw = xw + xw;
- float rm00 = w2 + x2 - z2 - y2;
- float rm01 = dxy + dzw;
- float rm02 = dxz - dyw;
- float rm10 = -dzw + dxy;
- float rm11 = y2 - z2 + w2 - x2;
- float rm12 = dyz + dxw;
- float rm20 = dyw + dxz;
- float rm21 = dyz - dxw;
- float rm22 = z2 - y2 - x2 + w2;
- float tm30 = m00() * ox + m10() * oy + m20() * oz + m30();
- float tm31 = m01() * ox + m11() * oy + m21() * oz + m31();
- float tm32 = m02() * ox + m12() * oy + m22() * oz + m32();
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02;
- float nm03 = m03() * rm00 + m13() * rm01 + m23() * rm02;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12;
- float nm13 = m03() * rm10 + m13() * rm11 + m23() * rm12;
- dest._m20(m00() * rm20 + m10() * rm21 + m20() * rm22)
- ._m21(m01() * rm20 + m11() * rm21 + m21() * rm22)
- ._m22(m02() * rm20 + m12() * rm21 + m22() * rm22)
- ._m23(m03() * rm20 + m13() * rm21 + m23() * rm22)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m30(-nm00 * ox - nm10 * oy - m20() * oz + tm30)
- ._m31(-nm01 * ox - nm11 * oy - m21() * oz + tm31)
- ._m32(-nm02 * ox - nm12 * oy - m22() * oz + tm32)
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- return dest;
- }
-
- /**
- * Set this matrix to a transformation composed of a rotation of the specified {@link Quaternionfc} while using
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method is equivalent to calling:
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param ox
- * the x coordinate of the rotation origin
- * @param oy
- * the y coordinate of the rotation origin
- * @param oz
- * the z coordinate of the rotation origin
- * @return this
- */
- public Matrix4f rotationAround(Quaternionfc quat, float ox, float oy, float oz) {
- float w2 = quat.w() * quat.w(), x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y(), z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw, xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz, yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz, xw = quat.x() * quat.w(), dxw = xw + xw;
- this._m20(dyw + dxz)
- ._m21(dyz - dxw)
- ._m22(z2 - y2 - x2 + w2)
- ._m23(0.0f)
- ._m00(w2 + x2 - z2 - y2)
- ._m01(dxy + dzw)
- ._m02(dxz - dyw)
- ._m03(0.0f)
- ._m10(-dzw + dxy)
- ._m11(y2 - z2 + w2 - x2)
- ._m12(dyz + dxw)
- ._m13(0.0f)
- ._m30(-m00() * ox - m10() * oy - m20() * oz + ox)
- ._m31(-m01() * ox - m11() * oy - m21() * oz + oy)
- ._m32(-m02() * ox - m12() * oy - m22() * oz + oz)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- /**
- * Pre-multiply the rotation transformation of the given {@link Quaternionfc} to this matrix and store
- * the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without pre-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateLocal(Quaternionfc quat, Matrix4f dest) {
- float w2 = quat.w() * quat.w(), x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y(), z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w(), dzw = zw + zw, xy = quat.x() * quat.y(), dxy = xy + xy;
- float xz = quat.x() * quat.z(), dxz = xz + xz, yw = quat.y() * quat.w(), dyw = yw + yw;
- float yz = quat.y() * quat.z(), dyz = yz + yz, xw = quat.x() * quat.w(), dxw = xw + xw;
- float lm00 = w2 + x2 - z2 - y2;
- float lm01 = dxy + dzw;
- float lm02 = dxz - dyw;
- float lm10 = -dzw + dxy;
- float lm11 = y2 - z2 + w2 - x2;
- float lm12 = dyz + dxw;
- float lm20 = dyw + dxz;
- float lm21 = dyz - dxw;
- float lm22 = z2 - y2 - x2 + w2;
- float nm00 = lm00 * m00() + lm10 * m01() + lm20 * m02();
- float nm01 = lm01 * m00() + lm11 * m01() + lm21 * m02();
- float nm02 = lm02 * m00() + lm12 * m01() + lm22 * m02();
- float nm10 = lm00 * m10() + lm10 * m11() + lm20 * m12();
- float nm11 = lm01 * m10() + lm11 * m11() + lm21 * m12();
- float nm12 = lm02 * m10() + lm12 * m11() + lm22 * m12();
- float nm20 = lm00 * m20() + lm10 * m21() + lm20 * m22();
- float nm21 = lm01 * m20() + lm11 * m21() + lm21 * m22();
- float nm22 = lm02 * m20() + lm12 * m21() + lm22 * m22();
- float nm30 = lm00 * m30() + lm10 * m31() + lm20 * m32();
- float nm31 = lm01 * m30() + lm11 * m31() + lm21 * m32();
- float nm32 = lm02 * m30() + lm12 * m31() + lm22 * m32();
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(m03())
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(m13())
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(m23())
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Pre-multiply the rotation transformation of the given {@link Quaternionfc} to this matrix.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without pre-multiplying,
- * use {@link #rotation(Quaternionfc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotation(Quaternionfc)
- *
- * @param quat
- * the {@link Quaternionfc}
- * @return this
- */
- public Matrix4f rotateLocal(Quaternionfc quat) {
- return rotateLocal(quat, this);
- }
-
- public Matrix4f rotateAroundLocal(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest) {
- float w2 = quat.w() * quat.w();
- float x2 = quat.x() * quat.x();
- float y2 = quat.y() * quat.y();
- float z2 = quat.z() * quat.z();
- float zw = quat.z() * quat.w();
- float xy = quat.x() * quat.y();
- float xz = quat.x() * quat.z();
- float yw = quat.y() * quat.w();
- float yz = quat.y() * quat.z();
- float xw = quat.x() * quat.w();
- float lm00 = w2 + x2 - z2 - y2;
- float lm01 = xy + zw + zw + xy;
- float lm02 = xz - yw + xz - yw;
- float lm10 = -zw + xy - zw + xy;
- float lm11 = y2 - z2 + w2 - x2;
- float lm12 = yz + yz + xw + xw;
- float lm20 = yw + xz + xz + yw;
- float lm21 = yz + yz - xw - xw;
- float lm22 = z2 - y2 - x2 + w2;
- float tm00 = m00() - ox * m03();
- float tm01 = m01() - oy * m03();
- float tm02 = m02() - oz * m03();
- float tm10 = m10() - ox * m13();
- float tm11 = m11() - oy * m13();
- float tm12 = m12() - oz * m13();
- float tm20 = m20() - ox * m23();
- float tm21 = m21() - oy * m23();
- float tm22 = m22() - oz * m23();
- float tm30 = m30() - ox * m33();
- float tm31 = m31() - oy * m33();
- float tm32 = m32() - oz * m33();
- dest._m00(lm00 * tm00 + lm10 * tm01 + lm20 * tm02 + ox * m03())
- ._m01(lm01 * tm00 + lm11 * tm01 + lm21 * tm02 + oy * m03())
- ._m02(lm02 * tm00 + lm12 * tm01 + lm22 * tm02 + oz * m03())
- ._m03(m03())
- ._m10(lm00 * tm10 + lm10 * tm11 + lm20 * tm12 + ox * m13())
- ._m11(lm01 * tm10 + lm11 * tm11 + lm21 * tm12 + oy * m13())
- ._m12(lm02 * tm10 + lm12 * tm11 + lm22 * tm12 + oz * m13())
- ._m13(m13())
- ._m20(lm00 * tm20 + lm10 * tm21 + lm20 * tm22 + ox * m23())
- ._m21(lm01 * tm20 + lm11 * tm21 + lm21 * tm22 + oy * m23())
- ._m22(lm02 * tm20 + lm12 * tm21 + lm22 * tm22 + oz * m23())
- ._m23(m23())
- ._m30(lm00 * tm30 + lm10 * tm31 + lm20 * tm32 + ox * m33())
- ._m31(lm01 * tm30 + lm11 * tm31 + lm21 * tm32 + oy * m33())
- ._m32(lm02 * tm30 + lm12 * tm31 + lm22 * tm32 + oz * m33())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- return dest;
- }
-
- /**
- * Pre-multiply the rotation transformation of the given {@link Quaternionfc} to this matrix while using
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param ox
- * the x coordinate of the rotation origin
- * @param oy
- * the y coordinate of the rotation origin
- * @param oz
- * the z coordinate of the rotation origin
- * @return this
- */
- public Matrix4f rotateAroundLocal(Quaternionfc quat, float ox, float oy, float oz) {
- return rotateAroundLocal(quat, ox, oy, oz, this);
- }
-
- /**
- * Apply a rotation transformation, rotating about the given {@link AxisAngle4f}, to this matrix.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(AxisAngle4f)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- * @see #rotation(AxisAngle4f)
- *
- * @param axisAngle
- * the {@link AxisAngle4f} (needs to be {@link AxisAngle4f#normalize() normalized})
- * @return this
- */
- public Matrix4f rotate(AxisAngle4f axisAngle) {
- return rotate(axisAngle.angle, axisAngle.x, axisAngle.y, axisAngle.z);
- }
-
- /**
- * Apply a rotation transformation, rotating about the given {@link AxisAngle4f} and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(AxisAngle4f)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- * @see #rotation(AxisAngle4f)
- *
- * @param axisAngle
- * the {@link AxisAngle4f} (needs to be {@link AxisAngle4f#normalize() normalized})
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotate(AxisAngle4f axisAngle, Matrix4f dest) {
- return rotate(axisAngle.angle, axisAngle.x, axisAngle.y, axisAngle.z, dest);
- }
-
- /**
- * Apply a rotation transformation, rotating the given radians about the specified axis, to this matrix.
- *
- * The axis described by the
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(float, Vector3fc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- * @see #rotation(float, Vector3fc)
- *
- * @param angle
- * the angle in radians
- * @param axis
- * the rotation axis (needs to be {@link Vector3f#normalize() normalized})
- * @return this
- */
- public Matrix4f rotate(float angle, Vector3fc axis) {
- return rotate(angle, axis.x(), axis.y(), axis.z());
- }
-
- /**
- * Apply a rotation transformation, rotating the given radians about the specified axis and store the result in
- * The axis described by the
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying,
- * use {@link #rotation(float, Vector3fc)}.
- *
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float)
- * @see #rotation(float, Vector3fc)
- *
- * @param angle
- * the angle in radians
- * @param axis
- * the rotation axis (needs to be {@link Vector3f#normalize() normalized})
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotate(float angle, Vector3fc axis, Matrix4f dest) {
- return rotate(angle, axis.x(), axis.y(), axis.z(), dest);
- }
-
- public Vector4f unproject(float winX, float winY, float winZ, int[] viewport, Vector4f dest) {
- float a = m00() * m11() - m01() * m10();
- float b = m00() * m12() - m02() * m10();
- float c = m00() * m13() - m03() * m10();
- float d = m01() * m12() - m02() * m11();
- float e = m01() * m13() - m03() * m11();
- float f = m02() * m13() - m03() * m12();
- float g = m20() * m31() - m21() * m30();
- float h = m20() * m32() - m22() * m30();
- float i = m20() * m33() - m23() * m30();
- float j = m21() * m32() - m22() * m31();
- float k = m21() * m33() - m23() * m31();
- float l = m22() * m33() - m23() * m32();
- float det = a * l - b * k + c * j + d * i - e * h + f * g;
- det = 1.0f / det;
- float im00 = ( m11() * l - m12() * k + m13() * j) * det;
- float im01 = (-m01() * l + m02() * k - m03() * j) * det;
- float im02 = ( m31() * f - m32() * e + m33() * d) * det;
- float im03 = (-m21() * f + m22() * e - m23() * d) * det;
- float im10 = (-m10() * l + m12() * i - m13() * h) * det;
- float im11 = ( m00() * l - m02() * i + m03() * h) * det;
- float im12 = (-m30() * f + m32() * c - m33() * b) * det;
- float im13 = ( m20() * f - m22() * c + m23() * b) * det;
- float im20 = ( m10() * k - m11() * i + m13() * g) * det;
- float im21 = (-m00() * k + m01() * i - m03() * g) * det;
- float im22 = ( m30() * e - m31() * c + m33() * a) * det;
- float im23 = (-m20() * e + m21() * c - m23() * a) * det;
- float im30 = (-m10() * j + m11() * h - m12() * g) * det;
- float im31 = ( m00() * j - m01() * h + m02() * g) * det;
- float im32 = (-m30() * d + m31() * b - m32() * a) * det;
- float im33 = ( m20() * d - m21() * b + m22() * a) * det;
- float ndcX = (winX-viewport[0])/viewport[2]*2.0f-1.0f;
- float ndcY = (winY-viewport[1])/viewport[3]*2.0f-1.0f;
- float ndcZ = winZ+winZ-1.0f;
- float invW = 1.0f / (im03 * ndcX + im13 * ndcY + im23 * ndcZ + im33);
- return dest.set((im00 * ndcX + im10 * ndcY + im20 * ndcZ + im30) * invW,
- (im01 * ndcX + im11 * ndcY + im21 * ndcZ + im31) * invW,
- (im02 * ndcX + im12 * ndcY + im22 * ndcZ + im32) * invW,
- 1.0f);
- }
-
- public Vector3f unproject(float winX, float winY, float winZ, int[] viewport, Vector3f dest) {
- float a = m00() * m11() - m01() * m10();
- float b = m00() * m12() - m02() * m10();
- float c = m00() * m13() - m03() * m10();
- float d = m01() * m12() - m02() * m11();
- float e = m01() * m13() - m03() * m11();
- float f = m02() * m13() - m03() * m12();
- float g = m20() * m31() - m21() * m30();
- float h = m20() * m32() - m22() * m30();
- float i = m20() * m33() - m23() * m30();
- float j = m21() * m32() - m22() * m31();
- float k = m21() * m33() - m23() * m31();
- float l = m22() * m33() - m23() * m32();
- float det = a * l - b * k + c * j + d * i - e * h + f * g;
- det = 1.0f / det;
- float im00 = ( m11() * l - m12() * k + m13() * j) * det;
- float im01 = (-m01() * l + m02() * k - m03() * j) * det;
- float im02 = ( m31() * f - m32() * e + m33() * d) * det;
- float im03 = (-m21() * f + m22() * e - m23() * d) * det;
- float im10 = (-m10() * l + m12() * i - m13() * h) * det;
- float im11 = ( m00() * l - m02() * i + m03() * h) * det;
- float im12 = (-m30() * f + m32() * c - m33() * b) * det;
- float im13 = ( m20() * f - m22() * c + m23() * b) * det;
- float im20 = ( m10() * k - m11() * i + m13() * g) * det;
- float im21 = (-m00() * k + m01() * i - m03() * g) * det;
- float im22 = ( m30() * e - m31() * c + m33() * a) * det;
- float im23 = (-m20() * e + m21() * c - m23() * a) * det;
- float im30 = (-m10() * j + m11() * h - m12() * g) * det;
- float im31 = ( m00() * j - m01() * h + m02() * g) * det;
- float im32 = (-m30() * d + m31() * b - m32() * a) * det;
- float im33 = ( m20() * d - m21() * b + m22() * a) * det;
- float ndcX = (winX-viewport[0])/viewport[2]*2.0f-1.0f;
- float ndcY = (winY-viewport[1])/viewport[3]*2.0f-1.0f;
- float ndcZ = winZ+winZ-1.0f;
- float invW = 1.0f / (im03 * ndcX + im13 * ndcY + im23 * ndcZ + im33);
- return dest.set((im00 * ndcX + im10 * ndcY + im20 * ndcZ + im30) * invW,
- (im01 * ndcX + im11 * ndcY + im21 * ndcZ + im31) * invW,
- (im02 * ndcX + im12 * ndcY + im22 * ndcZ + im32) * invW);
- }
-
- public Vector4f unproject(Vector3fc winCoords, int[] viewport, Vector4f dest) {
- return unproject(winCoords.x(), winCoords.y(), winCoords.z(), viewport, dest);
- }
-
- public Vector3f unproject(Vector3fc winCoords, int[] viewport, Vector3f dest) {
- return unproject(winCoords.x(), winCoords.y(), winCoords.z(), viewport, dest);
- }
-
- public Matrix4f unprojectRay(float winX, float winY, int[] viewport, Vector3f originDest, Vector3f dirDest) {
- float a = m00() * m11() - m01() * m10();
- float b = m00() * m12() - m02() * m10();
- float c = m00() * m13() - m03() * m10();
- float d = m01() * m12() - m02() * m11();
- float e = m01() * m13() - m03() * m11();
- float f = m02() * m13() - m03() * m12();
- float g = m20() * m31() - m21() * m30();
- float h = m20() * m32() - m22() * m30();
- float i = m20() * m33() - m23() * m30();
- float j = m21() * m32() - m22() * m31();
- float k = m21() * m33() - m23() * m31();
- float l = m22() * m33() - m23() * m32();
- float det = a * l - b * k + c * j + d * i - e * h + f * g;
- det = 1.0f / det;
- float im00 = ( m11() * l - m12() * k + m13() * j) * det;
- float im01 = (-m01() * l + m02() * k - m03() * j) * det;
- float im02 = ( m31() * f - m32() * e + m33() * d) * det;
- float im03 = (-m21() * f + m22() * e - m23() * d) * det;
- float im10 = (-m10() * l + m12() * i - m13() * h) * det;
- float im11 = ( m00() * l - m02() * i + m03() * h) * det;
- float im12 = (-m30() * f + m32() * c - m33() * b) * det;
- float im13 = ( m20() * f - m22() * c + m23() * b) * det;
- float im20 = ( m10() * k - m11() * i + m13() * g) * det;
- float im21 = (-m00() * k + m01() * i - m03() * g) * det;
- float im22 = ( m30() * e - m31() * c + m33() * a) * det;
- float im23 = (-m20() * e + m21() * c - m23() * a) * det;
- float im30 = (-m10() * j + m11() * h - m12() * g) * det;
- float im31 = ( m00() * j - m01() * h + m02() * g) * det;
- float im32 = (-m30() * d + m31() * b - m32() * a) * det;
- float im33 = ( m20() * d - m21() * b + m22() * a) * det;
- float ndcX = (winX-viewport[0])/viewport[2]*2.0f-1.0f;
- float ndcY = (winY-viewport[1])/viewport[3]*2.0f-1.0f;
- float px = im00 * ndcX + im10 * ndcY + im30;
- float py = im01 * ndcX + im11 * ndcY + im31;
- float pz = im02 * ndcX + im12 * ndcY + im32;
- float invNearW = 1.0f / (im03 * ndcX + im13 * ndcY - im23 + im33);
- float nearX = (px - im20) * invNearW;
- float nearY = (py - im21) * invNearW;
- float nearZ = (pz - im22) * invNearW;
- float invW0 = 1.0f / (im03 * ndcX + im13 * ndcY + im33);
- float x0 = px * invW0;
- float y0 = py * invW0;
- float z0 = pz * invW0;
- originDest.x = nearX; originDest.y = nearY; originDest.z = nearZ;
- dirDest.x = x0 - nearX; dirDest.y = y0 - nearY; dirDest.z = z0 - nearZ;
- return this;
- }
-
- public Vector4f unprojectInv(Vector3fc winCoords, int[] viewport, Vector4f dest) {
- return unprojectInv(winCoords.x(), winCoords.y(), winCoords.z(), viewport, dest);
- }
-
- public Vector4f unprojectInv(float winX, float winY, float winZ, int[] viewport, Vector4f dest) {
- float ndcX = (winX-viewport[0])/viewport[2]*2.0f-1.0f;
- float ndcY = (winY-viewport[1])/viewport[3]*2.0f-1.0f;
- float ndcZ = winZ+winZ-1.0f;
- float invW = 1.0f / (m03() * ndcX + m13() * ndcY + m23() * ndcZ + m33());
- return dest.set((m00() * ndcX + m10() * ndcY + m20() * ndcZ + m30()) * invW,
- (m01() * ndcX + m11() * ndcY + m21() * ndcZ + m31()) * invW,
- (m02() * ndcX + m12() * ndcY + m22() * ndcZ + m32()) * invW,
- 1.0f);
- }
-
- public Matrix4f unprojectInvRay(float winX, float winY, int[] viewport, Vector3f originDest, Vector3f dirDest) {
- float ndcX = (winX-viewport[0])/viewport[2]*2.0f-1.0f;
- float ndcY = (winY-viewport[1])/viewport[3]*2.0f-1.0f;
- float px = m00() * ndcX + m10() * ndcY + m30();
- float py = m01() * ndcX + m11() * ndcY + m31();
- float pz = m02() * ndcX + m12() * ndcY + m32();
- float invNearW = 1.0f / (m03() * ndcX + m13() * ndcY - m23() + m33());
- float nearX = (px - m20()) * invNearW;
- float nearY = (py - m21()) * invNearW;
- float nearZ = (pz - m22()) * invNearW;
- float invW0 = 1.0f / (m03() * ndcX + m13() * ndcY + m33());
- float x0 = px * invW0;
- float y0 = py * invW0;
- float z0 = pz * invW0;
- originDest.x = nearX; originDest.y = nearY; originDest.z = nearZ;
- dirDest.x = x0 - nearX; dirDest.y = y0 - nearY; dirDest.z = z0 - nearZ;
- return this;
- }
-
- public Vector3f unprojectInv(Vector3fc winCoords, int[] viewport, Vector3f dest) {
- return unprojectInv(winCoords.x(), winCoords.y(), winCoords.z(), viewport, dest);
- }
-
- public Vector3f unprojectInv(float winX, float winY, float winZ, int[] viewport, Vector3f dest) {
- float ndcX = (winX-viewport[0])/viewport[2]*2.0f-1.0f;
- float ndcY = (winY-viewport[1])/viewport[3]*2.0f-1.0f;
- float ndcZ = winZ+winZ-1.0f;
- float invW = 1.0f / (m03() * ndcX + m13() * ndcY + m23() * ndcZ + m33());
- return dest.set((m00() * ndcX + m10() * ndcY + m20() * ndcZ + m30()) * invW,
- (m01() * ndcX + m11() * ndcY + m21() * ndcZ + m31()) * invW,
- (m02() * ndcX + m12() * ndcY + m22() * ndcZ + m32()) * invW);
- }
-
- public Vector4f project(float x, float y, float z, int[] viewport, Vector4f winCoordsDest) {
- float invW = 1.0f / Math.fma(m03(), x, Math.fma(m13(), y, Math.fma(m23(), z, m33())));
- float nx = Math.fma(m00(), x, Math.fma(m10(), y, Math.fma(m20(), z, m30()))) * invW;
- float ny = Math.fma(m01(), x, Math.fma(m11(), y, Math.fma(m21(), z, m31()))) * invW;
- float nz = Math.fma(m02(), x, Math.fma(m12(), y, Math.fma(m22(), z, m32()))) * invW;
- return winCoordsDest.set(Math.fma(Math.fma(nx, 0.5f, 0.5f), viewport[2], viewport[0]),
- Math.fma(Math.fma(ny, 0.5f, 0.5f), viewport[3], viewport[1]),
- Math.fma(0.5f, nz, 0.5f),
- 1.0f);
- }
-
- public Vector3f project(float x, float y, float z, int[] viewport, Vector3f winCoordsDest) {
- float invW = 1.0f / Math.fma(m03(), x, Math.fma(m13(), y, Math.fma(m23(), z, m33())));
- float nx = Math.fma(m00(), x, Math.fma(m10(), y, Math.fma(m20(), z, m30()))) * invW;
- float ny = Math.fma(m01(), x, Math.fma(m11(), y, Math.fma(m21(), z, m31()))) * invW;
- float nz = Math.fma(m02(), x, Math.fma(m12(), y, Math.fma(m22(), z, m32()))) * invW;
- winCoordsDest.x = Math.fma(Math.fma(nx, 0.5f, 0.5f), viewport[2], viewport[0]);
- winCoordsDest.y = Math.fma(Math.fma(ny, 0.5f, 0.5f), viewport[3], viewport[1]);
- winCoordsDest.z = Math.fma(0.5f, nz, 0.5f);
- return winCoordsDest;
- }
-
- public Vector4f project(Vector3fc position, int[] viewport, Vector4f winCoordsDest) {
- return project(position.x(), position.y(), position.z(), viewport, winCoordsDest);
- }
-
- public Vector3f project(Vector3fc position, int[] viewport, Vector3f winCoordsDest) {
- return project(position.x(), position.y(), position.z(), viewport, winCoordsDest);
- }
-
- public Matrix4f reflect(float a, float b, float c, float d, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.reflection(a, b, c, d);
- else if ((properties & PROPERTY_AFFINE) != 0)
- return reflectAffine(a, b, c, d, dest);
- return reflectGeneric(a, b, c, d, dest);
- }
- private Matrix4f reflectAffine(float a, float b, float c, float d, Matrix4f dest) {
- float da = a + a, db = b + b, dc = c + c, dd = d + d;
- float rm00 = 1.0f - da * a;
- float rm01 = -da * b;
- float rm02 = -da * c;
- float rm10 = -db * a;
- float rm11 = 1.0f - db * b;
- float rm12 = -db * c;
- float rm20 = -dc * a;
- float rm21 = -dc * b;
- float rm22 = 1.0f - dc * c;
- float rm30 = -dd * a;
- float rm31 = -dd * b;
- float rm32 = -dd * c;
- // matrix multiplication
- dest._m30(m00() * rm30 + m10() * rm31 + m20() * rm32 + m30())
- ._m31(m01() * rm30 + m11() * rm31 + m21() * rm32 + m31())
- ._m32(m02() * rm30 + m12() * rm31 + m22() * rm32 + m32())
- ._m33(m33());
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12;
- dest._m20(m00() * rm20 + m10() * rm21 + m20() * rm22)
- ._m21(m01() * rm20 + m11() * rm21 + m21() * rm22)
- ._m22(m02() * rm20 + m12() * rm21 + m22() * rm22)
- ._m23(0.0f)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(0.0f)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(0.0f)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- return dest;
- }
- private Matrix4f reflectGeneric(float a, float b, float c, float d, Matrix4f dest) {
- float da = a + a, db = b + b, dc = c + c, dd = d + d;
- float rm00 = 1.0f - da * a;
- float rm01 = -da * b;
- float rm02 = -da * c;
- float rm10 = -db * a;
- float rm11 = 1.0f - db * b;
- float rm12 = -db * c;
- float rm20 = -dc * a;
- float rm21 = -dc * b;
- float rm22 = 1.0f - dc * c;
- float rm30 = -dd * a;
- float rm31 = -dd * b;
- float rm32 = -dd * c;
- // matrix multiplication
- dest._m30(m00() * rm30 + m10() * rm31 + m20() * rm32 + m30())
- ._m31(m01() * rm30 + m11() * rm31 + m21() * rm32 + m31())
- ._m32(m02() * rm30 + m12() * rm31 + m22() * rm32 + m32())
- ._m33(m03() * rm30 + m13() * rm31 + m23() * rm32 + m33());
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02;
- float nm03 = m03() * rm00 + m13() * rm01 + m23() * rm02;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12;
- float nm13 = m03() * rm10 + m13() * rm11 + m23() * rm12;
- dest._m20(m00() * rm20 + m10() * rm21 + m20() * rm22)
- ._m21(m01() * rm20 + m11() * rm21 + m21() * rm22)
- ._m22(m02() * rm20 + m12() * rm21 + m22() * rm22)
- ._m23(m03() * rm20 + m13() * rm21 + m23() * rm22)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- return dest;
- }
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects about the given plane
- * specified via the equation
- * The vector
- * If
- * Reference: msdn.microsoft.com
- *
- * @param a
- * the x factor in the plane equation
- * @param b
- * the y factor in the plane equation
- * @param c
- * the z factor in the plane equation
- * @param d
- * the constant in the plane equation
- * @return this
- */
- public Matrix4f reflect(float a, float b, float c, float d) {
- return reflect(a, b, c, d, this);
- }
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects about the given plane
- * specified via the plane normal and a point on the plane.
- *
- * If
- * If
- * This method can be used to build a reflection transformation based on the orientation of a mirror object in the scene.
- * It is assumed that the default mirror plane's normal is
- * If
- * The vector
- * Reference: msdn.microsoft.com
- *
- * @param a
- * the x factor in the plane equation
- * @param b
- * the y factor in the plane equation
- * @param c
- * the z factor in the plane equation
- * @param d
- * the constant in the plane equation
- * @return this
- */
- public Matrix4f reflection(float a, float b, float c, float d) {
- float da = a + a, db = b + b, dc = c + c, dd = d + d;
- this._m00(1.0f - da * a)
- ._m01(-da * b)
- ._m02(-da * c)
- ._m03(0.0f)
- ._m10(-db * a)
- ._m11(1.0f - db * b)
- ._m12(-db * c)
- ._m13(0.0f)
- ._m20(-dc * a)
- ._m21(-dc * b)
- ._m22(1.0f - dc * c)
- ._m23(0.0f)
- ._m30(-dd * a)
- ._m31(-dd * b)
- ._m32(-dd * c)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- /**
- * Set this matrix to a mirror/reflection transformation that reflects about the given plane
- * specified via the plane normal and a point on the plane.
- *
- * @param nx
- * the x-coordinate of the plane normal
- * @param ny
- * the y-coordinate of the plane normal
- * @param nz
- * the z-coordinate of the plane normal
- * @param px
- * the x-coordinate of a point on the plane
- * @param py
- * the y-coordinate of a point on the plane
- * @param pz
- * the z-coordinate of a point on the plane
- * @return this
- */
- public Matrix4f reflection(float nx, float ny, float nz, float px, float py, float pz) {
- float invLength = Math.invsqrt(nx * nx + ny * ny + nz * nz);
- float nnx = nx * invLength;
- float nny = ny * invLength;
- float nnz = nz * invLength;
- /* See: http://mathworld.wolfram.com/Plane.html */
- return reflection(nnx, nny, nnz, -nnx * px - nny * py - nnz * pz);
- }
-
- /**
- * Set this matrix to a mirror/reflection transformation that reflects about the given plane
- * specified via the plane normal and a point on the plane.
- *
- * @param normal
- * the plane normal
- * @param point
- * a point on the plane
- * @return this
- */
- public Matrix4f reflection(Vector3fc normal, Vector3fc point) {
- return reflection(normal.x(), normal.y(), normal.z(), point.x(), point.y(), point.z());
- }
-
- /**
- * Set this matrix to a mirror/reflection transformation that reflects about a plane
- * specified via the plane orientation and a point on the plane.
- *
- * This method can be used to build a reflection transformation based on the orientation of a mirror object in the scene.
- * It is assumed that the default mirror plane's normal is
- * The normal matrix of
- * Please note that, if
- * The normal matrix of
- * Please note that, if
- * The normal matrix of
- * Please note that, if
- * The cofactor matrix can be used instead of {@link #normal()} to transform normals
- * when the orientation of the normals with respect to the surface should be preserved.
- *
- * @return this
- */
- public Matrix4f cofactor3x3() {
- return cofactor3x3(this);
- }
-
- /**
- * Compute the cofactor matrix of the upper left 3x3 submatrix of
- * The cofactor matrix can be used instead of {@link #normal(Matrix3f)} to transform normals
- * when the orientation of the normals with respect to the surface should be preserved.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f cofactor3x3(Matrix3f dest) {
- return dest._m00(m11() * m22() - m21() * m12())
- ._m01(m20() * m12() - m10() * m22())
- ._m02(m10() * m21() - m20() * m11())
- ._m10(m21() * m02() - m01() * m22())
- ._m11(m00() * m22() - m20() * m02())
- ._m12(m20() * m01() - m00() * m21())
- ._m20(m01() * m12() - m02() * m11())
- ._m21(m02() * m10() - m00() * m12())
- ._m22(m00() * m11() - m01() * m10());
- }
-
- /**
- * Compute the cofactor matrix of the upper left 3x3 submatrix of
- * The cofactor matrix can be used instead of {@link #normal(Matrix4f)} to transform normals
- * when the orientation of the normals with respect to the surface should be preserved.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f cofactor3x3(Matrix4f dest) {
- float nm10 = m21() * m02() - m01() * m22();
- float nm11 = m00() * m22() - m20() * m02();
- float nm12 = m20() * m01() - m00() * m21();
- float nm20 = m01() * m12() - m11() * m02();
- float nm21 = m02() * m10() - m12() * m00();
- float nm22 = m00() * m11() - m10() * m01();
- return dest
- ._m00(m11() * m22() - m21() * m12())
- ._m01(m20() * m12() - m10() * m22())
- ._m02(m10() * m21() - m20() * m11())
- ._m03(0.0f)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(0.0f)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(1.0f)
- ._properties((properties | PROPERTY_AFFINE) & ~(PROPERTY_TRANSLATION | PROPERTY_PERSPECTIVE));
- }
-
- /**
- * Normalize the upper left 3x3 submatrix of this matrix.
- *
- * The resulting matrix will map unit vectors to unit vectors, though a pair of orthogonal input unit
- * vectors need not be mapped to a pair of orthogonal output vectors if the original matrix was not orthogonal itself
- * (i.e. had skewing).
- *
- * @return this
- */
- public Matrix4f normalize3x3() {
- return normalize3x3(this);
- }
-
- public Matrix4f normalize3x3(Matrix4f dest) {
- float invXlen = Math.invsqrt(m00() * m00() + m01() * m01() + m02() * m02());
- float invYlen = Math.invsqrt(m10() * m10() + m11() * m11() + m12() * m12());
- float invZlen = Math.invsqrt(m20() * m20() + m21() * m21() + m22() * m22());
- return dest
- ._m00(m00() * invXlen)._m01(m01() * invXlen)._m02(m02() * invXlen)
- ._m10(m10() * invYlen)._m11(m11() * invYlen)._m12(m12() * invYlen)
- ._m20(m20() * invZlen)._m21(m21() * invZlen)._m22(m22() * invZlen)
- ._m30(m30())._m31(m31())._m32(m32())._m33(m33())
- ._properties(properties);
- }
-
- public Matrix3f normalize3x3(Matrix3f dest) {
- float invXlen = Math.invsqrt(m00() * m00() + m01() * m01() + m02() * m02());
- float invYlen = Math.invsqrt(m10() * m10() + m11() * m11() + m12() * m12());
- float invZlen = Math.invsqrt(m20() * m20() + m21() * m21() + m22() * m22());
- return dest
- ._m00(m00() * invXlen)._m01(m01() * invXlen)._m02(m02() * invXlen)
- ._m10(m10() * invYlen)._m11(m11() * invYlen)._m12(m12() * invYlen)
- ._m20(m20() * invZlen)._m21(m21() * invZlen)._m22(m22() * invZlen);
- }
-
- public Vector4f frustumPlane(int plane, Vector4f dest) {
- switch (plane) {
- case PLANE_NX:
- dest.set(m03() + m00(), m13() + m10(), m23() + m20(), m33() + m30()).normalize3();
- break;
- case PLANE_PX:
- dest.set(m03() - m00(), m13() - m10(), m23() - m20(), m33() - m30()).normalize3();
- break;
- case PLANE_NY:
- dest.set(m03() + m01(), m13() + m11(), m23() + m21(), m33() + m31()).normalize3();
- break;
- case PLANE_PY:
- dest.set(m03() - m01(), m13() - m11(), m23() - m21(), m33() - m31()).normalize3();
- break;
- case PLANE_NZ:
- dest.set(m03() + m02(), m13() + m12(), m23() + m22(), m33() + m32()).normalize3();
- break;
- case PLANE_PZ:
- dest.set(m03() - m02(), m13() - m12(), m23() - m22(), m33() - m32()).normalize3();
- break;
- default:
- throw new IllegalArgumentException("dest"); //$NON-NLS-1$
- }
- return dest;
- }
-
- public Vector3f frustumCorner(int corner, Vector3f point) {
- float d1, d2, d3;
- float n1x, n1y, n1z, n2x, n2y, n2z, n3x, n3y, n3z;
- switch (corner) {
- case CORNER_NXNYNZ: // left, bottom, near
- n1x = m03() + m00(); n1y = m13() + m10(); n1z = m23() + m20(); d1 = m33() + m30(); // left
- n2x = m03() + m01(); n2y = m13() + m11(); n2z = m23() + m21(); d2 = m33() + m31(); // bottom
- n3x = m03() + m02(); n3y = m13() + m12(); n3z = m23() + m22(); d3 = m33() + m32(); // near
- break;
- case CORNER_PXNYNZ: // right, bottom, near
- n1x = m03() - m00(); n1y = m13() - m10(); n1z = m23() - m20(); d1 = m33() - m30(); // right
- n2x = m03() + m01(); n2y = m13() + m11(); n2z = m23() + m21(); d2 = m33() + m31(); // bottom
- n3x = m03() + m02(); n3y = m13() + m12(); n3z = m23() + m22(); d3 = m33() + m32(); // near
- break;
- case CORNER_PXPYNZ: // right, top, near
- n1x = m03() - m00(); n1y = m13() - m10(); n1z = m23() - m20(); d1 = m33() - m30(); // right
- n2x = m03() - m01(); n2y = m13() - m11(); n2z = m23() - m21(); d2 = m33() - m31(); // top
- n3x = m03() + m02(); n3y = m13() + m12(); n3z = m23() + m22(); d3 = m33() + m32(); // near
- break;
- case CORNER_NXPYNZ: // left, top, near
- n1x = m03() + m00(); n1y = m13() + m10(); n1z = m23() + m20(); d1 = m33() + m30(); // left
- n2x = m03() - m01(); n2y = m13() - m11(); n2z = m23() - m21(); d2 = m33() - m31(); // top
- n3x = m03() + m02(); n3y = m13() + m12(); n3z = m23() + m22(); d3 = m33() + m32(); // near
- break;
- case CORNER_PXNYPZ: // right, bottom, far
- n1x = m03() - m00(); n1y = m13() - m10(); n1z = m23() - m20(); d1 = m33() - m30(); // right
- n2x = m03() + m01(); n2y = m13() + m11(); n2z = m23() + m21(); d2 = m33() + m31(); // bottom
- n3x = m03() - m02(); n3y = m13() - m12(); n3z = m23() - m22(); d3 = m33() - m32(); // far
- break;
- case CORNER_NXNYPZ: // left, bottom, far
- n1x = m03() + m00(); n1y = m13() + m10(); n1z = m23() + m20(); d1 = m33() + m30(); // left
- n2x = m03() + m01(); n2y = m13() + m11(); n2z = m23() + m21(); d2 = m33() + m31(); // bottom
- n3x = m03() - m02(); n3y = m13() - m12(); n3z = m23() - m22(); d3 = m33() - m32(); // far
- break;
- case CORNER_NXPYPZ: // left, top, far
- n1x = m03() + m00(); n1y = m13() + m10(); n1z = m23() + m20(); d1 = m33() + m30(); // left
- n2x = m03() - m01(); n2y = m13() - m11(); n2z = m23() - m21(); d2 = m33() - m31(); // top
- n3x = m03() - m02(); n3y = m13() - m12(); n3z = m23() - m22(); d3 = m33() - m32(); // far
- break;
- case CORNER_PXPYPZ: // right, top, far
- n1x = m03() - m00(); n1y = m13() - m10(); n1z = m23() - m20(); d1 = m33() - m30(); // right
- n2x = m03() - m01(); n2y = m13() - m11(); n2z = m23() - m21(); d2 = m33() - m31(); // top
- n3x = m03() - m02(); n3y = m13() - m12(); n3z = m23() - m22(); d3 = m33() - m32(); // far
- break;
- default:
- throw new IllegalArgumentException("corner"); //$NON-NLS-1$
- }
- float c23x, c23y, c23z;
- c23x = n2y * n3z - n2z * n3y;
- c23y = n2z * n3x - n2x * n3z;
- c23z = n2x * n3y - n2y * n3x;
- float c31x, c31y, c31z;
- c31x = n3y * n1z - n3z * n1y;
- c31y = n3z * n1x - n3x * n1z;
- c31z = n3x * n1y - n3y * n1x;
- float c12x, c12y, c12z;
- c12x = n1y * n2z - n1z * n2y;
- c12y = n1z * n2x - n1x * n2z;
- c12z = n1x * n2y - n1y * n2x;
- float invDot = 1.0f / (n1x * c23x + n1y * c23y + n1z * c23z);
- point.x = (-c23x * d1 - c31x * d2 - c12x * d3) * invDot;
- point.y = (-c23y * d1 - c31y * d2 - c12y * d3) * invDot;
- point.z = (-c23z * d1 - c31z * d2 - c12z * d3) * invDot;
- return point;
- }
-
- /**
- * Compute the eye/origin of the perspective frustum transformation defined by
- * Note that this method will only work using perspective projections obtained via one of the
- * perspective methods, such as {@link #perspective(float, float, float, float) perspective()}
- * or {@link #frustum(float, float, float, float, float, float) frustum()}.
- *
- * Generally, this method computes the origin in the local frame of
- * any coordinate system that existed before
- * This method is equivalent to calling:
- * Reference: http://geomalgorithms.com
- *
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @see #perspectiveInvOrigin(Vector3f)
- *
- * @param origin
- * will hold the origin of the coordinate system before applying
- * Note that this method will only work using perspective projections obtained via one of the
- * perspective methods, such as {@link #perspective(float, float, float, float) perspective()}
- * or {@link #frustum(float, float, float, float, float, float) frustum()}.
- *
- * If the inverse of the modelview-projection matrix is not available, then calling {@link #perspectiveOrigin(Vector3f)}
- * on the original modelview-projection matrix is preferred.
- *
- * @see #perspectiveOrigin(Vector3f)
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- public Vector3f perspectiveInvOrigin(Vector3f dest) {
- float invW = 1.0f / m23();
- dest.x = m20() * invW;
- dest.y = m21() * invW;
- dest.z = m22() * invW;
- return dest;
- }
-
- /**
- * Return the vertical field-of-view angle in radians of this perspective transformation matrix.
- *
- * Note that this method will only work using perspective projections obtained via one of the
- * perspective methods, such as {@link #perspective(float, float, float, float) perspective()}
- * or {@link #frustum(float, float, float, float, float, float) frustum()}.
- *
- * For orthogonal transformations this method will return
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @return the vertical field-of-view angle in radians
- */
- public float perspectiveFov() {
- /*
- * Compute the angle between the bottom and top frustum plane normals.
- */
- float n1x, n1y, n1z, n2x, n2y, n2z;
- n1x = m03() + m01(); n1y = m13() + m11(); n1z = m23() + m21(); // bottom
- n2x = m01() - m03(); n2y = m11() - m13(); n2z = m21() - m23(); // top
- float n1len = Math.sqrt(n1x * n1x + n1y * n1y + n1z * n1z);
- float n2len = Math.sqrt(n2x * n2x + n2y * n2y + n2z * n2z);
- return Math.acos((n1x * n2x + n1y * n2y + n1z * n2z) / (n1len * n2len));
- }
-
- /**
- * Extract the near clip plane distance from
- * This method only works if
- * This method only works if
- * If
- * If
- * Reference: ftp.sgi.com
- *
- * @param light
- * the light's vector
- * @param a
- * the x factor in the plane equation
- * @param b
- * the y factor in the plane equation
- * @param c
- * the z factor in the plane equation
- * @param d
- * the constant in the plane equation
- * @return this
- */
- public Matrix4f shadow(Vector4f light, float a, float b, float c, float d) {
- return shadow(light.x, light.y, light.z, light.w, a, b, c, d, this);
- }
-
- public Matrix4f shadow(Vector4f light, float a, float b, float c, float d, Matrix4f dest) {
- return shadow(light.x, light.y, light.z, light.w, a, b, c, d, dest);
- }
-
- /**
- * Apply a projection transformation to this matrix that projects onto the plane specified via the general plane equation
- *
- * If
- * If
- * Reference: ftp.sgi.com
- *
- * @param lightX
- * the x-component of the light's vector
- * @param lightY
- * the y-component of the light's vector
- * @param lightZ
- * the z-component of the light's vector
- * @param lightW
- * the w-component of the light's vector
- * @param a
- * the x factor in the plane equation
- * @param b
- * the y factor in the plane equation
- * @param c
- * the z factor in the plane equation
- * @param d
- * the constant in the plane equation
- * @return this
- */
- public Matrix4f shadow(float lightX, float lightY, float lightZ, float lightW, float a, float b, float c, float d) {
- return shadow(lightX, lightY, lightZ, lightW, a, b, c, d, this);
- }
-
- public Matrix4f shadow(float lightX, float lightY, float lightZ, float lightW, float a, float b, float c, float d, Matrix4f dest) {
- // normalize plane
- float invPlaneLen = Math.invsqrt(a*a + b*b + c*c);
- float an = a * invPlaneLen;
- float bn = b * invPlaneLen;
- float cn = c * invPlaneLen;
- float dn = d * invPlaneLen;
-
- float dot = an * lightX + bn * lightY + cn * lightZ + dn * lightW;
-
- // compute right matrix elements
- float rm00 = dot - an * lightX;
- float rm01 = -an * lightY;
- float rm02 = -an * lightZ;
- float rm03 = -an * lightW;
- float rm10 = -bn * lightX;
- float rm11 = dot - bn * lightY;
- float rm12 = -bn * lightZ;
- float rm13 = -bn * lightW;
- float rm20 = -cn * lightX;
- float rm21 = -cn * lightY;
- float rm22 = dot - cn * lightZ;
- float rm23 = -cn * lightW;
- float rm30 = -dn * lightX;
- float rm31 = -dn * lightY;
- float rm32 = -dn * lightZ;
- float rm33 = dot - dn * lightW;
-
- // matrix multiplication
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02 + m30() * rm03;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02 + m31() * rm03;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02 + m32() * rm03;
- float nm03 = m03() * rm00 + m13() * rm01 + m23() * rm02 + m33() * rm03;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12 + m30() * rm13;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12 + m31() * rm13;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12 + m32() * rm13;
- float nm13 = m03() * rm10 + m13() * rm11 + m23() * rm12 + m33() * rm13;
- float nm20 = m00() * rm20 + m10() * rm21 + m20() * rm22 + m30() * rm23;
- float nm21 = m01() * rm20 + m11() * rm21 + m21() * rm22 + m31() * rm23;
- float nm22 = m02() * rm20 + m12() * rm21 + m22() * rm22 + m32() * rm23;
- float nm23 = m03() * rm20 + m13() * rm21 + m23() * rm22 + m33() * rm23;
- dest._m30(m00() * rm30 + m10() * rm31 + m20() * rm32 + m30() * rm33)
- ._m31(m01() * rm30 + m11() * rm31 + m21() * rm32 + m31() * rm33)
- ._m32(m02() * rm30 + m12() * rm31 + m22() * rm32 + m32() * rm33)
- ._m33(m03() * rm30 + m13() * rm31 + m23() * rm32 + m33() * rm33)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- public Matrix4f shadow(Vector4f light, Matrix4fc planeTransform, Matrix4f dest) {
- // compute plane equation by transforming (y = 0)
- float a = planeTransform.m10();
- float b = planeTransform.m11();
- float c = planeTransform.m12();
- float d = -a * planeTransform.m30() - b * planeTransform.m31() - c * planeTransform.m32();
- return shadow(light.x, light.y, light.z, light.w, a, b, c, d, dest);
- }
-
- /**
- * Apply a projection transformation to this matrix that projects onto the plane with the general plane equation
- *
- * Before the shadow projection is applied, the plane is transformed via the specified
- * If
- * If
- * Before the shadow projection is applied, the plane is transformed via the specified
- * If
- * If
- * This method can be used to create the complete model transformation for a given object, including the translation of the object to
- * its position
- * This method can be used to create the complete model transformation for a given object, including the translation of the object to
- * its position
- * If preserving an up vector is not necessary when rotating the +Z axis, then a shortest arc rotation can be obtained
- * using {@link #billboardSpherical(Vector3fc, Vector3fc)}.
- *
- * @see #billboardSpherical(Vector3fc, Vector3fc)
- *
- * @param objPos
- * the position of the object to rotate towards
- * This method can be used to create the complete model transformation for a given object, including the translation of the object to
- * its position
- * In order to specify an up vector which needs to be maintained when rotating the +Z axis of the object,
- * use {@link #billboardSpherical(Vector3fc, Vector3fc, Vector3fc)}.
- *
- * @see #billboardSpherical(Vector3fc, Vector3fc, Vector3fc)
- *
- * @param objPos
- * the position of the object to rotate towards
- * This method is equivalent to calling:
- * This method is equivalent to calling:
- * The matrix
- * The axis-aligned bounding box of the unit frustum is
- * This method only works if
- * The transformation represented by
- * The
- * Reference: OpenGL SDK - Cascaded Shadow Maps
- *
- * @param view
- * the view transformation to build a corresponding orthographic projection to fit the frustum of
- * The corner coordinates are given in counter-clockwise order starting from the left corner on the smaller parallel side of the trapezoid
- * seen when looking at the trapezoid oriented with its shorter parallel edge at the bottom and its longer parallel edge at the top.
- *
- * Reference: Trapezoidal Shadow Maps (TSM) - Recipe
- *
- * @param p0x
- * the x coordinate of the left corner at the shorter edge of the trapezoid
- * @param p0y
- * the y coordinate of the left corner at the shorter edge of the trapezoid
- * @param p1x
- * the x coordinate of the right corner at the shorter edge of the trapezoid
- * @param p1y
- * the y coordinate of the right corner at the shorter edge of the trapezoid
- * @param p2x
- * the x coordinate of the right corner at the longer edge of the trapezoid
- * @param p2y
- * the y coordinate of the right corner at the longer edge of the trapezoid
- * @param p3x
- * the x coordinate of the left corner at the longer edge of the trapezoid
- * @param p3y
- * the y coordinate of the left corner at the longer edge of the trapezoid
- * @return this
- */
- public Matrix4f trapezoidCrop(float p0x, float p0y, float p1x, float p1y, float p2x, float p2y, float p3x, float p3y) {
- float aX = p1y - p0y, aY = p0x - p1x;
- float nm00 = aY;
- float nm10 = -aX;
- float nm30 = aX * p0y - aY * p0x;
- float nm01 = aX;
- float nm11 = aY;
- float nm31 = -(aX * p0x + aY * p0y);
- float c3x = nm00 * p3x + nm10 * p3y + nm30;
- float c3y = nm01 * p3x + nm11 * p3y + nm31;
- float s = -c3x / c3y;
- nm00 += s * nm01;
- nm10 += s * nm11;
- nm30 += s * nm31;
- float d1x = nm00 * p1x + nm10 * p1y + nm30;
- float d2x = nm00 * p2x + nm10 * p2y + nm30;
- float d = d1x * c3y / (d2x - d1x);
- nm31 += d;
- float sx = 2.0f / d2x;
- float sy = 1.0f / (c3y + d);
- float u = (sy + sy) * d / (1.0f - sy * d);
- float m03 = nm01 * sy;
- float m13 = nm11 * sy;
- float m33 = nm31 * sy;
- nm01 = (u + 1.0f) * m03;
- nm11 = (u + 1.0f) * m13;
- nm31 = (u + 1.0f) * m33 - u;
- nm00 = sx * nm00 - m03;
- nm10 = sx * nm10 - m13;
- nm30 = sx * nm30 - m33;
- set(nm00, nm01, 0, m03,
- nm10, nm11, 0, m13,
- 0, 0, 1, 0,
- nm30, nm31, 0, m33);
- _properties(0);
- return this;
- }
-
- public Matrix4f transformAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, Vector3f outMin, Vector3f outMax) {
- float xax = m00() * minX, xay = m01() * minX, xaz = m02() * minX;
- float xbx = m00() * maxX, xby = m01() * maxX, xbz = m02() * maxX;
- float yax = m10() * minY, yay = m11() * minY, yaz = m12() * minY;
- float ybx = m10() * maxY, yby = m11() * maxY, ybz = m12() * maxY;
- float zax = m20() * minZ, zay = m21() * minZ, zaz = m22() * minZ;
- float zbx = m20() * maxZ, zby = m21() * maxZ, zbz = m22() * maxZ;
- float xminx, xminy, xminz, yminx, yminy, yminz, zminx, zminy, zminz;
- float xmaxx, xmaxy, xmaxz, ymaxx, ymaxy, ymaxz, zmaxx, zmaxy, zmaxz;
- if (xax < xbx) {
- xminx = xax;
- xmaxx = xbx;
- } else {
- xminx = xbx;
- xmaxx = xax;
- }
- if (xay < xby) {
- xminy = xay;
- xmaxy = xby;
- } else {
- xminy = xby;
- xmaxy = xay;
- }
- if (xaz < xbz) {
- xminz = xaz;
- xmaxz = xbz;
- } else {
- xminz = xbz;
- xmaxz = xaz;
- }
- if (yax < ybx) {
- yminx = yax;
- ymaxx = ybx;
- } else {
- yminx = ybx;
- ymaxx = yax;
- }
- if (yay < yby) {
- yminy = yay;
- ymaxy = yby;
- } else {
- yminy = yby;
- ymaxy = yay;
- }
- if (yaz < ybz) {
- yminz = yaz;
- ymaxz = ybz;
- } else {
- yminz = ybz;
- ymaxz = yaz;
- }
- if (zax < zbx) {
- zminx = zax;
- zmaxx = zbx;
- } else {
- zminx = zbx;
- zmaxx = zax;
- }
- if (zay < zby) {
- zminy = zay;
- zmaxy = zby;
- } else {
- zminy = zby;
- zmaxy = zay;
- }
- if (zaz < zbz) {
- zminz = zaz;
- zmaxz = zbz;
- } else {
- zminz = zbz;
- zmaxz = zaz;
- }
- outMin.x = xminx + yminx + zminx + m30();
- outMin.y = xminy + yminy + zminy + m31();
- outMin.z = xminz + yminz + zminz + m32();
- outMax.x = xmaxx + ymaxx + zmaxx + m30();
- outMax.y = xmaxy + ymaxy + zmaxy + m31();
- outMax.z = xmaxz + ymaxz + zmaxz + m32();
- return this;
- }
-
- public Matrix4f transformAab(Vector3fc min, Vector3fc max, Vector3f outMin, Vector3f outMax) {
- return transformAab(min.x(), min.y(), min.z(), max.x(), max.y(), max.z(), outMin, outMax);
- }
-
- /**
- * Linearly interpolate
- * If
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying it,
- * use {@link #rotationTowards(Vector3fc, Vector3fc) rotationTowards()}.
- *
- * This method is equivalent to calling:
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying it,
- * use {@link #rotationTowards(Vector3fc, Vector3fc) rotationTowards()}.
- *
- * This method is equivalent to calling:
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying it,
- * use {@link #rotationTowards(float, float, float, float, float, float) rotationTowards()}.
- *
- * This method is equivalent to calling:
- * If
- * In order to set the matrix to a rotation transformation without post-multiplying it,
- * use {@link #rotationTowards(float, float, float, float, float, float) rotationTowards()}.
- *
- * This method is equivalent to calling:
- * In order to apply the rotation transformation to a previous existing transformation,
- * use {@link #rotateTowards(float, float, float, float, float, float) rotateTowards}.
- *
- * This method is equivalent to calling:
- * In order to apply the rotation transformation to a previous existing transformation,
- * use {@link #rotateTowards(float, float, float, float, float, float) rotateTowards}.
- *
- * This method is equivalent to calling:
- * This method is equivalent to calling:
- * This method is equivalent to calling:
- * That means, given the maximum extents of the coordinate system between
- * This method is equivalent to computing at least three adjacent corners using {@link #frustumCorner(int, Vector3f)}
- * and subtracting them to obtain the length and direction of the span vectors.
- *
- * @param corner
- * will hold one corner of the span (usually the corner {@link Matrix4fc#CORNER_NXNYNZ})
- * @param xDir
- * will hold the direction and length of the span along the positive X axis
- * @param yDir
- * will hold the direction and length of the span along the positive Y axis
- * @param zDir
- * will hold the direction and length of the span along the positive z axis
- * @return this
- */
- public Matrix4f affineSpan(Vector3f corner, Vector3f xDir, Vector3f yDir, Vector3f zDir) {
- float a = m10() * m22(), b = m10() * m21(), c = m10() * m02(), d = m10() * m01();
- float e = m11() * m22(), f = m11() * m20(), g = m11() * m02(), h = m11() * m00();
- float i = m12() * m21(), j = m12() * m20(), k = m12() * m01(), l = m12() * m00();
- float m = m20() * m02(), n = m20() * m01(), o = m21() * m02(), p = m21() * m00();
- float q = m22() * m01(), r = m22() * m00();
- float s = 1.0f / (m00() * m11() - m01() * m10()) * m22() + (m02() * m10() - m00() * m12()) * m21() + (m01() * m12() - m02() * m11()) * m20();
- float nm00 = (e - i) * s, nm01 = (o - q) * s, nm02 = (k - g) * s;
- float nm10 = (j - a) * s, nm11 = (r - m) * s, nm12 = (c - l) * s;
- float nm20 = (b - f) * s, nm21 = (n - p) * s, nm22 = (h - d) * s;
- corner.x = -nm00 - nm10 - nm20 + (a * m31() - b * m32() + f * m32() - e * m30() + i * m30() - j * m31()) * s;
- corner.y = -nm01 - nm11 - nm21 + (m * m31() - n * m32() + p * m32() - o * m30() + q * m30() - r * m31()) * s;
- corner.z = -nm02 - nm12 - nm22 + (g * m30() - k * m30() + l * m31() - c * m31() + d * m32() - h * m32()) * s;
- xDir.x = 2.0f * nm00; xDir.y = 2.0f * nm01; xDir.z = 2.0f * nm02;
- yDir.x = 2.0f * nm10; yDir.y = 2.0f * nm11; yDir.z = 2.0f * nm12;
- zDir.x = 2.0f * nm20; zDir.y = 2.0f * nm21; zDir.z = 2.0f * nm22;
- return this;
- }
-
- public boolean testPoint(float x, float y, float z) {
- float nxX = m03() + m00(), nxY = m13() + m10(), nxZ = m23() + m20(), nxW = m33() + m30();
- float pxX = m03() - m00(), pxY = m13() - m10(), pxZ = m23() - m20(), pxW = m33() - m30();
- float nyX = m03() + m01(), nyY = m13() + m11(), nyZ = m23() + m21(), nyW = m33() + m31();
- float pyX = m03() - m01(), pyY = m13() - m11(), pyZ = m23() - m21(), pyW = m33() - m31();
- float nzX = m03() + m02(), nzY = m13() + m12(), nzZ = m23() + m22(), nzW = m33() + m32();
- float pzX = m03() - m02(), pzY = m13() - m12(), pzZ = m23() - m22(), pzW = m33() - m32();
- return nxX * x + nxY * y + nxZ * z + nxW >= 0 && pxX * x + pxY * y + pxZ * z + pxW >= 0 &&
- nyX * x + nyY * y + nyZ * z + nyW >= 0 && pyX * x + pyY * y + pyZ * z + pyW >= 0 &&
- nzX * x + nzY * y + nzZ * z + nzW >= 0 && pzX * x + pzY * y + pzZ * z + pzW >= 0;
- }
-
- public boolean testSphere(float x, float y, float z, float r) {
- float invl;
- float nxX = m03() + m00(), nxY = m13() + m10(), nxZ = m23() + m20(), nxW = m33() + m30();
- invl = Math.invsqrt(nxX * nxX + nxY * nxY + nxZ * nxZ);
- nxX *= invl; nxY *= invl; nxZ *= invl; nxW *= invl;
- float pxX = m03() - m00(), pxY = m13() - m10(), pxZ = m23() - m20(), pxW = m33() - m30();
- invl = Math.invsqrt(pxX * pxX + pxY * pxY + pxZ * pxZ);
- pxX *= invl; pxY *= invl; pxZ *= invl; pxW *= invl;
- float nyX = m03() + m01(), nyY = m13() + m11(), nyZ = m23() + m21(), nyW = m33() + m31();
- invl = Math.invsqrt(nyX * nyX + nyY * nyY + nyZ * nyZ);
- nyX *= invl; nyY *= invl; nyZ *= invl; nyW *= invl;
- float pyX = m03() - m01(), pyY = m13() - m11(), pyZ = m23() - m21(), pyW = m33() - m31();
- invl = Math.invsqrt(pyX * pyX + pyY * pyY + pyZ * pyZ);
- pyX *= invl; pyY *= invl; pyZ *= invl; pyW *= invl;
- float nzX = m03() + m02(), nzY = m13() + m12(), nzZ = m23() + m22(), nzW = m33() + m32();
- invl = Math.invsqrt(nzX * nzX + nzY * nzY + nzZ * nzZ);
- nzX *= invl; nzY *= invl; nzZ *= invl; nzW *= invl;
- float pzX = m03() - m02(), pzY = m13() - m12(), pzZ = m23() - m22(), pzW = m33() - m32();
- invl = Math.invsqrt(pzX * pzX + pzY * pzY + pzZ * pzZ);
- pzX *= invl; pzY *= invl; pzZ *= invl; pzW *= invl;
- return nxX * x + nxY * y + nxZ * z + nxW >= -r && pxX * x + pxY * y + pxZ * z + pxW >= -r &&
- nyX * x + nyY * y + nyZ * z + nyW >= -r && pyX * x + pyY * y + pyZ * z + pyW >= -r &&
- nzX * x + nzY * y + nzZ * z + nzW >= -r && pzX * x + pzY * y + pzZ * z + pzW >= -r;
- }
-
- public boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- float nxX = m03() + m00(), nxY = m13() + m10(), nxZ = m23() + m20(), nxW = m33() + m30();
- float pxX = m03() - m00(), pxY = m13() - m10(), pxZ = m23() - m20(), pxW = m33() - m30();
- float nyX = m03() + m01(), nyY = m13() + m11(), nyZ = m23() + m21(), nyW = m33() + m31();
- float pyX = m03() - m01(), pyY = m13() - m11(), pyZ = m23() - m21(), pyW = m33() - m31();
- float nzX = m03() + m02(), nzY = m13() + m12(), nzZ = m23() + m22(), nzW = m33() + m32();
- float pzX = m03() - m02(), pzY = m13() - m12(), pzZ = m23() - m22(), pzW = m33() - m32();
- /*
- * This is an implementation of the "2.4 Basic intersection test" of the mentioned site.
- * It does not distinguish between partially inside and fully inside, though, so the test with the 'p' vertex is omitted.
- */
- return nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW &&
- pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW &&
- nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW &&
- pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW &&
- nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW &&
- pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW;
- }
-
- /**
- * Apply an oblique projection transformation to this matrix with the given values for
- * If
- * The oblique transformation is defined as:
- *
- * If
- * The oblique transformation is defined as:
- *
- * This method creates a view and perspective projection matrix assuming that there is a pinhole camera at position
- * All positions and lengths are in the same (world) unit.
- *
- * @param eye
- * the position of the camera
- * @param p
- * the bottom left corner of the near plane rectangle (will map to the bottom left corner in window coordinates)
- * @param x
- * the direction and length of the local "bottom/top" X axis/side of the near plane rectangle
- * @param y
- * the direction and length of the local "left/right" Y axis/side of the near plane rectangle
- * @param nearFarDist
- * the distance between the far and near plane (the near plane will be calculated by this method).
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * If the special value {@link Float#NEGATIVE_INFINITY} is used, the near and far planes will be swapped and
- * the near clipping plane will be at positive infinity.
- * If a negative value is used (except for {@link Float#NEGATIVE_INFINITY}) the near and far planes will be swapped
- * @param zeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * This effectively ensures that the resulting matrix will be equal to the one obtained from
- * {@link #setLookAt(Vector3fc, Vector3fc, Vector3fc)} called with the current
- * local origin of this matrix (as obtained by {@link #originAffine(Vector3f)}), the sum of this position and the
- * negated local Z axis as well as the given vector
- * This method must only be called on {@link #isAffine()} matrices.
- *
- * @param up
- * the up vector
- * @return this
- */
- public Matrix4f withLookAtUp(Vector3fc up) {
- return withLookAtUp(up.x(), up.y(), up.z(), this);
- }
-
- public Matrix4f withLookAtUp(Vector3fc up, Matrix4f dest) {
- return withLookAtUp(up.x(), up.y(), up.z());
- }
-
- /**
- * Apply a transformation to this matrix to ensure that the local Y axis (as obtained by {@link #positiveY(Vector3f)})
- * will be coplanar to the plane spanned by the local Z axis (as obtained by {@link #positiveZ(Vector3f)}) and the
- * given vector
- * This effectively ensures that the resulting matrix will be equal to the one obtained from
- * {@link #setLookAt(float, float, float, float, float, float, float, float, float)} called with the current
- * local origin of this matrix (as obtained by {@link #originAffine(Vector3f)}), the sum of this position and the
- * negated local Z axis as well as the given vector
- * This method must only be called on {@link #isAffine()} matrices.
- *
- * @param upX
- * the x coordinate of the up vector
- * @param upY
- * the y coordinate of the up vector
- * @param upZ
- * the z coordinate of the up vector
- * @return this
- */
- public Matrix4f withLookAtUp(float upX, float upY, float upZ) {
- return withLookAtUp(upX, upY, upZ, this);
- }
-
- public Matrix4f withLookAtUp(float upX, float upY, float upZ, Matrix4f dest) {
- float y = (upY * m21() - upZ * m11()) * m02() +
- (upZ * m01() - upX * m21()) * m12() +
- (upX * m11() - upY * m01()) * m22();
- float x = upX * m01() + upY * m11() + upZ * m21();
- if ((properties & PROPERTY_ORTHONORMAL) == 0)
- x *= Math.sqrt(m01() * m01() + m11() * m11() + m21() * m21());
- float invsqrt = Math.invsqrt(y * y + x * x);
- float c = x * invsqrt, s = y * invsqrt;
- float nm00 = c * m00() - s * m01(), nm10 = c * m10() - s * m11(), nm20 = c * m20() - s * m21(), nm31 = s * m30() + c * m31();
- float nm01 = s * m00() + c * m01(), nm11 = s * m10() + c * m11(), nm21 = s * m20() + c * m21(), nm30 = c * m30() - s * m31();
- dest._m00(nm00)._m10(nm10)._m20(nm20)._m30(nm30)
- ._m01(nm01)._m11(nm11)._m21(nm21)._m31(nm31);
- if (dest != this) {
- dest._m02(m02())._m12(m12())._m22(m22())._m32(m32())
- ._m03(m03())._m13(m13())._m23(m23())._m33(m33());
- }
- dest._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- return dest;
- }
-
- /**
- * Multiply
- * This {@link Matrix4fStack} class inherits from {@link Matrix4f}, so the current/top matrix is always the {@link Matrix4fStack}/{@link Matrix4f} itself. This
- * affects all operations in {@link Matrix4f} that take another {@link Matrix4f} as parameter. If a {@link Matrix4fStack} is used as argument to those methods,
- * the effective argument will always be the current matrix of the matrix stack.
- *
- * @author Kai Burjack
- */
-public class Matrix4fStack extends Matrix4f {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * The matrix stack as a non-growable array. The size of the stack must be specified in the {@link #Matrix4fStack(int) constructor}.
- */
- private Matrix4f[] mats;
-
- /**
- * The index of the "current" matrix within {@link #mats}.
- */
- private int curr;
-
- /**
- * Create a new {@link Matrix4fStack} of the given size.
- *
- * Initially the stack pointer is at zero and the current matrix is set to identity.
- *
- * @param stackSize
- * the size of the stack. This must be at least 1, in which case the {@link Matrix4fStack} simply only consists of
- * Invoking this constructor from client code will result in an inconsistent state of the
- * created {@link Matrix4fStack} instance.
- */
- public Matrix4fStack() {
- /* Empty! */
- }
-
- /**
- * Set the stack pointer to zero and set the current/bottom matrix to {@link #identity() identity}.
- *
- * @return this
- */
- public Matrix4fStack clear() {
- curr = 0;
- identity();
- return this;
- }
-
- /**
- * Increment the stack pointer by one and set the values of the new current matrix to the one directly below it.
- *
- * @return this
- */
- public Matrix4fStack pushMatrix() {
- if (curr == mats.length) {
- throw new IllegalStateException("max stack size of " + (curr + 1) + " reached"); //$NON-NLS-1$ //$NON-NLS-2$
- }
- mats[curr++].set(this);
- return this;
- }
-
- /**
- * Decrement the stack pointer by one.
- *
- * This will effectively dispose of the current matrix.
- *
- * @return this
- */
- public Matrix4fStack popMatrix() {
- if (curr == 0) {
- throw new IllegalStateException("already at the bottom of the stack"); //$NON-NLS-1$
- }
- set(mats[--curr]);
- return this;
- }
-
- public int hashCode() {
- final int prime = 31;
- int result = super.hashCode();
- result = prime * result + curr;
- for (int i = 0; i < curr; i++) {
- result = prime * result + mats[i].hashCode();
- }
- return result;
- }
-
- /*
- * Contract between Matrix4f and Matrix4fStack:
- *
- * - Matrix4f.equals(Matrix4fStack) is true iff all the 16 matrix elements are equal
- * - Matrix4fStack.equals(Matrix4f) is true iff all the 16 matrix elements are equal
- * - Matrix4fStack.equals(Matrix4fStack) is true iff all 16 matrix elements are equal AND the matrix arrays as well as the stack pointer are equal
- * - everything else is inequal
- */
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (!super.equals(obj))
- return false;
- if (obj instanceof Matrix4fStack) {
- Matrix4fStack other = (Matrix4fStack) obj;
- if (curr != other.curr)
- return false;
- for (int i = 0; i < curr; i++) {
- if (!mats[i].equals(other.mats[i]))
- return false;
- }
- }
- return true;
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- super.writeExternal(out);
- out.writeInt(curr);
- for (int i = 0; i < curr; i++) {
- out.writeObject(mats[i]);
- }
- }
-
- public void readExternal(ObjectInput in) throws IOException {
- super.readExternal(in);
- curr = in.readInt();
- mats = new Matrix4fStack[curr];
- for (int i = 0; i < curr; i++) {
- Matrix4f m = new Matrix4f();
- m.readExternal(in);
- mats[i] = m;
- }
- }
-
- public Object clone() throws CloneNotSupportedException {
- Matrix4fStack cloned = (Matrix4fStack) super.clone();
- Matrix4f[] clonedMats = new Matrix4f[mats.length];
- for (int i = 0; i < mats.length; i++)
- clonedMats[i] = (Matrix4f) mats[i].clone();
- cloned.mats = clonedMats;
- return cloned;
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix4fc.java b/src/main/java/com/jozufozu/flywheel/util/joml/Matrix4fc.java
deleted file mode 100644
index 9652c5ffa..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix4fc.java
+++ /dev/null
@@ -1,5926 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2016-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.util.*;
-
-
-/**
- * Interface to a read-only view of a 4x4 matrix of single-precision floats.
- *
- * @author Kai Burjack
- */
-public interface Matrix4fc {
-
- /**
- * Argument to the first parameter of {@link #frustumPlane(int, Vector4f)}
- * identifying the plane with equation
- * If
- * If
- * This method neither assumes nor checks for any matrix properties of
- * If
- * If
- * If
- * This method assumes that
- * This method will not modify either the last row of
- * If
- * If
- * This method assumes that the given
- * If
- * This method assumes that
- * This method will not modify either the last row of
- * If
- * This method assumes that
- * This method will not modify either the last row of
- * If
- * If
- * The other components of
- * The matrices
- * The other components of
- * The other components of
- * The other components of
- * If
- * If
- * This method can be used to quickly obtain the inverse of a perspective projection matrix when being obtained via {@link #perspective(float, float, float, float, Matrix4f) perspective()}.
- *
- * @see #perspective(float, float, float, float, Matrix4f)
- *
- * @param dest
- * will hold the inverse of
- * This method can be used to quickly obtain the inverse of a perspective projection matrix.
- *
- * If this matrix represents a symmetric perspective frustum transformation, as obtained via {@link #perspective(float, float, float, float, Matrix4f) perspective()}, then
- * {@link #invertPerspective(Matrix4f)} should be used instead.
- *
- * @see #frustum(float, float, float, float, float, float, Matrix4f)
- * @see #invertPerspective(Matrix4f)
- *
- * @param dest
- * will hold the inverse of
- * This method can be used to quickly obtain the inverse of an orthographic projection matrix.
- *
- * @param dest
- * will hold the inverse of
- * This method can be used to quickly obtain the inverse of the combination of the view and projection matrices, when both were obtained
- * via the common methods {@link #perspective(float, float, float, float, Matrix4f) perspective()} and {@link #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f) lookAt()} or
- * other methods, that build affine matrices, such as {@link #translate(float, float, float, Matrix4f) translate} and {@link #rotate(float, float, float, float, Matrix4f)}, except for {@link #scale(float, float, float, Matrix4f) scale()}.
- *
- * For the special cases of the matrices
- * All other matrix elements are left unchanged.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f transpose3x3(Matrix4f dest);
-
- /**
- * Transpose only the upper left 3x3 submatrix of this matrix and store the result in
- * This method assumes that the first three column vectors of the upper left 3x3 submatrix are not normalized and
- * thus allows to ignore any additional scaling factor that is applied to the matrix.
- *
- * @see Quaternionf#setFromUnnormalized(Matrix4fc)
- *
- * @param dest
- * the destination {@link Quaternionf}
- * @return the passed in destination
- */
- Quaternionf getUnnormalizedRotation(Quaternionf dest);
-
- /**
- * Get the current values of
- * This method assumes that the first three column vectors of the upper left 3x3 submatrix are normalized.
- *
- * @see Quaternionf#setFromNormalized(Matrix4fc)
- *
- * @param dest
- * the destination {@link Quaternionf}
- * @return the passed in destination
- */
- Quaternionf getNormalizedRotation(Quaternionf dest);
-
- /**
- * Store this matrix in column-major order into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the matrix is stored, use {@link #get(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get(int, FloatBuffer)
- *
- * @param buffer
- * will receive the values of this matrix in column-major order at its current position
- * @return the passed in buffer
- */
- FloatBuffer get(FloatBuffer buffer);
-
- /**
- * Store this matrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of this matrix in column-major order
- * @return the passed in buffer
- */
- FloatBuffer get(int index, FloatBuffer buffer);
-
- /**
- * Store this matrix in column-major order into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the matrix is stored, use {@link #get(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get(int, ByteBuffer)
- *
- * @param buffer
- * will receive the values of this matrix in column-major order at its current position
- * @return the passed in buffer
- */
- ByteBuffer get(ByteBuffer buffer);
-
- /**
- * Store this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of this matrix in column-major order
- * @return the passed in buffer
- */
- ByteBuffer get(int index, ByteBuffer buffer);
-
- /**
- * Store the upper 4x3 submatrix in column-major order into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the matrix is stored, use {@link #get(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get(int, FloatBuffer)
- *
- * @param buffer
- * will receive the values of the upper 4x3 submatrix in column-major order at its current position
- * @return the passed in buffer
- */
- FloatBuffer get4x3(FloatBuffer buffer);
-
- /**
- * Store the upper 4x3 submatrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of the upper 4x3 submatrix in column-major order
- * @return the passed in buffer
- */
- FloatBuffer get4x3(int index, FloatBuffer buffer);
-
- /**
- * Store the upper 4x3 submatrix in column-major order into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the matrix is stored, use {@link #get(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get(int, ByteBuffer)
- *
- * @param buffer
- * will receive the values of the upper 4x3 submatrix in column-major order at its current position
- * @return the passed in buffer
- */
- ByteBuffer get4x3(ByteBuffer buffer);
-
- /**
- * Store the upper 4x3 submatrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of the upper 4x3 submatrix in column-major order
- * @return the passed in buffer
- */
- ByteBuffer get4x3(int index, ByteBuffer buffer);
-
- /**
- * Store the left 3x4 submatrix in column-major order into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the matrix is stored, use {@link #get3x4(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get3x4(int, FloatBuffer)
- *
- * @param buffer
- * will receive the values of the left 3x4 submatrix in column-major order at its current position
- * @return the passed in buffer
- */
- FloatBuffer get3x4(FloatBuffer buffer);
-
- /**
- * Store the left 3x4 submatrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of the left 3x4 submatrix in column-major order
- * @return the passed in buffer
- */
- FloatBuffer get3x4(int index, FloatBuffer buffer);
-
- /**
- * Store the left 3x4 submatrix in column-major order into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the matrix is stored, use {@link #get3x4(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get3x4(int, ByteBuffer)
- *
- * @param buffer
- * will receive the values of the left 3x4 submatrix in column-major order at its current position
- * @return the passed in buffer
- */
- ByteBuffer get3x4(ByteBuffer buffer);
-
- /**
- * Store the left 3x4 submatrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of the left 3x4 submatrix in column-major order
- * @return the passed in buffer
- */
- ByteBuffer get3x4(int index, ByteBuffer buffer);
-
- /**
- * Store the transpose of this matrix in column-major order into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the matrix is stored, use {@link #getTransposed(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #getTransposed(int, FloatBuffer)
- *
- * @param buffer
- * will receive the values of this matrix in column-major order at its current position
- * @return the passed in buffer
- */
- FloatBuffer getTransposed(FloatBuffer buffer);
-
- /**
- * Store the transpose of this matrix in column-major order into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of this matrix in column-major order
- * @return the passed in buffer
- */
- FloatBuffer getTransposed(int index, FloatBuffer buffer);
-
- /**
- * Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the matrix is stored, use {@link #getTransposed(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #getTransposed(int, ByteBuffer)
- *
- * @param buffer
- * will receive the values of this matrix in column-major order at its current position
- * @return the passed in buffer
- */
- ByteBuffer getTransposed(ByteBuffer buffer);
-
- /**
- * Store the transpose of this matrix in column-major order into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- *
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of this matrix in column-major order
- * @return the passed in buffer
- */
- ByteBuffer getTransposed(int index, ByteBuffer buffer);
-
- /**
- * Store the upper 4x3 submatrix of
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the matrix is stored, use {@link #get4x3Transposed(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get4x3Transposed(int, FloatBuffer)
- *
- * @param buffer
- * will receive the values of the upper 4x3 submatrix in row-major order at its current position
- * @return the passed in buffer
- */
- FloatBuffer get4x3Transposed(FloatBuffer buffer);
-
- /**
- * Store the upper 4x3 submatrix of
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of the upper 4x3 submatrix in row-major order
- * @return the passed in buffer
- */
- FloatBuffer get4x3Transposed(int index, FloatBuffer buffer);
-
- /**
- * Store the upper 4x3 submatrix of
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the matrix is stored, use {@link #get4x3Transposed(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get4x3Transposed(int, ByteBuffer)
- *
- * @param buffer
- * will receive the values of the upper 4x3 submatrix in row-major order at its current position
- * @return the passed in buffer
- */
- ByteBuffer get4x3Transposed(ByteBuffer buffer);
-
- /**
- * Store the upper 4x3 submatrix of
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of the upper 4x3 submatrix in row-major order
- * @return the passed in buffer
- */
- ByteBuffer get4x3Transposed(int index, ByteBuffer buffer);
-
- /**
- * Store this matrix in column-major order at the given off-heap address.
- *
- * This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
- *
- * This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
- *
- * @param address
- * the off-heap address where to store this matrix
- * @return this
- */
- Matrix4fc getToAddress(long address);
-
- /**
- * Store this matrix into the supplied float array in column-major order at the given offset.
- *
- * @param arr
- * the array to write the matrix values into
- * @param offset
- * the offset into the array
- * @return the passed in array
- */
- float[] get(float[] arr, int offset);
-
- /**
- * Store this matrix into the supplied float array in column-major order.
- *
- * In order to specify an explicit offset into the array, use the method {@link #get(float[], int)}.
- *
- * @see #get(float[], int)
- *
- * @param arr
- * the array to write the matrix values into
- * @return the passed in array
- */
- float[] get(float[] arr);
-
- /**
- * Transform/multiply the given vector by this matrix and store the result in that vector.
- *
- * @see Vector4f#mul(Matrix4fc)
- *
- * @param v
- * the vector to transform and to hold the final result
- * @return v
- */
- Vector4f transform(Vector4f v);
-
- /**
- * Transform/multiply the given vector by this matrix and store the result in
- * This method uses
- * This method uses
- * This method uses
- * The given 3D-vector is treated as a 4D-vector with its w-component being 1.0, so it
- * will represent a position/location in 3D-space rather than a direction. This method is therefore
- * not suited for perspective projection transformations as it will not save the
- *
- * In order to store the result in another vector, use {@link #transformPosition(Vector3fc, Vector3f)}.
- *
- * @see #transformPosition(Vector3fc, Vector3f)
- * @see #transform(Vector4f)
- * @see #transformProject(Vector3f)
- *
- * @param v
- * the vector to transform and to hold the final result
- * @return v
- */
- Vector3f transformPosition(Vector3f v);
-
- /**
- * Transform/multiply the given 3D-vector, as if it was a 4D-vector with w=1, by
- * this matrix and store the result in
- * The given 3D-vector is treated as a 4D-vector with its w-component being 1.0, so it
- * will represent a position/location in 3D-space rather than a direction. This method is therefore
- * not suited for perspective projection transformations as it will not save the
- *
- * In order to store the result in the same vector, use {@link #transformPosition(Vector3f)}.
- *
- * @see #transformPosition(Vector3f)
- * @see #transform(Vector4fc, Vector4f)
- * @see #transformProject(Vector3fc, Vector3f)
- *
- * @param v
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformPosition(Vector3fc v, Vector3f dest);
-
- /**
- * Transform/multiply the 3D-vector
- * The given 3D-vector is treated as a 4D-vector with its w-component being 1.0, so it
- * will represent a position/location in 3D-space rather than a direction. This method is therefore
- * not suited for perspective projection transformations as it will not save the
- *
- * The given 3D-vector is treated as a 4D-vector with its w-component being
- * In order to store the result in another vector, use {@link #transformDirection(Vector3fc, Vector3f)}.
- *
- * @see #transformDirection(Vector3fc, Vector3f)
- *
- * @param v
- * the vector to transform and to hold the final result
- * @return v
- */
- Vector3f transformDirection(Vector3f v);
-
- /**
- * Transform/multiply the given 3D-vector, as if it was a 4D-vector with w=0, by
- * this matrix and store the result in
- * The given 3D-vector is treated as a 4D-vector with its w-component being
- * In order to store the result in the same vector, use {@link #transformDirection(Vector3f)}.
- *
- * @see #transformDirection(Vector3f)
- *
- * @param v
- * the vector to transform and to hold the final result
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformDirection(Vector3fc v, Vector3f dest);
-
- /**
- * Transform/multiply the given 3D-vector
- * The given 3D-vector is treated as a 4D-vector with its w-component being
- * In order to store the result in another vector, use {@link #transformAffine(Vector4fc, Vector4f)}.
- *
- * @see #transformAffine(Vector4fc, Vector4f)
- *
- * @param v
- * the vector to transform and to hold the final result
- * @return v
- */
- Vector4f transformAffine(Vector4f v);
-
- /**
- * Transform/multiply the given 4D-vector by assuming that
- * In order to store the result in the same vector, use {@link #transformAffine(Vector4f)}.
- *
- * @see #transformAffine(Vector4f)
- *
- * @param v
- * the vector to transform and to hold the final result
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformAffine(Vector4fc v, Vector4f dest);
-
- /**
- * Transform/multiply the 4D-vector
- * If
- * If
- * Individual scaling of all three axes can be applied using {@link #scale(float, float, float, Matrix4f)}.
- *
- * @see #scale(float, float, float, Matrix4f)
- *
- * @param xyz
- * the factor for all components
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f scale(float xyz, Matrix4f dest);
-
- /**
- * Apply scaling to this matrix by by scaling the X axis by
- * If
- * If
- * If
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * If
- * If
- * If
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateX(float ang, Matrix4f dest);
-
- /**
- * Apply rotation about the Y axis to this matrix by rotating the given amount of radians
- * and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateY(float ang, Matrix4f dest);
-
- /**
- * Apply rotation about the Z axis to this matrix by rotating the given amount of radians
- * and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateZ(float ang, Matrix4f dest);
-
- /**
- * Apply rotation about the Z axis to align the local
- * If
- * The vector
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method assumes that
- * If
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method assumes that
- * If
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * This method assumes that
- * If
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotate(float ang, float x, float y, float z, Matrix4f dest);
-
- /**
- * Apply rotation to this matrix, which is assumed to only contain a translation, by rotating the given amount of radians
- * about the specified
- * This method assumes
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateTranslation(float ang, float x, float y, float z, Matrix4f dest);
-
- /**
- * Apply rotation to this {@link #isAffine() affine} matrix by rotating the given amount of radians
- * about the specified
- * This method assumes
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateAffine(float ang, float x, float y, float z, Matrix4f dest);
-
- /**
- * Pre-multiply a rotation to this matrix by rotating the given amount of radians
- * about the specified
- * The axis described by the three components needs to be a unit vector.
- *
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians
- * @param x
- * the x component of the axis
- * @param y
- * the y component of the axis
- * @param z
- * the z component of the axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateLocal(float ang, float x, float y, float z, Matrix4f dest);
-
- /**
- * Pre-multiply a rotation around the X axis to this matrix by rotating the given amount of radians
- * about the X axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians to rotate about the X axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateLocalX(float ang, Matrix4f dest);
-
- /**
- * Pre-multiply a rotation around the Y axis to this matrix by rotating the given amount of radians
- * about the Y axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians to rotate about the Y axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateLocalY(float ang, Matrix4f dest);
-
- /**
- * Pre-multiply a rotation around the Z axis to this matrix by rotating the given amount of radians
- * about the Z axis and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param ang
- * the angle in radians to rotate about the Z axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateLocalZ(float ang, Matrix4f dest);
-
- /**
- * Apply a translation to this matrix by translating by the given number of
- * units in x, y and z and store the result in
- * If
- * If
- * If
- * If
- * If
- * If
- * Reference: http://www.songho.ca
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply an orthographic projection transformation for a left-handed coordiante system
- * using the given NDC z range to this matrix and store the result in
- * If
- * Reference: http://www.songho.ca
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * If
- * Reference: http://www.songho.ca
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f orthoLH(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply a symmetric orthographic projection transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in
- * This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, boolean, Matrix4f) ortho()} with
- *
- * If
- * Reference: http://www.songho.ca
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, Matrix4f) ortho()} with
- *
- * If
- * Reference: http://www.songho.ca
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f orthoSymmetric(float width, float height, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply a symmetric orthographic projection transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix and store the result in
- * This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, boolean, Matrix4f) orthoLH()} with
- *
- * If
- * Reference: http://www.songho.ca
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of
- * This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, Matrix4f) orthoLH()} with
- *
- * If
- * Reference: http://www.songho.ca
- *
- * @param width
- * the distance between the right and left frustum edges
- * @param height
- * the distance between the top and bottom frustum edges
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f orthoSymmetricLH(float width, float height, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply an orthographic projection transformation for a right-handed coordinate system to this matrix
- * and store the result in
- * This method is equivalent to calling {@link #ortho(float, float, float, float, float, float, Matrix4f) ortho()} with
- *
- * If
- * Reference: http://www.songho.ca
- *
- * @see #ortho(float, float, float, float, float, float, Matrix4f)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f ortho2D(float left, float right, float bottom, float top, Matrix4f dest);
-
- /**
- * Apply an orthographic projection transformation for a left-handed coordinate system to this matrix and store the result in
- * This method is equivalent to calling {@link #orthoLH(float, float, float, float, float, float, Matrix4f) orthoLH()} with
- *
- * If
- * Reference: http://www.songho.ca
- *
- * @see #orthoLH(float, float, float, float, float, float, Matrix4f)
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f ortho2DLH(float left, float right, float bottom, float top, Matrix4f dest);
-
- /**
- * Apply a rotation transformation to this matrix to make
- * If
- * This is equivalent to calling
- * {@link #lookAt(Vector3fc, Vector3fc, Vector3fc, Matrix4f) lookAt}
- * with
- * If
- * This is equivalent to calling
- * {@link #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f) lookAt()}
- * with
- * If
- * If
- * This method assumes
- * If
- * If
- * If
- * This method assumes
- * If
- * If
- * If
- * If
- * If
- * If
- * The given angles
- * If
- * The given angles
- * If
- * The given angles
- * If
- * The given angles
- * If
- * The given angles
- * If
- * The given angles
- * If
- * If
- * If
- * If
- * Reference: http://www.songho.ca
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * Reference: http://www.songho.ca
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * Reference: http://www.songho.ca
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * If
- * Reference: http://www.songho.ca
- *
- * @param left
- * the distance along the x-axis to the left frustum edge
- * @param right
- * the distance along the x-axis to the right frustum edge
- * @param bottom
- * the distance along the y-axis to the bottom frustum edge
- * @param top
- * the distance along the y-axis to the top frustum edge
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case,
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotate(Quaternionfc quat, Matrix4f dest);
-
- /**
- * Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this {@link #isAffine() affine} matrix and store
- * the result in
- * This method assumes
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateAffine(Quaternionfc quat, Matrix4f dest);
-
- /**
- * Apply the rotation - and possibly scaling - ransformation of the given {@link Quaternionfc} to this matrix, which is assumed to only contain a translation, and store
- * the result in
- * This method assumes
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateTranslation(Quaternionfc quat, Matrix4f dest);
-
- /**
- * Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this {@link #isAffine() affine}
- * matrix while using
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is only applicable if
- * This method is equivalent to calling:
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param ox
- * the x coordinate of the rotation origin
- * @param oy
- * the y coordinate of the rotation origin
- * @param oz
- * the z coordinate of the rotation origin
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateAroundAffine(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest);
-
- /**
- * Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix while using
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param ox
- * the x coordinate of the rotation origin
- * @param oy
- * the y coordinate of the rotation origin
- * @param oz
- * the z coordinate of the rotation origin
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateAround(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest);
-
- /**
- * Pre-multiply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix and store
- * the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateLocal(Quaternionfc quat, Matrix4f dest);
-
- /**
- * Pre-multiply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix while using
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * This method is equivalent to calling:
- * Reference: http://en.wikipedia.org
- *
- * @param quat
- * the {@link Quaternionfc}
- * @param ox
- * the x coordinate of the rotation origin
- * @param oy
- * the y coordinate of the rotation origin
- * @param oz
- * the z coordinate of the rotation origin
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateAroundLocal(Quaternionfc quat, float ox, float oy, float oz, Matrix4f dest);
-
- /**
- * Apply a rotation transformation, rotating about the given {@link AxisAngle4f} and store the result in
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float, Matrix4f)
- *
- * @param axisAngle
- * the {@link AxisAngle4f} (needs to be {@link AxisAngle4f#normalize() normalized})
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotate(AxisAngle4f axisAngle, Matrix4f dest);
-
- /**
- * Apply a rotation transformation, rotating the given radians about the specified axis and store the result in
- * The axis described by the
- * When used with a right-handed coordinate system, the produced rotation will rotate a vector
- * counter-clockwise around the rotation axis, when viewing along the negative axis direction towards the origin.
- * When used with a left-handed coordinate system, the rotation is clockwise.
- *
- * If
- * Reference: http://en.wikipedia.org
- *
- * @see #rotate(float, float, float, float, Matrix4f)
- *
- * @param angle
- * the angle in radians
- * @param axis
- * the rotation axis (needs to be {@link Vector3fc#normalize(Vector3f) normalized})
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotate(float angle, Vector3fc axis, Matrix4f dest);
-
- /**
- * Unproject the given window coordinates
- * This method first converts the given window coordinates to normalized device coordinates in the range
- * The depth range of
- * As a necessary computation step for unprojecting, this method computes the inverse of
- * This method first converts the given window coordinates to normalized device coordinates in the range
- * The depth range of
- * As a necessary computation step for unprojecting, this method computes the inverse of
- * This method first converts the given window coordinates to normalized device coordinates in the range
- * The depth range of
- * As a necessary computation step for unprojecting, this method computes the inverse of
- * This method first converts the given window coordinates to normalized device coordinates in the range
- * The depth range of
- * As a necessary computation step for unprojecting, this method computes the inverse of
- * This method first converts the given window coordinates to normalized device coordinates in the range
- * As a necessary computation step for unprojecting, this method computes the inverse of
- * This method differs from {@link #unproject(Vector3fc, int[], Vector4f) unproject()}
- * in that it assumes that
- * The depth range of
- * This method reads the four viewport parameters from the given int[].
- *
- * @see #unproject(Vector3fc, int[], Vector4f)
- *
- * @param winCoords
- * the window coordinates to unproject
- * @param viewport
- * the viewport described by
- * This method differs from {@link #unproject(float, float, float, int[], Vector4f) unproject()}
- * in that it assumes that
- * The depth range of
- * This method differs from {@link #unprojectRay(float, float, int[], Vector3f, Vector3f) unprojectRay()}
- * in that it assumes that
- * This method differs from {@link #unproject(Vector3fc, int[], Vector3f) unproject()}
- * in that it assumes that
- * The depth range of
- * This method differs from {@link #unproject(float, float, float, int[], Vector3f) unproject()}
- * in that it assumes that
- * The depth range of
- * This method transforms the given coordinates by
- * The depth range of the returned
- * This method transforms the given coordinates by
- * The depth range of the returned
- * This method transforms the given coordinates by
- * The depth range of the returned
- * This method transforms the given coordinates by
- * The depth range of the returned
- * The vector
- * If
- * Reference: msdn.microsoft.com
- *
- * @param a
- * the x factor in the plane equation
- * @param b
- * the y factor in the plane equation
- * @param c
- * the z factor in the plane equation
- * @param d
- * the constant in the plane equation
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f reflect(float a, float b, float c, float d, Matrix4f dest);
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects about the given plane
- * specified via the plane normal and a point on the plane, and store the result in
- * If
- * This method can be used to build a reflection transformation based on the orientation of a mirror object in the scene.
- * It is assumed that the default mirror plane's normal is
- * If
- * If
- * The normal matrix of
- * The normal matrix of
- * The cofactor matrix can be used instead of {@link #normal(Matrix3f)} to transform normals
- * when the orientation of the normals with respect to the surface should be preserved.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f cofactor3x3(Matrix3f dest);
-
- /**
- * Compute the cofactor matrix of the upper left 3x3 submatrix of
- * The cofactor matrix can be used instead of {@link #normal(Matrix4f)} to transform normals
- * when the orientation of the normals with respect to the surface should be preserved.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f cofactor3x3(Matrix4f dest);
-
- /**
- * Normalize the upper left 3x3 submatrix of this matrix and store the result in
- * The resulting matrix will map unit vectors to unit vectors, though a pair of orthogonal input unit
- * vectors need not be mapped to a pair of orthogonal output vectors if the original matrix was not orthogonal itself
- * (i.e. had skewing).
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f normalize3x3(Matrix4f dest);
-
- /**
- * Normalize the upper left 3x3 submatrix of this matrix and store the result in
- * The resulting matrix will map unit vectors to unit vectors, though a pair of orthogonal input unit
- * vectors need not be mapped to a pair of orthogonal output vectors if the original matrix was not orthogonal itself
- * (i.e. had skewing).
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f normalize3x3(Matrix3f dest);
-
- /**
- * Calculate a frustum plane of
- * Generally, this method computes the frustum plane in the local frame of
- * any coordinate system that existed before
- * The frustum plane will be given in the form of a general plane equation:
- *
- * The plane normal, which is
- * For performing frustum culling, the class {@link FrustumIntersection} should be used instead of
- * manually obtaining the frustum planes and testing them against points, spheres or axis-aligned boxes.
- *
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @param plane
- * one of the six possible planes, given as numeric constants
- * {@link #PLANE_NX}, {@link #PLANE_PX},
- * {@link #PLANE_NY}, {@link #PLANE_PY},
- * {@link #PLANE_NZ} and {@link #PLANE_PZ}
- * @param planeEquation
- * will hold the computed plane equation.
- * The plane equation will be normalized, meaning that
- * Generally, this method computes the frustum corners in the local frame of
- * any coordinate system that existed before
- * Reference: http://geomalgorithms.com
- *
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @param corner
- * one of the eight possible corners, given as numeric constants
- * {@link #CORNER_NXNYNZ}, {@link #CORNER_PXNYNZ}, {@link #CORNER_PXPYNZ}, {@link #CORNER_NXPYNZ},
- * {@link #CORNER_PXNYPZ}, {@link #CORNER_NXNYPZ}, {@link #CORNER_NXPYPZ}, {@link #CORNER_PXPYPZ}
- * @param point
- * will hold the resulting corner point coordinates
- * @return point
- */
- Vector3f frustumCorner(int corner, Vector3f point);
-
- /**
- * Compute the eye/origin of the perspective frustum transformation defined by
- * Note that this method will only work using perspective projections obtained via one of the
- * perspective methods, such as {@link #perspective(float, float, float, float, Matrix4f) perspective()}
- * or {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()}.
- *
- * Generally, this method computes the origin in the local frame of
- * any coordinate system that existed before
- * This method is equivalent to calling:
- * Reference: http://geomalgorithms.com
- *
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @param origin
- * will hold the origin of the coordinate system before applying
- * Note that this method will only work using perspective projections obtained via one of the
- * perspective methods, such as {@link #perspective(float, float, float, float, Matrix4f) perspective()}
- * or {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()}.
- *
- * If the inverse of the modelview-projection matrix is not available, then calling {@link #perspectiveOrigin(Vector3f)}
- * on the original modelview-projection matrix is preferred.
- *
- * @see #perspectiveOrigin(Vector3f)
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f perspectiveInvOrigin(Vector3f dest);
-
- /**
- * Return the vertical field-of-view angle in radians of this perspective transformation matrix.
- *
- * Note that this method will only work using perspective projections obtained via one of the
- * perspective methods, such as {@link #perspective(float, float, float, float, Matrix4f) perspective()}
- * or {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()}.
- *
- * For orthogonal transformations this method will return
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @return the vertical field-of-view angle in radians
- */
- float perspectiveFov();
-
- /**
- * Extract the near clip plane distance from
- * This method only works if
- * This method only works if
- * This method computes the
- * The parameters
- * For optimal efficiency when building many ray directions over the whole frustum,
- * it is recommended to use this method only in order to compute the four corner rays at
- *
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @param x
- * the interpolation factor along the left-to-right frustum planes, within
- * This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
- * that is transformed to
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
- * that is transformed to
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
- * that is transformed to
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
- * that is transformed to
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
- * that is transformed to
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method uses the rotation component of the upper left 3x3 submatrix to obtain the direction
- * that is transformed to
- * This method is equivalent to the following code:
- *
- * Reference: http://www.euclideanspace.com
- *
- * @param dir
- * will hold the direction of
- * This method only works with {@link #isAffine() affine} matrices.
- *
- * This method is equivalent to the following code:
- *
- * This method is equivalent to the following code:
- *
- * If
- * If
- * Reference: ftp.sgi.com
- *
- * @param light
- * the light's vector
- * @param a
- * the x factor in the plane equation
- * @param b
- * the y factor in the plane equation
- * @param c
- * the z factor in the plane equation
- * @param d
- * the constant in the plane equation
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f shadow(Vector4f light, float a, float b, float c, float d, Matrix4f dest);
-
- /**
- * Apply a projection transformation to this matrix that projects onto the plane specified via the general plane equation
- *
- * If
- * If
- * Reference: ftp.sgi.com
- *
- * @param lightX
- * the x-component of the light's vector
- * @param lightY
- * the y-component of the light's vector
- * @param lightZ
- * the z-component of the light's vector
- * @param lightW
- * the w-component of the light's vector
- * @param a
- * the x factor in the plane equation
- * @param b
- * the y factor in the plane equation
- * @param c
- * the z factor in the plane equation
- * @param d
- * the constant in the plane equation
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f shadow(float lightX, float lightY, float lightZ, float lightW, float a, float b, float c, float d, Matrix4f dest);
-
- /**
- * Apply a projection transformation to this matrix that projects onto the plane with the general plane equation
- *
- * Before the shadow projection is applied, the plane is transformed via the specified
- * If
- * If
- * Before the shadow projection is applied, the plane is transformed via the specified
- * If
- * If
- * This method is equivalent to calling:
- * This method is equivalent to calling:
- * The matrix
- * The axis-aligned bounding box of the unit frustum is
- * If the projected grid will not be visible then this method returns
- * This method uses the
- * This method only works if
- * The transformation represented by
- * The
- * Reference: OpenGL SDK - Cascaded Shadow Maps
- *
- * @param view
- * the view transformation to build a corresponding orthographic projection to fit the frustum of
- * Reference: http://dev.theomader.com
- *
- * @param minX
- * the x coordinate of the minimum corner of the axis-aligned box
- * @param minY
- * the y coordinate of the minimum corner of the axis-aligned box
- * @param minZ
- * the z coordinate of the minimum corner of the axis-aligned box
- * @param maxX
- * the x coordinate of the maximum corner of the axis-aligned box
- * @param maxY
- * the y coordinate of the maximum corner of the axis-aligned box
- * @param maxZ
- * the y coordinate of the maximum corner of the axis-aligned box
- * @param outMin
- * will hold the minimum corner of the resulting axis-aligned box
- * @param outMax
- * will hold the maximum corner of the resulting axis-aligned box
- * @return this
- */
- Matrix4f transformAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, Vector3f outMin, Vector3f outMax);
-
- /**
- * Transform the axis-aligned box given as the minimum corner
- * If
- * If
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * This method assumes that the upper left of
- * The Euler angles are always returned as the angle around X in the {@link Vector3f#x} field, the angle around Y in the {@link Vector3f#y}
- * field and the angle around Z in the {@link Vector3f#z} field of the supplied {@link Vector3f} instance.
- *
- * Note that the returned Euler angles must be applied in the order
- * Reference: http://en.wikipedia.org/
- *
- * @param dest
- * will hold the extracted Euler angles
- * @return dest
- */
- Vector3f getEulerAnglesXYZ(Vector3f dest);
-
- /**
- * Extract the Euler angles from the rotation represented by the upper left 3x3 submatrix of
- * This method assumes that the upper left of
- * The Euler angles are always returned as the angle around X in the {@link Vector3f#x} field, the angle around Y in the {@link Vector3f#y}
- * field and the angle around Z in the {@link Vector3f#z} field of the supplied {@link Vector3f} instance.
- *
- * Note that the returned Euler angles must be applied in the order
- * Reference: http://nghiaho.com/
- *
- * @param dest
- * will hold the extracted Euler angles
- * @return dest
- */
- Vector3f getEulerAnglesZYX(Vector3f dest);
-
- /**
- * Test whether the given point
- * This method assumes
- * When testing multiple points using the same transformation matrix, {@link FrustumIntersection} should be used instead.
- *
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @param x
- * the x-coordinate of the point
- * @param y
- * the y-coordinate of the point
- * @param z
- * the z-coordinate of the point
- * @return
- * This method assumes
- * When testing multiple spheres using the same transformation matrix, or more sophisticated/optimized intersection algorithms are required,
- * {@link FrustumIntersection} should be used instead.
- *
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @param x
- * the x-coordinate of the sphere's center
- * @param y
- * the y-coordinate of the sphere's center
- * @param z
- * the z-coordinate of the sphere's center
- * @param r
- * the sphere's radius
- * @return
- * This method assumes
- * When testing multiple axis-aligned boxes using the same transformation matrix, or more sophisticated/optimized intersection algorithms are required,
- * {@link FrustumIntersection} should be used instead.
- *
- * The algorithm implemented by this method is conservative. This means that in certain circumstances a false positive
- * can occur, when the method returns
- * Reference: Efficient View Frustum Culling
- *
- * If
- * The oblique transformation is defined as:
- *
- * This effectively ensures that the resulting matrix will be equal to the one obtained from calling
- * {@link Matrix4f#setLookAt(Vector3fc, Vector3fc, Vector3fc)} with the current
- * local origin of this matrix (as obtained by {@link #originAffine(Vector3f)}), the sum of this position and the
- * negated local Z axis as well as the given vector
- * This method must only be called on {@link #isAffine()} matrices.
- *
- * @param up
- * the up vector
- * @param dest
- * will hold the result
- * @return this
- */
- Matrix4f withLookAtUp(Vector3fc up, Matrix4f dest);
-
- /**
- * Apply a transformation to this matrix to ensure that the local Y axis (as obtained by {@link #positiveY(Vector3f)})
- * will be coplanar to the plane spanned by the local Z axis (as obtained by {@link #positiveZ(Vector3f)}) and the
- * given vector
- * This effectively ensures that the resulting matrix will be equal to the one obtained from calling
- * {@link Matrix4f#setLookAt(float, float, float, float, float, float, float, float, float)} called with the current
- * local origin of this matrix (as obtained by {@link #originAffine(Vector3f)}), the sum of this position and the
- * negated local Z axis as well as the given vector
- * This method must only be called on {@link #isAffine()} matrices.
- *
- * @param upX
- * the x coordinate of the up vector
- * @param upY
- * the y coordinate of the up vector
- * @param upZ
- * the z coordinate of the up vector
- * @param dest
- * will hold the result
- * @return this
- */
- Matrix4f withLookAtUp(float upX, float upY, float upZ, Matrix4f dest);
-
- /**
- * Multiply
- * Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
- * and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
- * data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
- *
- * @param m
- * the other matrix
- * @param delta
- * the allowed maximum difference
- * @return
- * This method assumes that the given rotation axis
- * This method assumes that the given rotation axis
- * This method assumes that the first three columns of the upper left 3x3 submatrix are no unit vectors.
- *
- * @param mat
- * the matrix whose rotational component is used to set this quaternion
- * @return this
- */
- public Quaternionf setFromUnnormalized(Matrix4fc mat) {
- setFromUnnormalized(mat.m00(), mat.m01(), mat.m02(), mat.m10(), mat.m11(), mat.m12(), mat.m20(), mat.m21(), mat.m22());
- return this;
- }
-
- /**
- * Set this quaternion to be a representation of the rotational component of the given matrix.
- *
- * This method assumes that the first three columns of the upper left 3x3 submatrix are unit vectors.
- *
- * @param mat
- * the matrix whose rotational component is used to set this quaternion
- * @return this
- */
- public Quaternionf setFromNormalized(Matrix4fc mat) {
- setFromNormalized(mat.m00(), mat.m01(), mat.m02(), mat.m10(), mat.m11(), mat.m12(), mat.m20(), mat.m21(), mat.m22());
- return this;
- }
-
- /**
- * Set this quaternion to be a representation of the rotational component of the given matrix.
- *
- * This method assumes that the first three columns of the upper left 3x3 submatrix are no unit vectors.
- *
- * @param mat
- * the matrix whose rotational component is used to set this quaternion
- * @return this
- */
- public Quaternionf setFromUnnormalized(Matrix3fc mat) {
- setFromUnnormalized(mat.m00(), mat.m01(), mat.m02(), mat.m10(), mat.m11(), mat.m12(), mat.m20(), mat.m21(), mat.m22());
- return this;
- }
-
- /**
- * Set this quaternion to be a representation of the rotational component of the given matrix.
- *
- * This method assumes that the first three columns of the upper left 3x3 submatrix are unit vectors.
- *
- * @param mat
- * the matrix whose rotational component is used to set this quaternion
- * @return this
- */
- public Quaternionf setFromNormalized(Matrix3fc mat) {
- setFromNormalized(mat.m00(), mat.m01(), mat.m02(), mat.m10(), mat.m11(), mat.m12(), mat.m20(), mat.m21(), mat.m22());
- return this;
- }
-
- /**
- * Set this quaternion to be a representation of the supplied axis and
- * angle (in radians).
- *
- * @param axis
- * the rotation axis
- * @param angle
- * the angle in radians
- * @return this
- */
- public Quaternionf fromAxisAngleRad(Vector3fc axis, float angle) {
- return fromAxisAngleRad(axis.x(), axis.y(), axis.z(), angle);
- }
-
- /**
- * Set this quaternion to be a representation of the supplied axis and
- * angle (in radians).
- *
- * @param axisX
- * the x component of the rotation axis
- * @param axisY
- * the y component of the rotation axis
- * @param axisZ
- * the z component of the rotation axis
- * @param angle
- * the angle in radians
- * @return this
- */
- public Quaternionf fromAxisAngleRad(float axisX, float axisY, float axisZ, float angle) {
- float hangle = angle / 2.0f;
- float sinAngle = Math.sin(hangle);
- float vLength = Math.sqrt(axisX * axisX + axisY * axisY + axisZ * axisZ);
- x = axisX / vLength * sinAngle;
- y = axisY / vLength * sinAngle;
- z = axisZ / vLength * sinAngle;
- w = Math.cosFromSin(sinAngle, hangle);
- return this;
- }
-
- /**
- * Set this quaternion to be a representation of the supplied axis and
- * angle (in degrees).
- *
- * @param axis
- * the rotation axis
- * @param angle
- * the angle in degrees
- * @return this
- */
- public Quaternionf fromAxisAngleDeg(Vector3fc axis, float angle) {
- return fromAxisAngleRad(axis.x(), axis.y(), axis.z(), Math.toRadians(angle));
- }
-
- /**
- * Set this quaternion to be a representation of the supplied axis and
- * angle (in degrees).
- *
- * @param axisX
- * the x component of the rotation axis
- * @param axisY
- * the y component of the rotation axis
- * @param axisZ
- * the z component of the rotation axis
- * @param angle
- * the angle in radians
- * @return this
- */
- public Quaternionf fromAxisAngleDeg(float axisX, float axisY, float axisZ, float angle) {
- return fromAxisAngleRad(axisX, axisY, axisZ, Math.toRadians(angle));
- }
-
- /**
- * Multiply this quaternion by
- * If
- *
- * So, this method uses post-multiplication like the matrix classes, resulting in a
- * vector to be transformed by
- * If
- *
- * So, this method uses post-multiplication like the matrix classes, resulting in a
- * vector to be transformed by
- * If
- *
- * So, this method uses pre-multiplication, resulting in a vector to be transformed by
- * If
- *
- * So, this method uses pre-multiplication, resulting in a vector to be transformed by
- * If this quaternion is already normalized, then {@link #conjugate()} should be used instead.
- *
- * @see #conjugate()
- *
- * @return this
- */
- public Quaternionf invert() {
- return invert(this);
- }
-
- public Quaternionf div(Quaternionfc b, Quaternionf dest) {
- float invNorm = 1.0f / Math.fma(b.x(), b.x(), Math.fma(b.y(), b.y(), Math.fma(b.z(), b.z(), b.w() * b.w())));
- float x = -b.x() * invNorm;
- float y = -b.y() * invNorm;
- float z = -b.z() * invNorm;
- float w = b.w() * invNorm;
- return dest.set(Math.fma(this.w, x, Math.fma(this.x, w, Math.fma(this.y, z, -this.z * y))),
- Math.fma(this.w, y, Math.fma(-this.x, z, Math.fma(this.y, w, this.z * x))),
- Math.fma(this.w, z, Math.fma(this.x, y, Math.fma(-this.y, x, this.z * w))),
- Math.fma(this.w, w, Math.fma(-this.x, x, Math.fma(-this.y, y, -this.z * z))));
- }
-
- /**
- * Divide
- * The division expressed using the inverse is performed in the following way:
- *
- *
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * Reference: this stackexchange answer
- *
- * @param angleX
- * the angle in radians to rotate about x
- * @param angleY
- * the angle in radians to rotate about y
- * @param angleZ
- * the angle in radians to rotate about z
- * @return this
- */
- public Quaternionf rotationXYZ(float angleX, float angleY, float angleZ) {
- float sx = Math.sin(angleX * 0.5f);
- float cx = Math.cosFromSin(sx, angleX * 0.5f);
- float sy = Math.sin(angleY * 0.5f);
- float cy = Math.cosFromSin(sy, angleY * 0.5f);
- float sz = Math.sin(angleZ * 0.5f);
- float cz = Math.cosFromSin(sz, angleZ * 0.5f);
-
- float cycz = cy * cz;
- float sysz = sy * sz;
- float sycz = sy * cz;
- float cysz = cy * sz;
- w = cx*cycz - sx*sysz;
- x = sx*cycz + cx*sysz;
- y = cx*sycz - sx*cysz;
- z = cx*cysz + sx*sycz;
-
- return this;
- }
-
- /**
- * Set this quaternion from the supplied euler angles (in radians) with rotation order ZYX.
- *
- * This method is equivalent to calling:
- * Reference: this stackexchange answer
- *
- * @param angleX
- * the angle in radians to rotate about x
- * @param angleY
- * the angle in radians to rotate about y
- * @param angleZ
- * the angle in radians to rotate about z
- * @return this
- */
- public Quaternionf rotationZYX(float angleZ, float angleY, float angleX) {
- float sx = Math.sin(angleX * 0.5f);
- float cx = Math.cosFromSin(sx, angleX * 0.5f);
- float sy = Math.sin(angleY * 0.5f);
- float cy = Math.cosFromSin(sy, angleY * 0.5f);
- float sz = Math.sin(angleZ * 0.5f);
- float cz = Math.cosFromSin(sz, angleZ * 0.5f);
-
- float cycz = cy * cz;
- float sysz = sy * sz;
- float sycz = sy * cz;
- float cysz = cy * sz;
- w = cx*cycz + sx*sysz;
- x = sx*cycz - cx*sysz;
- y = cx*sycz + sx*cysz;
- z = cx*cysz - sx*sycz;
-
- return this;
- }
-
- /**
- * Set this quaternion from the supplied euler angles (in radians) with rotation order YXZ.
- *
- * This method is equivalent to calling:
- * Reference: https://en.wikipedia.org
- *
- * @param angleY
- * the angle in radians to rotate about y
- * @param angleX
- * the angle in radians to rotate about x
- * @param angleZ
- * the angle in radians to rotate about z
- * @return this
- */
- public Quaternionf rotationYXZ(float angleY, float angleX, float angleZ) {
- float sx = Math.sin(angleX * 0.5f);
- float cx = Math.cosFromSin(sx, angleX * 0.5f);
- float sy = Math.sin(angleY * 0.5f);
- float cy = Math.cosFromSin(sy, angleY * 0.5f);
- float sz = Math.sin(angleZ * 0.5f);
- float cz = Math.cosFromSin(sz, angleZ * 0.5f);
-
- float x = cy * sx;
- float y = sy * cx;
- float z = sy * sx;
- float w = cy * cx;
- this.x = x * cz + y * sz;
- this.y = y * cz - x * sz;
- this.z = w * sz - z * cz;
- this.w = w * cz + z * sz;
-
- return this;
- }
-
- /**
- * Interpolate between
- * This method resorts to non-spherical linear interpolation when the absolute dot product of
- * This method will interpolate between each two successive quaternions via {@link #slerp(Quaternionfc, float)} using their relative interpolation weights.
- *
- * This method resorts to non-spherical linear interpolation when the absolute dot product of any two interpolated quaternions is below
- * Reference: http://gamedev.stackexchange.com/
- *
- * @param qs
- * the quaternions to interpolate over
- * @param weights
- * the weights of each individual quaternion in
- * This method pre-multiplies the rotation given by
- * This method is equivalent to calling:
- * Reference: http://physicsforgames.blogspot.de/
- *
- * @param dt
- * the delta time
- * @param vx
- * the angular velocity around the x axis
- * @param vy
- * the angular velocity around the y axis
- * @param vz
- * the angular velocity around the z axis
- * @return this
- */
- public Quaternionf integrate(float dt, float vx, float vy, float vz) {
- return integrate(dt, vx, vy, vz, this);
- }
-
- public Quaternionf integrate(float dt, float vx, float vy, float vz, Quaternionf dest) {
- float thetaX = dt * vx * 0.5f;
- float thetaY = dt * vy * 0.5f;
- float thetaZ = dt * vz * 0.5f;
- float thetaMagSq = thetaX * thetaX + thetaY * thetaY + thetaZ * thetaZ;
- float s;
- float dqX, dqY, dqZ, dqW;
- if (thetaMagSq * thetaMagSq / 24.0f < 1E-8f) {
- dqW = 1.0f - thetaMagSq * 0.5f;
- s = 1.0f - thetaMagSq / 6.0f;
- } else {
- float thetaMag = Math.sqrt(thetaMagSq);
- float sin = Math.sin(thetaMag);
- s = sin / thetaMag;
- dqW = Math.cosFromSin(sin, thetaMag);
- }
- dqX = thetaX * s;
- dqY = thetaY * s;
- dqZ = thetaZ * s;
- /* Pre-multiplication */
- return dest.set(Math.fma(dqW, x, Math.fma(dqX, w, Math.fma(dqY, z, -dqZ * y))),
- Math.fma(dqW, y, Math.fma(-dqX, z, Math.fma(dqY, w, dqZ * x))),
- Math.fma(dqW, z, Math.fma(dqX, y, Math.fma(-dqY, x, dqZ * w))),
- Math.fma(dqW, w, Math.fma(-dqX, x, Math.fma(-dqY, y, -dqZ * z))));
- }
-
- /**
- * Compute a linear (non-spherical) interpolation of
- * This method will interpolate between each two successive quaternions via {@link #nlerp(Quaternionfc, float)}
- * using their relative interpolation weights.
- *
- * Reference: http://gamedev.stackexchange.com/
- *
- * @param qs
- * the quaternions to interpolate over
- * @param weights
- * the weights of each individual quaternion in
- * This method performs a series of small-step nlerp interpolations to avoid doing a costly spherical linear interpolation, like
- * {@link #slerp(Quaternionfc, float, Quaternionf) slerp},
- * by subdividing the rotation arc between
- * Thanks to
- * This method will interpolate between each two successive quaternions via {@link #nlerpIterative(Quaternionfc, float, float)}
- * using their relative interpolation weights.
- *
- * Reference: http://gamedev.stackexchange.com/
- *
- * @param qs
- * the quaternions to interpolate over
- * @param weights
- * the weights of each individual quaternion in
- * Because there are multiple possibilities for such a rotation, this method will choose the one that ensures the given up direction to remain
- * parallel to the plane spanned by the
- * If
- * Reference: http://answers.unity3d.com
- *
- * @see #lookAlong(float, float, float, float, float, float, Quaternionf)
- *
- * @param dir
- * the direction to map to the positive Z axis
- * @param up
- * the vector which will be mapped to a vector parallel to the plane
- * spanned by the given
- * Because there are multiple possibilities for such a rotation, this method will choose the one that ensures the given up direction to remain
- * parallel to the plane spanned by the
- * If
- * Reference: http://answers.unity3d.com
- *
- * @see #lookAlong(float, float, float, float, float, float, Quaternionf)
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Quaternionf lookAlong(float dirX, float dirY, float dirZ, float upX, float upY, float upZ) {
- return lookAlong(dirX, dirY, dirZ, upX, upY, upZ, this);
- }
-
- public Quaternionf lookAlong(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Quaternionf dest) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- float dirnX = -dirX * invDirLength;
- float dirnY = -dirY * invDirLength;
- float dirnZ = -dirZ * invDirLength;
- // left = up x dir
- float leftX, leftY, leftZ;
- leftX = upY * dirnZ - upZ * dirnY;
- leftY = upZ * dirnX - upX * dirnZ;
- leftZ = upX * dirnY - upY * dirnX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = dirnY * leftZ - dirnZ * leftY;
- float upnY = dirnZ * leftX - dirnX * leftZ;
- float upnZ = dirnX * leftY - dirnY * leftX;
-
- /* Convert orthonormal basis vectors to quaternion */
- float x, y, z, w;
- double t;
- double tr = leftX + upnY + dirnZ;
- if (tr >= 0.0) {
- t = Math.sqrt(tr + 1.0);
- w = (float) (t * 0.5);
- t = 0.5 / t;
- x = (float) ((dirnY - upnZ) * t);
- y = (float) ((leftZ - dirnX) * t);
- z = (float) ((upnX - leftY) * t);
- } else {
- if (leftX > upnY && leftX > dirnZ) {
- t = Math.sqrt(1.0 + leftX - upnY - dirnZ);
- x = (float) (t * 0.5);
- t = 0.5 / t;
- y = (float) ((leftY + upnX) * t);
- z = (float) ((dirnX + leftZ) * t);
- w = (float) ((dirnY - upnZ) * t);
- } else if (upnY > dirnZ) {
- t = Math.sqrt(1.0 + upnY - leftX - dirnZ);
- y = (float) (t * 0.5);
- t = 0.5 / t;
- x = (float) ((leftY + upnX) * t);
- z = (float) ((upnZ + dirnY) * t);
- w = (float) ((leftZ - dirnX) * t);
- } else {
- t = Math.sqrt(1.0 + dirnZ - leftX - upnY);
- z = (float) (t * 0.5);
- t = 0.5 / t;
- x = (float) ((dirnX + leftZ) * t);
- y = (float) ((upnZ + dirnY) * t);
- w = (float) ((upnX - leftY) * t);
- }
- }
- /* Multiply */
- return dest.set(Math.fma(this.w, x, Math.fma(this.x, w, Math.fma(this.y, z, -this.z * y))),
- Math.fma(this.w, y, Math.fma(-this.x, z, Math.fma(this.y, w, this.z * x))),
- Math.fma(this.w, z, Math.fma(this.x, y, Math.fma(-this.y, x, this.z * w))),
- Math.fma(this.w, w, Math.fma(-this.x, x, Math.fma(-this.y, y, -this.z * z))));
- }
-
- /**
- * Set
- * Since there can be multiple possible rotations, this method chooses the one with the shortest arc.
- *
- * Reference: stackoverflow.com
- *
- * @param fromDirX
- * the x-coordinate of the direction to rotate into the destination direction
- * @param fromDirY
- * the y-coordinate of the direction to rotate into the destination direction
- * @param fromDirZ
- * the z-coordinate of the direction to rotate into the destination direction
- * @param toDirX
- * the x-coordinate of the direction to rotate to
- * @param toDirY
- * the y-coordinate of the direction to rotate to
- * @param toDirZ
- * the z-coordinate of the direction to rotate to
- * @return this
- */
- public Quaternionf rotationTo(float fromDirX, float fromDirY, float fromDirZ, float toDirX, float toDirY, float toDirZ) {
- float fn = Math.invsqrt(Math.fma(fromDirX, fromDirX, Math.fma(fromDirY, fromDirY, fromDirZ * fromDirZ)));
- float tn = Math.invsqrt(Math.fma(toDirX, toDirX, Math.fma(toDirY, toDirY, toDirZ * toDirZ)));
- float fx = fromDirX * fn, fy = fromDirY * fn, fz = fromDirZ * fn;
- float tx = toDirX * tn, ty = toDirY * tn, tz = toDirZ * tn;
- float dot = fx * tx + fy * ty + fz * tz;
- float x, y, z, w;
- if (dot < -1.0f + 1E-6f) {
- x = fy;
- y = -fx;
- z = 0.0f;
- w = 0.0f;
- if (x * x + y * y == 0.0f) {
- x = 0.0f;
- y = fz;
- z = -fy;
- w = 0.0f;
- }
- this.x = x;
- this.y = y;
- this.z = z;
- this.w = 0;
- } else {
- float sd2 = Math.sqrt((1.0f + dot) * 2.0f);
- float isd2 = 1.0f / sd2;
- float cx = fy * tz - fz * ty;
- float cy = fz * tx - fx * tz;
- float cz = fx * ty - fy * tx;
- x = cx * isd2;
- y = cy * isd2;
- z = cz * isd2;
- w = sd2 * 0.5f;
- float n2 = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w))));
- this.x = x * n2;
- this.y = y * n2;
- this.z = z * n2;
- this.w = w * n2;
- }
- return this;
- }
-
- /**
- * Set
- * Because there can be multiple possible rotations, this method chooses the one with the shortest arc.
- *
- * @see #rotationTo(float, float, float, float, float, float)
- *
- * @param fromDir
- * the starting direction
- * @param toDir
- * the destination direction
- * @return this
- */
- public Quaternionf rotationTo(Vector3fc fromDir, Vector3fc toDir) {
- return rotationTo(fromDir.x(), fromDir.y(), fromDir.z(), toDir.x(), toDir.y(), toDir.z());
- }
-
- public Quaternionf rotateTo(float fromDirX, float fromDirY, float fromDirZ, float toDirX, float toDirY, float toDirZ, Quaternionf dest) {
- float fn = Math.invsqrt(Math.fma(fromDirX, fromDirX, Math.fma(fromDirY, fromDirY, fromDirZ * fromDirZ)));
- float tn = Math.invsqrt(Math.fma(toDirX, toDirX, Math.fma(toDirY, toDirY, toDirZ * toDirZ)));
- float fx = fromDirX * fn, fy = fromDirY * fn, fz = fromDirZ * fn;
- float tx = toDirX * tn, ty = toDirY * tn, tz = toDirZ * tn;
- float dot = fx * tx + fy * ty + fz * tz;
- float x, y, z, w;
- if (dot < -1.0f + 1E-6f) {
- x = fy;
- y = -fx;
- z = 0.0f;
- w = 0.0f;
- if (x * x + y * y == 0.0f) {
- x = 0.0f;
- y = fz;
- z = -fy;
- w = 0.0f;
- }
- } else {
- float sd2 = Math.sqrt((1.0f + dot) * 2.0f);
- float isd2 = 1.0f / sd2;
- float cx = fy * tz - fz * ty;
- float cy = fz * tx - fx * tz;
- float cz = fx * ty - fy * tx;
- x = cx * isd2;
- y = cy * isd2;
- z = cz * isd2;
- w = sd2 * 0.5f;
- float n2 = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w))));
- x *= n2;
- y *= n2;
- z *= n2;
- w *= n2;
- }
- /* Multiply */
- return dest.set(Math.fma(this.w, x, Math.fma(this.x, w, Math.fma(this.y, z, -this.z * y))),
- Math.fma(this.w, y, Math.fma(-this.x, z, Math.fma(this.y, w, this.z * x))),
- Math.fma(this.w, z, Math.fma(this.x, y, Math.fma(-this.y, x, this.z * w))),
- Math.fma(this.w, w, Math.fma(-this.x, x, Math.fma(-this.y, y, -this.z * z))));
- }
-
- /**
- * Apply a rotation to
- * Since there can be multiple possible rotations, this method chooses the one with the shortest arc.
- *
- * If
- * Because there can be multiple possible rotations, this method chooses the one with the shortest arc.
- *
- * If
- * If
- * If
- * If
- * If
- * If
- * If
- * If
- * If
- * This method creates a new {@link DecimalFormat} on every invocation with the format string "
- * The difference is the rotation that has to be applied to get from
- *
- *
- * It is defined as:
- * Instances of this class are not thread-safe.
- *
- * @author Kai Burjack
- */
-public class QuaternionfInterpolator {
-
- /**
- * Performs singular value decomposition on {@link Matrix3f}.
- *
- * This code was adapted from http://www.public.iastate.edu/.
- *
- * @author Kai Burjack
- */
- private static class SvdDecomposition3f {
- private final float rv1[];
- private final float w[];
- private final float v[];
-
- SvdDecomposition3f() {
- this.rv1 = new float[3];
- this.w = new float[3];
- this.v = new float[9];
- }
-
- private float SIGN(float a, float b) {
- return ((b) >= 0.0 ? Math.abs(a) : -Math.abs(a));
- }
-
- void svd(float[] a, int maxIterations, Matrix3f destU, Matrix3f destV) {
- int flag, i, its, j, jj, k, l = 0, nm = 0;
- float c, f, h, s, x, y, z;
- float anorm = 0.0f, g = 0.0f, scale = 0.0f;
- /* Householder reduction to bidiagonal form */
- for (i = 0; i < 3; i++) {
- /* left-hand reduction */
- l = i + 1;
- rv1[i] = scale * g;
- g = s = scale = 0.0f;
- for (k = i; k < 3; k++)
- scale += Math.abs(a[k + 3 * i]);
- if (scale != 0.0f) {
- for (k = i; k < 3; k++) {
- a[k + 3 * i] = (a[k + 3 * i] / scale);
- s += (a[k + 3 * i] * a[k + 3 * i]);
- }
- f = a[i + 3 * i];
- g = -SIGN((float) Math.sqrt(s), f);
- h = f * g - s;
- a[i + 3 * i] = f - g;
- if (i != 3 - 1) {
- for (j = l; j < 3; j++) {
- for (s = 0.0f, k = i; k < 3; k++)
- s += a[k + 3 * i] * a[k + 3 * j];
- f = s / h;
- for (k = i; k < 3; k++)
- a[k + 3 * j] += f * a[k + 3 * i];
- }
- }
- for (k = i; k < 3; k++)
- a[k + 3 * i] = a[k + 3 * i] * scale;
- }
- w[i] = scale * g;
-
- /* right-hand reduction */
- g = s = scale = 0.0f;
- if (i < 3 && i != 3 - 1) {
- for (k = l; k < 3; k++)
- scale += Math.abs(a[i + 3 * k]);
- if (scale != 0.0f) {
- for (k = l; k < 3; k++) {
- a[i + 3 * k] = a[i + 3 * k] / scale;
- s += a[i + 3 * k] * a[i + 3 * k];
- }
- f = a[i + 3 * l];
- g = -SIGN((float) Math.sqrt(s), f);
- h = f * g - s;
- a[i + 3 * l] = f - g;
- for (k = l; k < 3; k++)
- rv1[k] = a[i + 3 * k] / h;
- if (i != 3 - 1) {
- for (j = l; j < 3; j++) {
- for (s = 0.0f, k = l; k < 3; k++)
- s += a[j + 3 * k] * a[i + 3 * k];
- for (k = l; k < 3; k++)
- a[j + 3 * k] += s * rv1[k];
- }
- }
- for (k = l; k < 3; k++)
- a[i + 3 * k] = a[i + 3 * k] * scale;
- }
- }
- anorm = Math.max(anorm, (Math.abs(w[i]) + Math.abs(rv1[i])));
- }
-
- /* accumulate the right-hand transformation */
- for (i = 3 - 1; i >= 0; i--) {
- if (i < 3 - 1) {
- if (g != 0.0f) {
- for (j = l; j < 3; j++)
- v[j + 3 * i] = (a[i + 3 * j] / a[i + 3 * l]) / g;
- /* double division to avoid underflow */
- for (j = l; j < 3; j++) {
- for (s = 0.0f, k = l; k < 3; k++)
- s += a[i + 3 * k] * v[k + 3 * j];
- for (k = l; k < 3; k++)
- v[k + 3 * j] += s * v[k + 3 * i];
- }
- }
- for (j = l; j < 3; j++)
- v[i + 3 * j] = v[j + 3 * i] = 0.0f;
- }
- v[i + 3 * i] = 1.0f;
- g = rv1[i];
- l = i;
- }
-
- /* accumulate the left-hand transformation */
- for (i = 3 - 1; i >= 0; i--) {
- l = i + 1;
- g = w[i];
- if (i < 3 - 1)
- for (j = l; j < 3; j++)
- a[i + 3 * j] = 0.0f;
- if (g != 0.0f) {
- g = 1.0f / g;
- if (i != 3 - 1) {
- for (j = l; j < 3; j++) {
- for (s = 0.0f, k = l; k < 3; k++)
- s += a[k + 3 * i] * a[k + 3 * j];
- f = s / a[i + 3 * i] * g;
- for (k = i; k < 3; k++)
- a[k + 3 * j] += f * a[k + 3 * i];
- }
- }
- for (j = i; j < 3; j++)
- a[j + 3 * i] = a[j + 3 * i] * g;
- } else {
- for (j = i; j < 3; j++)
- a[j + 3 * i] = 0.0f;
- }
- ++a[i + 3 * i];
- }
-
- /* diagonalize the bidiagonal form */
- for (k = 3 - 1; k >= 0; k--) { /* loop over singular values */
- for (its = 0; its < maxIterations; its++) { /* loop over allowed iterations */
- flag = 1;
- for (l = k; l >= 0; l--) { /* test for splitting */
- nm = l - 1;
- if (Math.abs(rv1[l]) + anorm == anorm) {
- flag = 0;
- break;
- }
- if (Math.abs(w[nm]) + anorm == anorm)
- break;
- }
- if (flag != 0) {
- c = 0.0f;
- s = 1.0f;
- for (i = l; i <= k; i++) {
- f = s * rv1[i];
- if (Math.abs(f) + anorm != anorm) {
- g = w[i];
- h = PYTHAG(f, g);
- w[i] = h;
- h = 1.0f / h;
- c = g * h;
- s = (-f * h);
- for (j = 0; j < 3; j++) {
- y = a[j + 3 * nm];
- z = a[j + 3 * i];
- a[j + 3 * nm] = y * c + z * s;
- a[j + 3 * i] = z * c - y * s;
- }
- }
- }
- }
- z = w[k];
- if (l == k) { /* convergence */
- if (z < 0.0f) { /* make singular value nonnegative */
- w[k] = -z;
- for (j = 0; j < 3; j++)
- v[j + 3 * k] = (-v[j + 3 * k]);
- }
- break;
- }
- if (its == maxIterations - 1) {
- throw new RuntimeException("No convergence after " + maxIterations + " iterations");
- }
-
- /* shift from bottom 2 x 2 minor */
- x = w[l];
- nm = k - 1;
- y = w[nm];
- g = rv1[nm];
- h = rv1[k];
- f = ((y - z) * (y + z) + (g - h) * (g + h)) / (2.0f * h * y);
- g = PYTHAG(f, 1.0f);
- f = ((x - z) * (x + z) + h * ((y / (f + SIGN(g, f))) - h)) / x;
-
- /* next QR transformation */
- c = s = 1.0f;
- for (j = l; j <= nm; j++) {
- i = j + 1;
- g = rv1[i];
- y = w[i];
- h = s * g;
- g = c * g;
- z = PYTHAG(f, h);
- rv1[j] = z;
- c = f / z;
- s = h / z;
- f = x * c + g * s;
- g = g * c - x * s;
- h = y * s;
- y = y * c;
- for (jj = 0; jj < 3; jj++) {
- x = v[jj + 3 * j];
- z = v[jj + 3 * i];
- v[jj + 3 * j] = x * c + z * s;
- v[jj + 3 * i] = z * c - x * s;
- }
- z = PYTHAG(f, h);
- w[j] = z;
- if (z != 0.0f) {
- z = 1.0f / z;
- c = f * z;
- s = h * z;
- }
- f = (c * g) + (s * y);
- x = (c * y) - (s * g);
- for (jj = 0; jj < 3; jj++) {
- y = a[jj + 3 * j];
- z = a[jj + 3 * i];
- a[jj + 3 * j] = y * c + z * s;
- a[jj + 3 * i] = z * c - y * s;
- }
- }
- rv1[l] = 0.0f;
- rv1[k] = f;
- w[k] = x;
- }
- }
- destU.set(a);
- destV.set(v);
- }
-
- private static float PYTHAG(float a, float b) {
- float at = Math.abs(a), bt = Math.abs(b), ct, result;
- if (at > bt) {
- ct = bt / at;
- result = at * (float) Math.sqrt(1.0 + ct * ct);
- } else if (bt > 0.0f) {
- ct = at / bt;
- result = bt * (float) Math.sqrt(1.0 + ct * ct);
- } else
- result = 0.0f;
- return (result);
- }
- }
-
- private final SvdDecomposition3f svdDecomposition3f = new SvdDecomposition3f();
- private final float[] m = new float[9];
- private final Matrix3f u = new Matrix3f();
- private final Matrix3f v = new Matrix3f();
-
- /**
- * Compute the weighted average of all of the quaternions given in
- * This quaternion must be {@link #normalize(Quaternionf) normalized}.
- *
- * @return the angle in radians
- */
- float angle();
-
- /**
- * Set the given destination matrix to the rotation represented by
- * This is equivalent to calling:
- * This is equivalent to calling:
- * This is equivalent to calling:
- * This is equivalent to calling:
- * This is equivalent to calling:
- * This is equivalent to calling:
- * If
- *
- * So, this method uses post-multiplication like the matrix classes, resulting in a
- * vector to be transformed by
- * If
- *
- * So, this method uses post-multiplication like the matrix classes, resulting in a
- * vector to be transformed by
- * If
- *
- * So, this method uses pre-multiplication, resulting in a vector to be transformed by
- * If
- *
- * So, this method uses pre-multiplication, resulting in a vector to be transformed by
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * @param vec
- * the vector to transform
- * @return vec
- */
- Vector3f transform(Vector3f vec);
-
- /**
- * Transform the given vector by the inverse of this quaternion.
- *
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * @param vec
- * the vector to transform
- * @return vec
- */
- Vector3f transformInverse(Vector3f vec);
-
- /**
- * Transform the given vector by this unit quaternion.
- *
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * This method is only applicable when
- * Only the first three components of the given 4D vector are modified.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformPositiveX(Vector4f dest);
-
- /**
- * Transform the vector
- * This method is only applicable when
- * Reference: https://de.mathworks.com/
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformUnitPositiveX(Vector3f dest);
-
- /**
- * Transform the vector
- * Only the first three components of the given 4D vector are modified.
- *
- * This method is only applicable when
- * Reference: https://de.mathworks.com/
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformUnitPositiveX(Vector4f dest);
-
- /**
- * Transform the vector
- * Only the first three components of the given 4D vector are modified.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformPositiveY(Vector4f dest);
-
- /**
- * Transform the vector
- * This method is only applicable when
- * Reference: https://de.mathworks.com/
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformUnitPositiveY(Vector3f dest);
-
- /**
- * Transform the vector
- * Only the first three components of the given 4D vector are modified.
- *
- * This method is only applicable when
- * Reference: https://de.mathworks.com/
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformUnitPositiveY(Vector4f dest);
-
- /**
- * Transform the vector
- * Only the first three components of the given 4D vector are modified.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformPositiveZ(Vector4f dest);
-
- /**
- * Transform the vector
- * This method is only applicable when
- * Reference: https://de.mathworks.com/
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformUnitPositiveZ(Vector3f dest);
-
- /**
- * Transform the vector
- * Only the first three components of the given 4D vector are modified.
- *
- * This method is only applicable when
- * Reference: https://de.mathworks.com/
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformUnitPositiveZ(Vector4f dest);
-
- /**
- * Transform the given vector by this quaternion.
- *
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * Only the first three components of the given 4D vector are being used and modified.
- *
- * @param vec
- * the vector to transform
- * @return vec
- */
- Vector4f transform(Vector4f vec);
-
- /**
- * Transform the given vector by the inverse of this quaternion.
- *
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * Only the first three components of the given 4D vector are being used and modified.
- *
- * @param vec
- * the vector to transform
- * @return vec
- */
- Vector4f transformInverse(Vector4f vec);
-
- /**
- * Transform the given vector by this quaternion
- * and store the result in
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * @param vec
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transform(Vector3fc vec, Vector3f dest);
-
- /**
- * Transform the given vector by the inverse of quaternion
- * and store the result in
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * @param vec
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformInverse(Vector3fc vec, Vector3f dest);
-
- /**
- * Transform the given vector
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transform(float x, float y, float z, Vector3f dest);
-
- /**
- * Transform the given vector
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformInverse(float x, float y, float z, Vector3f dest);
-
- /**
- * Transform the given vector by the inverse of this unit quaternion.
- *
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * Only the first three components of the given 4D vector are being used and set on the destination.
- *
- * @param vec
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transform(Vector4fc vec, Vector4f dest);
-
- /**
- * Transform the given vector by the inverse of this quaternion and store the result in
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * Only the first three components of the given 4D vector are being used and set on the destination.
- *
- * @param vec
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformInverse(Vector4fc vec, Vector4f dest);
-
- /**
- * Transform the given vector
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transform(float x, float y, float z, Vector4f dest);
-
- /**
- * Transform the given vector
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformInverse(float x, float y, float z, Vector4f dest);
-
- /**
- * Transform the given vector by this unit quaternion and store the result in
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * Only the first three components of the given 4D vector are being used and set on the destination.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * Only the first three components of the given 4D vector are being used and set on the destination.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * Only the first three components of the given 4D vector are being used and set on the destination.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * Only the first three components of the given 4D vector are being used and set on the destination.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * This method is only applicable when
- * This will apply the rotation described by this quaternion to the given vector.
- *
- * This method is only applicable when
- * If this quaternion is already normalized, then {@link #conjugate(Quaternionf)} should be used instead.
- *
- * @see #conjugate(Quaternionf)
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf invert(Quaternionf dest);
-
- /**
- * Divide
- * The division expressed using the inverse is performed in the following way:
- *
- *
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * If
- * This method is equivalent to calling:
- * If
- * The Euler angles are always returned as the angle around X in the {@link Vector3f#x} field, the angle around Y in the {@link Vector3f#y}
- * field and the angle around Z in the {@link Vector3f#z} field of the supplied {@link Vector3f} instance.
- *
- * @param eulerAngles
- * will hold the euler angles in radians
- * @return the passed in vector
- */
- Vector3f getEulerAnglesXYZ(Vector3f eulerAngles);
-
- /**
- * Get the euler angles in radians in rotation sequence
- * The Euler angles are always returned as the angle around X in the {@link Vector3f#x} field, the angle around Y in the {@link Vector3f#y}
- * field and the angle around Z in the {@link Vector3f#z} field of the supplied {@link Vector3f} instance.
- *
- * @param eulerAngles
- * will hold the euler angles in radians
- * @return the passed in vector
- */
- Vector3f getEulerAnglesZYX(Vector3f eulerAngles);
-
- /**
- * Get the euler angles in radians in rotation sequence
- * The Euler angles are always returned as the angle around X in the {@link Vector3f#x} field, the angle around Y in the {@link Vector3f#y}
- * field and the angle around Z in the {@link Vector3f#z} field of the supplied {@link Vector3f} instance.
- *
- * @param eulerAngles
- * will hold the euler angles in radians
- * @return the passed in vector
- */
- Vector3f getEulerAnglesZXY(Vector3f eulerAngles);
-
- /**
- * Get the euler angles in radians in rotation sequence
- * The Euler angles are always returned as the angle around X in the {@link Vector3f#x} field, the angle around Y in the {@link Vector3f#y}
- * field and the angle around Z in the {@link Vector3f#z} field of the supplied {@link Vector3f} instance.
- *
- * @param eulerAngles
- * will hold the euler angles in radians
- * @return the passed in vector
- */
- Vector3f getEulerAnglesYXZ(Vector3f eulerAngles);
-
- /**
- * Return the square of the length of this quaternion.
- *
- * @return the length
- */
- float lengthSquared();
-
- /**
- * Interpolate between
- * This method resorts to non-spherical linear interpolation when the absolute dot product of
- * Reference: http://fabiensanglard.net
- *
- * @param target
- * the target of the interpolation, which should be reached with
- * This method pre-multiplies the rotation given by
- * This method is equivalent to calling:
- * Reference: http://physicsforgames.blogspot.de/
- *
- * @param dt
- * the delta time
- * @param vx
- * the angular velocity around the x axis
- * @param vy
- * the angular velocity around the y axis
- * @param vz
- * the angular velocity around the z axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf integrate(float dt, float vx, float vy, float vz, Quaternionf dest);
-
- /**
- * Compute a linear (non-spherical) interpolation of
- * Reference: http://fabiensanglard.net
- *
- * @param q
- * the other quaternion
- * @param factor
- * the interpolation factor. It is between 0.0 and 1.0
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf nlerp(Quaternionfc q, float factor, Quaternionf dest);
-
- /**
- * Compute linear (non-spherical) interpolations of
- * This method performs a series of small-step nlerp interpolations to avoid doing a costly spherical linear interpolation, like
- * {@link #slerp(Quaternionfc, float, Quaternionf) slerp},
- * by subdividing the rotation arc between
- * Thanks to
- * Because there are multiple possibilities for such a rotation, this method will choose the one that ensures the given up direction to remain
- * parallel to the plane spanned by the
- * If
- * Reference: http://answers.unity3d.com
- *
- * @see #lookAlong(float, float, float, float, float, float, Quaternionf)
- *
- * @param dir
- * the direction to map to the positive Z axis
- * @param up
- * the vector which will be mapped to a vector parallel to the plane
- * spanned by the given
- * Because there are multiple possibilities for such a rotation, this method will choose the one that ensures the given up direction to remain
- * parallel to the plane spanned by the
- * If
- * Reference: http://answers.unity3d.com
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf lookAlong(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Quaternionf dest);
-
- /**
- * Apply a rotation to
- * Since there can be multiple possible rotations, this method chooses the one with the shortest arc.
- *
- * If
- * Reference: stackoverflow.com
- *
- * @param fromDirX
- * the x-coordinate of the direction to rotate into the destination direction
- * @param fromDirY
- * the y-coordinate of the direction to rotate into the destination direction
- * @param fromDirZ
- * the z-coordinate of the direction to rotate into the destination direction
- * @param toDirX
- * the x-coordinate of the direction to rotate to
- * @param toDirY
- * the y-coordinate of the direction to rotate to
- * @param toDirZ
- * the z-coordinate of the direction to rotate to
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateTo(float fromDirX, float fromDirY, float fromDirZ, float toDirX, float toDirY, float toDirZ, Quaternionf dest);
-
- /**
- * Apply a rotation to
- * Because there can be multiple possible rotations, this method chooses the one with the shortest arc.
- *
- * If
- * If
- * If
- * If
- * If
- * If
- * If
- * If
- * If
- * The difference is the rotation that has to be applied to get from
- *
- *
- * It is defined as:
- * This method is equivalent to the following code:
- *
- * This method is equivalent to the following code:
- *
- * This method is equivalent to the following code:
- *
- * This method is equivalent to the following code:
- *
- * This method is equivalent to the following code:
- *
- * This method is equivalent to the following code:
- *
- * Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
- * and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
- * data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
- *
- * @param q
- * the other quaternion
- * @param delta
- * the allowed maximum difference
- * @return
- * It is an efficient implementation when testing many axis-aligned boxes against the same ray.
- *
- * This class is thread-safe and can be used in a multithreaded environment when testing many axis-aligned boxes against the same ray concurrently.
- *
- * @author Kai Burjack
- */
-public class RayAabIntersection {
- private float originX, originY, originZ;
- private float dirX, dirY, dirZ;
-
- /* Needed for ray slope intersection method */
- private float c_xy, c_yx, c_zy, c_yz, c_xz, c_zx;
- private float s_xy, s_yx, s_zy, s_yz, s_xz, s_zx;
- private byte classification;
-
- /**
- * Create a new {@link RayAabIntersection} without initializing a ray.
- *
- * Before using the {@link #test(float, float, float, float, float, float) intersect()} method,
- * the method {@link #set(float, float, float, float, float, float) set()} must be called in order to
- * initialize the created RayAabIntersection instance with a ray.
- *
- * @see #set(float, float, float, float, float, float)
- */
- public RayAabIntersection() {
- }
-
- /**
- * Create a new {@link RayAabIntersection} and initialize it with a ray with origin
- * In order to change the direction and/or origin of the ray later, use {@link #set(float, float, float, float, float, float) set()}.
- *
- * @see #set(float, float, float, float, float, float)
- *
- * @param originX
- * the x coordinate of the origin
- * @param originY
- * the y coordinate of the origin
- * @param originZ
- * the z coordinate of the origin
- * @param dirX
- * the x coordinate of the direction
- * @param dirY
- * the y coordinate of the direction
- * @param dirZ
- * the z coordinate of the direction
- */
- public RayAabIntersection(float originX, float originY, float originZ, float dirX, float dirY, float dirZ) {
- set(originX, originY, originZ, dirX, dirY, dirZ);
- }
-
- /**
- * Update the ray stored by this {@link RayAabIntersection} with the new origin
- * This implementation uses a tableswitch to dispatch to the correct intersection method.
- *
- * This method is thread-safe and can be used to test many axis-aligned boxes concurrently.
- *
- * @param minX
- * the x coordinate of the minimum corner
- * @param minY
- * the y coordinate of the minimum corner
- * @param minZ
- * the z coordinate of the minimum corner
- * @param maxX
- * the x coordinate of the maximum corner
- * @param maxY
- * the y coordinate of the maximum corner
- * @param maxZ
- * the z coordinate of the maximum corner
- * @return
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the vector is read, use {@link #Vector3f(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer values will be read in
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index the absolute position into the ByteBuffer
- * @param buffer values will be read in
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the vector is read, use {@link #Vector3f(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer values will be read in
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index the absolute position into the FloatBuffer
- * @param buffer values will be read in
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the vector is read, use {@link #set(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the vector is read, use {@link #set(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * values will be read in
- * This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
- *
- * This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
- *
- * @param address
- * the off-heap memory address to read the vector values from
- * @return this
- */
- public Vector3f setFromAddress(long address) {
- if (Options.NO_UNSAFE)
- throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
- MemUtil.MemUtilUnsafe.get(this, address);
- return this;
- }
-
- /**
- * Set the value of the specified component of this vector.
- *
- * @param component
- * the component whose value to set, within
- * This method uses
- * This method assumes the
- * This method assumes the
- * This method assumes the
- * This method assumes the
- * This method assumes the
- * This method creates a new {@link DecimalFormat} on every invocation with the format string "
- * If
- * Reference: Gram–Schmidt process
- *
- * @param v
- * the reference vector which the result should be orthogonal to
- * @return this
- */
- public Vector3f orthogonalize(Vector3fc v) {
- return orthogonalize(v, this);
- }
-
- public Vector3f orthogonalizeUnit(Vector3fc v, Vector3f dest) {
- return orthogonalize(v, dest);
- }
-
- /**
- * Transform
- * The vector
- * Reference: Gram–Schmidt process
- *
- * @param v
- * the reference unit vector which the result should be orthogonal to
- * @return this
- */
- public Vector3f orthogonalizeUnit(Vector3fc v) {
- return orthogonalizeUnit(v, this);
- }
-
- /**
- * Set each component of this vector to the largest (closest to positive
- * infinity) {@code float} value that is less than or equal to that
- * component and is equal to a mathematical integer.
- *
- * @return this
- */
- public Vector3f floor() {
- return floor(this);
- }
-
- public Vector3f floor(Vector3f dest) {
- dest.x = Math.floor(x);
- dest.y = Math.floor(y);
- dest.z = Math.floor(z);
- return dest;
- }
-
- /**
- * Set each component of this vector to the smallest (closest to negative
- * infinity) {@code float} value that is greater than or equal to that
- * component and is equal to a mathematical integer.
- *
- * @return this
- */
- public Vector3f ceil() {
- return ceil(this);
- }
-
- public Vector3f ceil(Vector3f dest) {
- dest.x = Math.ceil(x);
- dest.y = Math.ceil(y);
- dest.z = Math.ceil(z);
- return dest;
- }
-
- /**
- * Set each component of this vector to the closest float that is equal to
- * a mathematical integer, with ties rounding to positive infinity.
- *
- * @return this
- */
- public Vector3f round() {
- return round(this);
- }
-
- public Vector3f round(Vector3f dest) {
- dest.x = Math.round(x);
- dest.y = Math.round(y);
- dest.z = Math.round(z);
- return dest;
- }
-
- public boolean isFinite() {
- return Math.isFinite(x) && Math.isFinite(y) && Math.isFinite(z);
- }
-
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Vector3fc.java b/src/main/java/com/jozufozu/flywheel/util/joml/Vector3fc.java
deleted file mode 100644
index 690aee2dc..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Vector3fc.java
+++ /dev/null
@@ -1,1003 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2016-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.util.*;
-
-/**
- * Interface to a read-only view of a 3-dimensional vector of single-precision floats.
- *
- * @author Kai Burjack
- */
-public interface Vector3fc {
-
- /**
- * @return the value of the x component
- */
- float x();
-
- /**
- * @return the value of the y component
- */
- float y();
-
- /**
- * @return the value of the z component
- */
- float z();
-
- /**
- * Store this vector into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- *
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the vector is stored, use {@link #get(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get(int, FloatBuffer)
- *
- * @param buffer
- * will receive the values of this vector in
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of this vector in
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the vector is stored, use {@link #get(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @see #get(int, ByteBuffer)
- *
- * @param buffer
- * will receive the values of this vector in
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of this vector in
- * This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
- *
- * This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
- *
- * @param address
- * the off-heap address where to store this vector
- * @return this
- */
- Vector3fc getToAddress(long address);
-
- /**
- * Subtract the supplied vector from this one and store the result in
- * This method uses
- * This method uses the given
- * This method assumes the
- * This method assumes the
- * This method assumes the
- * This method assumes the
- * This method assumes the
- * Because there can be multiple possible rotations, this method chooses the one with the shortest arc.
- *
- * @see Quaternionf#rotationTo(Vector3fc, Vector3fc)
- *
- * @param toDir
- * the destination direction
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotationTo(Vector3fc toDir, Quaternionf dest);
-
- /**
- * Compute the quaternion representing a rotation of
- * Because there can be multiple possible rotations, this method chooses the one with the shortest arc.
- *
- * @see Quaternionf#rotationTo(float, float, float, float, float, float)
- *
- * @param toDirX
- * the x coordinate of the destination direction
- * @param toDirY
- * the y coordinate of the destination direction
- * @param toDirZ
- * the z coordinate of the destination direction
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotationTo(float toDirX, float toDirY, float toDirZ, Quaternionf dest);
-
- /**
- * Rotate this vector the specified radians around the given rotation axis and store the result
- * into
- * If
- * Reference: Gram–Schmidt process
- *
- * @param v
- * the reference vector which the result should be orthogonal to
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f orthogonalize(Vector3fc v, Vector3f dest);
-
- /**
- * Transform
- * The vector
- * Reference: Gram–Schmidt process
- *
- * @param v
- * the reference unit vector which the result should be orthogonal to
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f orthogonalizeUnit(Vector3fc v, Vector3f dest);
-
- /**
- * Compute for each component of this vector the largest (closest to positive
- * infinity) {@code float} value that is less than or equal to that
- * component and is equal to a mathematical integer and store the result in
- *
- * Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
- * and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
- * data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
- *
- * @param v
- * the other vector
- * @param delta
- * the allowed maximum difference
- * @return
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the vector is read, use {@link #Vector4f(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the vector is read, use {@link #Vector4f(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the vector is read, use {@link #set(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the vector is read, use {@link #set(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer
- * values will be read in
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * values will be read in
- * This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
- *
- * This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
- *
- * @param address
- * the off-heap memory address to read the vector values from
- * @return this
- */
- public Vector4f setFromAddress(long address) {
- if (Options.NO_UNSAFE)
- throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
- MemUtil.MemUtilUnsafe.get(this, address);
- return this;
- }
-
- /**
- * Set the value of the specified component of this vector.
- *
- * @param component
- * the component whose value to set, within
- * This method creates a new {@link DecimalFormat} on every invocation with the format string "
- * If
- * This method will not increment the position of the given FloatBuffer.
- *
- * In order to specify the offset into the FloatBuffer at which
- * the vector is stored, use {@link #get(int, FloatBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer
- * will receive the values of this vector in
- * This method will not increment the position of the given FloatBuffer.
- *
- * @param index
- * the absolute position into the FloatBuffer
- * @param buffer
- * will receive the values of this vector in
- * This method will not increment the position of the given ByteBuffer.
- *
- * In order to specify the offset into the ByteBuffer at which
- * the vector is stored, use {@link #get(int, ByteBuffer)}, taking
- * the absolute position as parameter.
- *
- * @param buffer
- * will receive the values of this vector in
- * This method will not increment the position of the given ByteBuffer.
- *
- * @param index
- * the absolute position into the ByteBuffer
- * @param buffer
- * will receive the values of this vector in
- * This method will throw an {@link UnsupportedOperationException} when JOML is used with `-Djoml.nounsafe`.
- *
- * This method is unsafe as it can result in a crash of the JVM process when the specified address range does not belong to this process.
- *
- * @param address
- * the off-heap address where to store this vector
- * @return this
- */
- Vector4fc getToAddress(long address);
-
- /**
- * Subtract the supplied vector from this one and store the result in
- * If
- * Please note that this method is not used by any data structure such as {@link ArrayList} {@link HashSet} or {@link HashMap}
- * and their operations, such as {@link ArrayList#contains(Object)} or {@link HashSet#remove(Object)}, since those
- * data structures only use the {@link Object#equals(Object)} and {@link Object#hashCode()} methods.
- *
- * @param v
- * the other vector
- * @param delta
- * the allowed maximum difference
- * @return x=-1
when using the identity frustum.
- */
- public static final int PLANE_NX = 0;
- /**
- * Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
- * and its different overloads identifying the plane with equation x=1
when using the identity frustum.
- */
- public static final int PLANE_PX = 1;
- /**
- * Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
- * and its different overloads identifying the plane with equation y=-1
when using the identity frustum.
- */
- public static final int PLANE_NY= 2;
- /**
- * Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
- * and its different overloads identifying the plane with equation y=1
when using the identity frustum.
- */
- public static final int PLANE_PY = 3;
- /**
- * Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
- * and its different overloads identifying the plane with equation z=-1
when using the identity frustum.
- */
- public static final int PLANE_NZ = 4;
- /**
- * Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
- * and its different overloads identifying the plane with equation z=1
when using the identity frustum.
- */
- public static final int PLANE_PZ = 5;
-
- /**
- * Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
- * and its different overloads indicating that the axis-aligned box intersects the frustum.
- */
- public static final int INTERSECT = -1;
- /**
- * Return value of {@link #intersectAab(float, float, float, float, float, float) intersectAab()}
- * and its different overloads indicating that the axis-aligned box is fully inside of the frustum.
- */
- public static final int INSIDE = -2;
- /**
- * Return value of {@link #intersectSphere(Vector3fc, float)} or {@link #intersectSphere(float, float, float, float)}
- * indicating that the sphere is completely outside of the frustum.
- */
- public static final int OUTSIDE = -3;
-
- /**
- * The value in a bitmask for
- * {@link #intersectAab(float, float, float, float, float, float, int) intersectAab()}
- * that identifies the plane with equation x=-1
when using the identity frustum.
- */
- public static final int PLANE_MASK_NX = 1<false
should be used
- */
- public FrustumIntersection(Matrix4fc m, boolean allowTestSpheres) {
- set(m, allowTestSpheres);
- }
-
- /**
- * Update the stored frustum planes of this
{@link FrustumIntersection} with the given {@link Matrix4fc matrix}.
- * this
frustum culler's frustum planes from
- * @return this
- */
- public FrustumIntersection set(Matrix4fc m) {
- return set(m, true);
- }
-
- /**
- * Update the stored frustum planes of this
{@link FrustumIntersection} with the given {@link Matrix4fc matrix} and
- * allow to optimize the frustum plane extraction in the case when no intersection test is needed for spheres.
- * this
frustum culler's frustum planes from
- * @param allowTestSpheres
- * whether the methods {@link #testSphere(Vector3fc, float)}, {@link #testSphere(float, float, float, float)},
- * {@link #intersectSphere(Vector3fc, float)} or {@link #intersectSphere(float, float, float, float)} will be used.
- * If no spheres need to be tested, then false
should be used
- * @return this
- */
- public FrustumIntersection set(Matrix4fc m, boolean allowTestSpheres) {
- float invl;
- nxX = m.m03() + m.m00(); nxY = m.m13() + m.m10(); nxZ = m.m23() + m.m20(); nxW = m.m33() + m.m30();
- if (allowTestSpheres) {
- invl = Math.invsqrt(nxX * nxX + nxY * nxY + nxZ * nxZ);
- nxX *= invl; nxY *= invl; nxZ *= invl; nxW *= invl;
- }
- planes[0].set(nxX, nxY, nxZ, nxW);
- pxX = m.m03() - m.m00(); pxY = m.m13() - m.m10(); pxZ = m.m23() - m.m20(); pxW = m.m33() - m.m30();
- if (allowTestSpheres) {
- invl = Math.invsqrt(pxX * pxX + pxY * pxY + pxZ * pxZ);
- pxX *= invl; pxY *= invl; pxZ *= invl; pxW *= invl;
- }
- planes[1].set(pxX, pxY, pxZ, pxW);
- nyX = m.m03() + m.m01(); nyY = m.m13() + m.m11(); nyZ = m.m23() + m.m21(); nyW = m.m33() + m.m31();
- if (allowTestSpheres) {
- invl = Math.invsqrt(nyX * nyX + nyY * nyY + nyZ * nyZ);
- nyX *= invl; nyY *= invl; nyZ *= invl; nyW *= invl;
- }
- planes[2].set(nyX, nyY, nyZ, nyW);
- pyX = m.m03() - m.m01(); pyY = m.m13() - m.m11(); pyZ = m.m23() - m.m21(); pyW = m.m33() - m.m31();
- if (allowTestSpheres) {
- invl = Math.invsqrt(pyX * pyX + pyY * pyY + pyZ * pyZ);
- pyX *= invl; pyY *= invl; pyZ *= invl; pyW *= invl;
- }
- planes[3].set(pyX, pyY, pyZ, pyW);
- nzX = m.m03() + m.m02(); nzY = m.m13() + m.m12(); nzZ = m.m23() + m.m22(); nzW = m.m33() + m.m32();
- if (allowTestSpheres) {
- invl = Math.invsqrt(nzX * nzX + nzY * nzY + nzZ * nzZ);
- nzX *= invl; nzY *= invl; nzZ *= invl; nzW *= invl;
- }
- planes[4].set(nzX, nzY, nzZ, nzW);
- pzX = m.m03() - m.m02(); pzY = m.m13() - m.m12(); pzZ = m.m23() - m.m22(); pzW = m.m33() - m.m32();
- if (allowTestSpheres) {
- invl = Math.invsqrt(pzX * pzX + pzY * pzY + pzZ * pzZ);
- pzX *= invl; pzY *= invl; pzZ *= invl; pzW *= invl;
- }
- planes[5].set(pzX, pzY, pzZ, pzW);
- return this;
- }
-
- /**
- * Test whether the given point is within the frustum defined by this
frustum culler.
- *
- * @param point
- * the point to test
- * @return true
if the given point is inside the frustum; false
otherwise
- */
- public boolean testPoint(Vector3fc point) {
- return testPoint(point.x(), point.y(), point.z());
- }
-
- /**
- * Test whether the given point (x, y, z)
is within the frustum defined by this
frustum culler.
- *
- * @param x
- * the x-coordinate of the point
- * @param y
- * the y-coordinate of the point
- * @param z
- * the z-coordinate of the point
- * @return true
if the given point is inside the frustum; false
otherwise
- */
- public boolean testPoint(float x, float y, float z) {
- return nxX * x + nxY * y + nxZ * z + nxW >= 0 &&
- pxX * x + pxY * y + pxZ * z + pxW >= 0 &&
- nyX * x + nyY * y + nyZ * z + nyW >= 0 &&
- pyX * x + pyY * y + pyZ * z + pyW >= 0 &&
- nzX * x + nzY * y + nzZ * z + nzW >= 0 &&
- pzX * x + pzY * y + pzZ * z + pzW >= 0;
- }
-
- /**
- * Test whether the given sphere is partly or completely within or outside of the frustum defined by this
frustum culler.
- * true
for spheres that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * @param center
- * the sphere's center
- * @param radius
- * the sphere's radius
- * @return true
if the given sphere is partly or completely inside the frustum;
- * false
otherwise
- */
- public boolean testSphere(Vector3fc center, float radius) {
- return testSphere(center.x(), center.y(), center.z(), radius);
- }
-
- /**
- * Test whether the given sphere is partly or completely within or outside of the frustum defined by this
frustum culler.
- * true
for spheres that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * @param x
- * the x-coordinate of the sphere's center
- * @param y
- * the y-coordinate of the sphere's center
- * @param z
- * the z-coordinate of the sphere's center
- * @param r
- * the sphere's radius
- * @return true
if the given sphere is partly or completely inside the frustum;
- * false
otherwise
- */
- public boolean testSphere(float x, float y, float z, float r) {
- return nxX * x + nxY * y + nxZ * z + nxW >= -r &&
- pxX * x + pxY * y + pxZ * z + pxW >= -r &&
- nyX * x + nyY * y + nyZ * z + nyW >= -r &&
- pyX * x + pyY * y + pyZ * z + pyW >= -r &&
- nzX * x + nzY * y + nzZ * z + nzW >= -r &&
- pzX * x + pzY * y + pzZ * z + pzW >= -r;
- }
-
- /**
- * Determine whether the given sphere is partly or completely within or outside of the frustum defined by this
frustum culler.
- * this
frustum culler.
- * this
frustum culler.
- * The box is specified via its min
and max
corner coordinates.
- * true
for boxes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * @param min
- * the minimum corner coordinates of the axis-aligned box
- * @param max
- * the maximum corner coordinates of the axis-aligned box
- * @return true
if the axis-aligned box is completely or partly inside of the frustum; false
otherwise
- */
- public boolean testAab(Vector3fc min, Vector3fc max) {
- return testAab(min.x(), min.y(), min.z(), max.x(), max.y(), max.z());
- }
-
- /**
- * Test whether the given axis-aligned box is partly or completely within or outside of the frustum defined by this
frustum culler.
- * The box is specified via its min and max corner coordinates.
- * true
for boxes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- * true
if the axis-aligned box is completely or partly inside of the frustum; false
otherwise
- */
- public boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- /*
- * This is an implementation of the "2.4 Basic intersection test" of the mentioned site.
- * It does not distinguish between partially inside and fully inside, though, so the test with the 'p' vertex is omitted.
- */
- return nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW &&
- pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW &&
- nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW &&
- pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW &&
- nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW &&
- pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW;
- }
-
- /**
- * Test whether the given XY-plane (at Z = 0
) is partly or completely within or outside of the frustum defined by this
frustum culler.
- * The plane is specified via its min and max corner coordinates.
- * true
for planes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- * true
if the XY-plane is completely or partly inside of the frustum; false
otherwise
- */
- public boolean testPlaneXY(float minX, float minY, float maxX, float maxY) {
- /*
- * This is an implementation of the "2.4 Basic intersection test" of the mentioned site.
- * It does not distinguish between partially inside and fully inside, though, so the test with the 'p' vertex is omitted.
- */
- return nxX * (nxX < 0 ? minX : maxX) + nxY * (nxY < 0 ? minY : maxY) >= -nxW &&
- pxX * (pxX < 0 ? minX : maxX) + pxY * (pxY < 0 ? minY : maxY) >= -pxW &&
- nyX * (nyX < 0 ? minX : maxX) + nyY * (nyY < 0 ? minY : maxY) >= -nyW &&
- pyX * (pyX < 0 ? minX : maxX) + pyY * (pyY < 0 ? minY : maxY) >= -pyW &&
- nzX * (nzX < 0 ? minX : maxX) + nzY * (nzY < 0 ? minY : maxY) >= -nzW &&
- pzX * (pzX < 0 ? minX : maxX) + pzY * (pzY < 0 ? minY : maxY) >= -pzW;
- }
-
- /**
- * Test whether the given XZ-plane (at Y = 0
) is partly or completely within or outside of the frustum defined by this
frustum culler.
- * The plane is specified via its min and max corner coordinates.
- * true
for planes that do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- * true
if the XZ-plane is completely or partly inside of the frustum; false
otherwise
- */
- public boolean testPlaneXZ(float minX, float minZ, float maxX, float maxZ) {
- /*
- * This is an implementation of the "2.4 Basic intersection test" of the mentioned site.
- * It does not distinguish between partially inside and fully inside, though, so the test with the 'p' vertex is omitted.
- */
- return nxX * (nxX < 0 ? minX : maxX) + nxZ * (nxZ < 0 ? minZ : maxZ) >= -nxW &&
- pxX * (pxX < 0 ? minX : maxX) + pxZ * (pxZ < 0 ? minZ : maxZ) >= -pxW &&
- nyX * (nyX < 0 ? minX : maxX) + nyZ * (nyZ < 0 ? minZ : maxZ) >= -nyW &&
- pyX * (pyX < 0 ? minX : maxX) + pyZ * (pyZ < 0 ? minZ : maxZ) >= -pyW &&
- nzX * (nzX < 0 ? minX : maxX) + nzZ * (nzZ < 0 ? minZ : maxZ) >= -nzW &&
- pzX * (pzX < 0 ? minX : maxX) + pzZ * (pzZ < 0 ? minZ : maxZ) >= -pzW;
- }
-
- /**
- * Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by this
frustum culler
- * and, if the box is not inside this frustum, return the index of the plane that culled it.
- * The box is specified via its min
and max
corner coordinates.
- * this
frustum culler
- * and, if the box is not inside this frustum, return the index of the plane that culled it.
- * The box is specified via its min and max corner coordinates.
- * plane
.
- *
- * @param minX
- * the x-coordinate of the minimum corner
- * @param minY
- * the y-coordinate of the minimum corner
- * @param minZ
- * the z-coordinate of the minimum corner
- * @param maxX
- * the x-coordinate of the maximum corner
- * @param maxY
- * the y-coordinate of the maximum corner
- * @param maxZ
- * the z-coordinate of the maximum corner
- * @param plane
- * one of
- * {@link #PLANE_NX}, {@link #PLANE_PX},
- * {@link #PLANE_NY}, {@link #PLANE_PY},
- * {@link #PLANE_NZ} and {@link #PLANE_PZ}
- * @return the signed distance of the axis-aligned box to the plane
- */
- public float distanceToPlane(float minX, float minY, float minZ, float maxX, float maxY, float maxZ, int plane) {
- return planes[plane].x * (planes[plane].x < 0 ? maxX : minX) + planes[plane].y * (planes[plane].y < 0 ? maxY : minY)
- + planes[plane].z * (planes[plane].z < 0 ? maxZ : minZ) + planes[plane].w;
- }
-
- /**
- * Determine whether the given axis-aligned box is partly or completely within or outside of the frustum defined by this
frustum culler
- * and, if the box is not inside this frustum, return the index of the plane that culled it.
- * The box is specified via its min
and max
corner coordinates.
- * (~0 ^ PLANE_MASK_NX)
.
- * this
frustum culler
- * and, if the box is not inside this frustum, return the index of the plane that culled it.
- * The box is specified via its min and max corner coordinates.
- * (~0 ^ PLANE_MASK_NX)
.
- * this
frustum culler
- * and, if the box is not inside this frustum, return the index of the plane that culled it.
- * The box is specified via its min
and max
corner coordinates.
- * (~0 ^ PLANE_MASK_NX)
.
- * startPlane
denotes the first frustum plane to test the box against. To use this effectively means to store the
- * plane that previously culled an axis-aligned box (as returned by intersectAab()
) and in the next frame use the return value
- * as the argument to the startPlane
parameter of this method. The assumption is that the plane that culled the object previously will also
- * cull it now (temporal coherency) and the culling computation is likely reduced in that case.
- * this
frustum culler
- * and, if the box is not inside this frustum, return the index of the plane that culled it.
- * The box is specified via its min and max corner coordinates.
- * (~0 ^ PLANE_MASK_NX)
.
- * startPlane
denotes the first frustum plane to test the box against. To use this effectively means to store the
- * plane that previously culled an axis-aligned box (as returned by intersectAab()
) and in the next frame use the return value
- * as the argument to the startPlane
parameter of this method. The assumption is that the plane that culled the object previously will also
- * cull it now (temporal coherency) and the culling computation is likely reduced in that case.
- * a
and b
,
- * is partly or completely within the frustum defined by this
frustum culler.
- *
- * @param a
- * the line segment's first end point
- * @param b
- * the line segment's second end point
- * @return true
if the given line segment is partly or completely inside the frustum;
- * false
otherwise
- */
- public boolean testLineSegment(Vector3fc a, Vector3fc b) {
- return testLineSegment(a.x(), a.y(), a.z(), b.x(), b.y(), b.z());
- }
-
- /**
- * Test whether the given line segment, defined by the end points (aX, aY, aZ)
and (bX, bY, bZ)
,
- * is partly or completely within the frustum defined by this
frustum culler.
- *
- * @param aX
- * the x coordinate of the line segment's first end point
- * @param aY
- * the y coordinate of the line segment's first end point
- * @param aZ
- * the z coordinate of the line segment's first end point
- * @param bX
- * the x coordinate of the line segment's second end point
- * @param bY
- * the y coordinate of the line segment's second end point
- * @param bZ
- * the z coordinate of the line segment's second end point
- * @return true
if the given line segment is partly or completely inside the frustum;
- * false
otherwise
- */
- public boolean testLineSegment(float aX, float aY, float aZ, float bX, float bY, float bZ) {
- float da, db;
- da = Math.fma(nxX, aX, Math.fma(nxY, aY, Math.fma(nxZ, aZ, nxW)));
- db = Math.fma(nxX, bX, Math.fma(nxY, bY, Math.fma(nxZ, bZ, nxW)));
- if (da < 0.0f && db < 0.0f)
- return false;
- if (da * db < 0.0f) {
- float p = Math.abs(da) / Math.abs(db - da);
- float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
- if (da < 0.0f) {
- aX = dx; aY = dy; aZ = dz;
- } else {
- bX = dx; bY = dy; bZ = dz;
- }
- }
- da = Math.fma(pxX, aX, Math.fma(pxY, aY, Math.fma(pxZ, aZ, pxW)));
- db = Math.fma(pxX, bX, Math.fma(pxY, bY, Math.fma(pxZ, bZ, pxW)));
- if (da < 0.0f && db < 0.0f)
- return false;
- if (da * db < 0.0f) {
- float p = Math.abs(da) / Math.abs(db - da);
- float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
- if (da < 0.0f) {
- aX = dx; aY = dy; aZ = dz;
- } else {
- bX = dx; bY = dy; bZ = dz;
- }
- }
- da = Math.fma(nyX, aX, Math.fma(nyY, aY, Math.fma(nyZ, aZ, nyW)));
- db = Math.fma(nyX, bX, Math.fma(nyY, bY, Math.fma(nyZ, bZ, nyW)));
- if (da < 0.0f && db < 0.0f)
- return false;
- if (da * db < 0.0f) {
- float p = Math.abs(da) / Math.abs(db - da);
- float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
- if (da < 0.0f) {
- aX = dx; aY = dy; aZ = dz;
- } else {
- bX = dx; bY = dy; bZ = dz;
- }
- }
- da = Math.fma(pyX, aX, Math.fma(pyY, aY, Math.fma(pyZ, aZ, pyW)));
- db = Math.fma(pyX, bX, Math.fma(pyY, bY, Math.fma(pyZ, bZ, pyW)));
- if (da < 0.0f && db < 0.0f)
- return false;
- if (da * db < 0.0f) {
- float p = Math.abs(da) / Math.abs(db - da);
- float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
- if (da < 0.0f) {
- aX = dx; aY = dy; aZ = dz;
- } else {
- bX = dx; bY = dy; bZ = dz;
- }
- }
- da = Math.fma(nzX, aX, Math.fma(nzY, aY, Math.fma(nzZ, aZ, nzW)));
- db = Math.fma(nzX, bX, Math.fma(nzY, bY, Math.fma(nzZ, bZ, nzW)));
- if (da < 0.0f && db < 0.0f)
- return false;
- if (da * db < 0.0f) {
- float p = Math.abs(da) / Math.abs(db - da);
- float dx = Math.fma(bX - aX, p, aX), dy = Math.fma(bY - aY, p, aY), dz = Math.fma(bZ - aZ, p, aZ);
- if (da < 0.0f) {
- aX = dx; aY = dy; aZ = dz;
- } else {
- bX = dx; bY = dy; bZ = dz;
- }
- }
- da = Math.fma(pzX, aX, Math.fma(pzY, aY, Math.fma(pzZ, aZ, pzW)));
- db = Math.fma(pzX, bX, Math.fma(pzY, bY, Math.fma(pzZ, bZ, pzW)));
- return da >= 0.0f || db >= 0.0f;
- }
-
- public void getCorners(ByteBuffer buffer) {
-
- Vector3f scratch = new Vector3f();
- Vector3f result = new Vector3f();
-
- long addr = MemoryUtil.memAddress(buffer);
- planeIntersect(planes[0], planes[2], planes[4], result, scratch); result.getToAddress(addr);
- planeIntersect(planes[0], planes[2], planes[5], result, scratch); result.getToAddress(addr + 12);
- planeIntersect(planes[0], planes[3], planes[4], result, scratch); result.getToAddress(addr + 24);
- planeIntersect(planes[0], planes[3], planes[5], result, scratch); result.getToAddress(addr + 36);
- planeIntersect(planes[1], planes[2], planes[4], result, scratch); result.getToAddress(addr + 48);
- planeIntersect(planes[1], planes[2], planes[5], result, scratch); result.getToAddress(addr + 60);
- planeIntersect(planes[1], planes[3], planes[4], result, scratch); result.getToAddress(addr + 72);
- planeIntersect(planes[1], planes[3], planes[5], result, scratch); result.getToAddress(addr + 84);
- }
-
- private Vector3f planeIntersect(Vector4f a, Vector4f b, Vector4f c, Vector3f result, Vector3f scratch) {
- // Formula used
- // d1 ( N2 * N3 ) + d2 ( N3 * N1 ) + d3 ( N1 * N2 )
- //P = ---------------------------------------------------------------------
- // N1 . ( N2 * N3 )
- //
- // Note: N refers to the normal, d refers to the displacement. '.' means dot product. '*' means cross product
-
- float f = result.set(b.x, b.y, b.z).cross(c.x, c.y, c.z).dot(a.x, a.y, a.z);
-
- result.set(0);
- scratch.set(b.x, b.y, b.z).cross(c.x, c.y, c.z).mul(a.z);
- result.add(scratch);
- scratch.set(c.x, c.y, c.z).cross(a.x, a.y, a.z).mul(b.z);
- result.add(scratch);
- scratch.set(a.x, a.y, a.z).cross(b.x, b.y, b.z).mul(c.z);
- result.add(scratch);
-
- return result.div(f);
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/FrustumRayBuilder.java b/src/main/java/com/jozufozu/flywheel/util/joml/FrustumRayBuilder.java
deleted file mode 100644
index d2b17a09f..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/FrustumRayBuilder.java
+++ /dev/null
@@ -1,154 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 Kai Burjack
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-/**
- * Provides methods to compute rays through an arbitrary perspective transformation defined by a {@link Matrix4fc}.
- * this
{@link FrustumRayBuilder} with the given {@link Matrix4fc matrix}.
- * origin
.
- *
- * @param origin
- * will hold the perspective origin
- * @return the origin
vector
- */
- public Vector3fc origin(Vector3f origin) {
- origin.x = cx;
- origin.y = cy;
- origin.z = cz;
- return origin;
- }
-
- /**
- * Obtain the normalized direction of a ray starting at the center of the coordinate system and going
- * through the near frustum plane.
- * x
and y
are used to interpolate the generated ray direction
- * from the bottom-left to the top-right frustum corners.
- *
- * @param x
- * the interpolation factor along the left-to-right frustum planes, within [0..1]
- * @param y
- * the interpolation factor along the bottom-to-top frustum planes, within [0..1]
- * @param dir
- * will hold the normalized ray direction
- * @return the dir
vector
- */
- public Vector3fc dir(float x, float y, Vector3f dir) {
- float y1x = nxnyX + (nxpyX - nxnyX) * y;
- float y1y = nxnyY + (nxpyY - nxnyY) * y;
- float y1z = nxnyZ + (nxpyZ - nxnyZ) * y;
- float y2x = pxnyX + (pxpyX - pxnyX) * y;
- float y2y = pxnyY + (pxpyY - pxnyY) * y;
- float y2z = pxnyZ + (pxpyZ - pxnyZ) * y;
- float dx = y1x + (y2x - y1x) * x;
- float dy = y1y + (y2y - y1y) * x;
- float dz = y1z + (y2z - y1z) * x;
- // normalize the vector
- float invLen = Math.invsqrt(dx * dx + dy * dy + dz * dz);
- dir.x = dx * invLen;
- dir.y = dy * invLen;
- dir.z = dz * invLen;
- return dir;
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Math.java b/src/main/java/com/jozufozu/flywheel/util/joml/Math.java
deleted file mode 100644
index b67177d4c..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Math.java
+++ /dev/null
@@ -1,571 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-/**
- * Contains fast approximations of some {@link java.lang.Math} operations.
- * -Djoml.fastmath
.
- *
- *
- * By default, the first algorithm is being used. In order to use the second one, start the JVM with -Djoml.sinLookup
. The lookup table bit length of the second algorithm can also be adjusted
- * for improved accuracy via -Djoml.sinLookup.bits=<n>
, where <n> is the number of bits of the lookup table.
- *
- * @author Kai Burjack
- */
-public class Math {
-
- /*
- * The following implementation of an approximation of sine and cosine was
- * thankfully donated by Riven from http://java-gaming.org/.
- *
- * The code for linear interpolation was gratefully donated by theagentd
- * from the same site.
- */
- public static final double PI = java.lang.Math.PI;
- static final double PI2 = PI * 2.0;
- static final float PI_f = (float) java.lang.Math.PI;
- static final float PI2_f = PI_f * 2.0f;
- static final double PIHalf = PI * 0.5;
- static final float PIHalf_f = (float) (PI * 0.5);
- static final double PI_4 = PI * 0.25;
- static final double PI_INV = 1.0 / PI;
- private static final int lookupBits = Options.SIN_LOOKUP_BITS;
- private static final int lookupTableSize = 1 << lookupBits;
- private static final int lookupTableSizeMinus1 = lookupTableSize - 1;
- private static final int lookupTableSizeWithMargin = lookupTableSize + 1;
- private static final float pi2OverLookupSize = PI2_f / lookupTableSize;
- private static final float lookupSizeOverPi2 = lookupTableSize / PI2_f;
- private static final float sinTable[];
- static {
- if (Options.FASTMATH && Options.SIN_LOOKUP) {
- sinTable = new float[lookupTableSizeWithMargin];
- for (int i = 0; i < lookupTableSizeWithMargin; i++) {
- double d = i * pi2OverLookupSize;
- sinTable[i] = (float) java.lang.Math.sin(d);
- }
- } else {
- sinTable = null;
- }
- }
-
- private static final double c1 = Double.longBitsToDouble(-4628199217061079772L);
- private static final double c2 = Double.longBitsToDouble(4575957461383582011L);
- private static final double c3 = Double.longBitsToDouble(-4671919876300759001L);
- private static final double c4 = Double.longBitsToDouble(4523617214285661942L);
- private static final double c5 = Double.longBitsToDouble(-4730215272828025532L);
- private static final double c6 = Double.longBitsToDouble(4460272573143870633L);
- private static final double c7 = Double.longBitsToDouble(-4797767418267846529L);
-
- /**
- * @author theagentd
- */
- static double sin_theagentd_arith(double x){
- double xi = floor((x + PI_4) * PI_INV);
- double x_ = x - xi * PI;
- double sign = ((int)xi & 1) * -2 + 1;
- double x2 = x_ * x_;
- double sin = x_;
- double tx = x_ * x2;
- sin += tx * c1; tx *= x2;
- sin += tx * c2; tx *= x2;
- sin += tx * c3; tx *= x2;
- sin += tx * c4; tx *= x2;
- sin += tx * c5; tx *= x2;
- sin += tx * c6; tx *= x2;
- sin += tx * c7;
- return sign * sin;
- }
-
- /**
- * Reference: http://www.java-gaming.org/
- */
- static double sin_roquen_arith(double x) {
- double xi = Math.floor((x + PI_4) * PI_INV);
- double x_ = x - xi * PI;
- double sign = ((int)xi & 1) * -2 + 1;
- double x2 = x_ * x_;
-
- // code from sin_theagentd_arith:
- // double sin = x_;
- // double tx = x_ * x2;
- // sin += tx * c1; tx *= x2;
- // sin += tx * c2; tx *= x2;
- // sin += tx * c3; tx *= x2;
- // sin += tx * c4; tx *= x2;
- // sin += tx * c5; tx *= x2;
- // sin += tx * c6; tx *= x2;
- // sin += tx * c7;
- // return sign * sin;
-
- double sin;
- x_ = sign*x_;
- sin = c7;
- sin = sin*x2 + c6;
- sin = sin*x2 + c5;
- sin = sin*x2 + c4;
- sin = sin*x2 + c3;
- sin = sin*x2 + c2;
- sin = sin*x2 + c1;
- return x_ + x_*x2*sin;
- }
-
- private static final double s5 = Double.longBitsToDouble(4523227044276562163L);
- private static final double s4 = Double.longBitsToDouble(-4671934770969572232L);
- private static final double s3 = Double.longBitsToDouble(4575957211482072852L);
- private static final double s2 = Double.longBitsToDouble(-4628199223918090387L);
- private static final double s1 = Double.longBitsToDouble(4607182418589157889L);
-
- /**
- * Reference: http://www.java-gaming.org/
- */
- static double sin_roquen_9(double v) {
- double i = java.lang.Math.rint(v*PI_INV);
- double x = v - i * Math.PI;
- double qs = 1-2*((int)i & 1);
- double x2 = x*x;
- double r;
- x = qs*x;
- r = s5;
- r = r*x2 + s4;
- r = r*x2 + s3;
- r = r*x2 + s2;
- r = r*x2 + s1;
- return x*r;
- }
-
- private static final double k1 = Double.longBitsToDouble(-4628199217061079959L);
- private static final double k2 = Double.longBitsToDouble(4575957461383549981L);
- private static final double k3 = Double.longBitsToDouble(-4671919876307284301L);
- private static final double k4 = Double.longBitsToDouble(4523617213632129738L);
- private static final double k5 = Double.longBitsToDouble(-4730215344060517252L);
- private static final double k6 = Double.longBitsToDouble(4460268259291226124L);
- private static final double k7 = Double.longBitsToDouble(-4798040743777455072L);
-
- /**
- * Reference: http://www.java-gaming.org/
- */
- static double sin_roquen_newk(double v) {
- double i = java.lang.Math.rint(v*PI_INV);
- double x = v - i * Math.PI;
- double qs = 1-2*((int)i & 1);
- double x2 = x*x;
- double r;
- x = qs*x;
- r = k7;
- r = r*x2 + k6;
- r = r*x2 + k5;
- r = r*x2 + k4;
- r = r*x2 + k3;
- r = r*x2 + k2;
- r = r*x2 + k1;
- return x + x*x2*r;
- }
-
- /**
- * Reference: http://www.java-gaming.org/
- */
- static float sin_theagentd_lookup(float rad) {
- float index = rad * lookupSizeOverPi2;
- int ii = (int)java.lang.Math.floor(index);
- float alpha = index - ii;
- int i = ii & lookupTableSizeMinus1;
- float sin1 = sinTable[i];
- float sin2 = sinTable[i + 1];
- return sin1 + (sin2 - sin1) * alpha;
- }
-
- public static float sin(float rad) {
- if (Options.FASTMATH) {
- if (Options.SIN_LOOKUP)
- return sin_theagentd_lookup(rad);
- return (float) sin_roquen_newk(rad);
- }
- return (float) java.lang.Math.sin(rad);
- }
- public static double sin(double rad) {
- if (Options.FASTMATH) {
- if (Options.SIN_LOOKUP)
- return sin_theagentd_lookup((float) rad);
- return sin_roquen_newk(rad);
- }
- return java.lang.Math.sin(rad);
- }
-
- public static float cos(float rad) {
- if (Options.FASTMATH)
- return sin(rad + PIHalf_f);
- return (float) java.lang.Math.cos(rad);
- }
- public static double cos(double rad) {
- if (Options.FASTMATH)
- return sin(rad + PIHalf);
- return java.lang.Math.cos(rad);
- }
-
- public static float cosFromSin(float sin, float angle) {
- if (Options.FASTMATH)
- return sin(angle + PIHalf_f);
- return cosFromSinInternal(sin, angle);
- }
- private static float cosFromSinInternal(float sin, float angle) {
- // sin(x)^2 + cos(x)^2 = 1
- float cos = sqrt(1.0f - sin * sin);
- float a = angle + PIHalf_f;
- float b = a - (int)(a / PI2_f) * PI2_f;
- if (b < 0.0)
- b = PI2_f + b;
- if (b >= PI_f)
- return -cos;
- return cos;
- }
- public static double cosFromSin(double sin, double angle) {
- if (Options.FASTMATH)
- return sin(angle + PIHalf);
- // sin(x)^2 + cos(x)^2 = 1
- double cos = sqrt(1.0 - sin * sin);
- double a = angle + PIHalf;
- double b = a - (int)(a / PI2) * PI2;
- if (b < 0.0)
- b = PI2 + b;
- if (b >= PI)
- return -cos;
- return cos;
- }
-
- /* Other math functions not yet approximated */
-
- public static float sqrt(float r) {
- return (float) java.lang.Math.sqrt(r);
- }
- public static double sqrt(double r) {
- return java.lang.Math.sqrt(r);
- }
-
- public static float invsqrt(float r) {
- return 1.0f / (float) java.lang.Math.sqrt(r);
- }
- public static double invsqrt(double r) {
- return 1.0 / java.lang.Math.sqrt(r);
- }
-
- public static float tan(float r) {
- return (float) java.lang.Math.tan(r);
- }
- public static double tan(double r) {
- return java.lang.Math.tan(r);
- }
-
- public static float acos(float r) {
- return (float) java.lang.Math.acos(r);
- }
- public static double acos(double r) {
- return java.lang.Math.acos(r);
- }
-
- public static float safeAcos(float v) {
- if (v < -1.0f)
- return Math.PI_f;
- else if (v > +1.0f)
- return 0.0f;
- else
- return acos(v);
- }
- public static double safeAcos(double v) {
- if (v < -1.0)
- return Math.PI;
- else if (v > +1.0)
- return 0.0;
- else
- return acos(v);
- }
-
- /**
- * https://math.stackexchange.com/questions/1098487/atan2-faster-approximation/1105038#answer-1105038
- */
- private static double fastAtan2(double y, double x) {
- double ax = x >= 0.0 ? x : -x, ay = y >= 0.0 ? y : -y;
- double a = min(ax, ay) / max(ax, ay);
- double s = a * a;
- double r = ((-0.0464964749 * s + 0.15931422) * s - 0.327622764) * s * a + a;
- if (ay > ax)
- r = 1.57079637 - r;
- if (x < 0.0)
- r = 3.14159274 - r;
- return y >= 0 ? r : -r;
- }
-
- public static float atan2(float y, float x) {
- return (float) java.lang.Math.atan2(y, x);
- }
- public static double atan2(double y, double x) {
- if (Options.FASTMATH)
- return fastAtan2(y, x);
- return java.lang.Math.atan2(y, x);
- }
-
- public static float asin(float r) {
- return (float) java.lang.Math.asin(r);
- }
- public static double asin(double r) {
- return java.lang.Math.asin(r);
- }
- public static float safeAsin(float r) {
- return r <= -1.0f ? -PIHalf_f : r >= 1.0f ? PIHalf_f : asin(r);
- }
- public static double safeAsin(double r) {
- return r <= -1.0 ? -PIHalf : r >= 1.0 ? PIHalf : asin(r);
- }
-
- public static float abs(float r) {
- return java.lang.Math.abs(r);
- }
- public static double abs(double r) {
- return java.lang.Math.abs(r);
- }
-
- static boolean absEqualsOne(float r) {
- return (Float.floatToRawIntBits(r) & 0x7FFFFFFF) == 0x3F800000;
- }
- static boolean absEqualsOne(double r) {
- return (Double.doubleToRawLongBits(r) & 0x7FFFFFFFFFFFFFFFL) == 0x3FF0000000000000L;
- }
-
- public static int abs(int r) {
- return java.lang.Math.abs(r);
- }
-
- public static int max(int x, int y) {
- return java.lang.Math.max(x, y);
- }
-
- public static int min(int x, int y) {
- return java.lang.Math.min(x, y);
- }
-
- public static double min(double a, double b) {
- return a < b ? a : b;
- }
- public static float min(float a, float b) {
- return a < b ? a : b;
- }
-
- public static float max(float a, float b) {
- return a > b ? a : b;
- }
- public static double max(double a, double b) {
- return a > b ? a : b;
- }
-
- public static float clamp(float a, float b, float val){
- return max(a,min(b,val));
- }
- public static double clamp(double a, double b, double val) {
- return max(a,min(b,val));
- }
- public static int clamp(int a, int b, int val) {
- return max(a, min(b, val));
- }
-
- public static float toRadians(float angles) {
- return (float) java.lang.Math.toRadians(angles);
- }
- public static double toRadians(double angles) {
- return java.lang.Math.toRadians(angles);
- }
-
- public static double toDegrees(double angles) {
- return java.lang.Math.toDegrees(angles);
- }
-
- public static double floor(double v) {
- return java.lang.Math.floor(v);
- }
-
- public static float floor(float v) {
- return (float) java.lang.Math.floor(v);
- }
-
- public static double ceil(double v) {
- return java.lang.Math.ceil(v);
- }
-
- public static float ceil(float v) {
- return (float) java.lang.Math.ceil(v);
- }
-
- public static long round(double v) {
- return java.lang.Math.round(v);
- }
-
- public static int round(float v) {
- return java.lang.Math.round(v);
- }
-
- public static double exp(double a) {
- return java.lang.Math.exp(a);
- }
-
- public static boolean isFinite(double d) {
- return abs(d) <= Double.MAX_VALUE;
- }
-
- public static boolean isFinite(float f) {
- return abs(f) <= Float.MAX_VALUE;
- }
-
- public static float fma(float a, float b, float c) {
- if (Runtime.HAS_Math_fma)
- return java.lang.Math.fma(a, b, c);
- return a * b + c;
- }
-
- public static double fma(double a, double b, double c) {
- if (Runtime.HAS_Math_fma)
- return java.lang.Math.fma(a, b, c);
- return a * b + c;
- }
-
- public static int roundUsing(float v, int mode) {
- switch (mode) {
- case RoundingMode.TRUNCATE:
- return (int) v;
- case RoundingMode.CEILING:
- return (int) java.lang.Math.ceil(v);
- case RoundingMode.FLOOR:
- return (int) java.lang.Math.floor(v);
- case RoundingMode.HALF_DOWN:
- return roundHalfDown(v);
- case RoundingMode.HALF_UP:
- return roundHalfUp(v);
- case RoundingMode.HALF_EVEN:
- return roundHalfEven(v);
- default:
- throw new UnsupportedOperationException();
- }
- }
- public static int roundUsing(double v, int mode) {
- switch (mode) {
- case RoundingMode.TRUNCATE:
- return (int) v;
- case RoundingMode.CEILING:
- return (int) java.lang.Math.ceil(v);
- case RoundingMode.FLOOR:
- return (int) java.lang.Math.floor(v);
- case RoundingMode.HALF_DOWN:
- return roundHalfDown(v);
- case RoundingMode.HALF_UP:
- return roundHalfUp(v);
- case RoundingMode.HALF_EVEN:
- return roundHalfEven(v);
- default:
- throw new UnsupportedOperationException();
- }
- }
-
- public static float lerp(float a, float b, float t){
- return Math.fma(b - a, t, a);
- }
- public static double lerp(double a, double b, double t) {
- return Math.fma(b - a, t, a);
- }
-
- public static float biLerp(float q00, float q10, float q01, float q11, float tx, float ty) {
- float lerpX1 = lerp(q00, q10, tx);
- float lerpX2 = lerp(q01, q11, tx);
- return lerp(lerpX1, lerpX2, ty);
- }
-
- public static double biLerp(double q00, double q10, double q01, double q11, double tx, double ty) {
- double lerpX1 = lerp(q00, q10, tx);
- double lerpX2 = lerp(q01, q11, tx);
- return lerp(lerpX1, lerpX2, ty);
- }
-
- public static float triLerp(float q000, float q100, float q010, float q110, float q001, float q101, float q011, float q111, float tx, float ty, float tz) {
- float x00 = lerp(q000, q100, tx);
- float x10 = lerp(q010, q110, tx);
- float x01 = lerp(q001, q101, tx);
- float x11 = lerp(q011, q111, tx);
- float y0 = lerp(x00, x10, ty);
- float y1 = lerp(x01, x11, ty);
- return lerp(y0, y1, tz);
- }
-
- public static double triLerp(double q000, double q100, double q010, double q110, double q001, double q101, double q011, double q111, double tx, double ty, double tz) {
- double x00 = lerp(q000, q100, tx);
- double x10 = lerp(q010, q110, tx);
- double x01 = lerp(q001, q101, tx);
- double x11 = lerp(q011, q111, tx);
- double y0 = lerp(x00, x10, ty);
- double y1 = lerp(x01, x11, ty);
- return lerp(y0, y1, tz);
- }
-
- public static int roundHalfEven(float v) {
- return (int) java.lang.Math.rint(v);
- }
- public static int roundHalfDown(float v) {
- return (v > 0) ? (int) java.lang.Math.ceil(v - 0.5d) : (int) java.lang.Math.floor(v + 0.5d);
- }
- public static int roundHalfUp(float v) {
- return (v > 0) ? (int) java.lang.Math.floor(v + 0.5d) : (int) java.lang.Math.ceil(v - 0.5d);
- }
-
- public static int roundHalfEven(double v) {
- return (int) java.lang.Math.rint(v);
- }
- public static int roundHalfDown(double v) {
- return (v > 0) ? (int) java.lang.Math.ceil(v - 0.5d) : (int) java.lang.Math.floor(v + 0.5d);
- }
- public static int roundHalfUp(double v) {
- return (v > 0) ? (int) java.lang.Math.floor(v + 0.5d) : (int) java.lang.Math.ceil(v - 0.5d);
- }
-
- public static double random() {
- return java.lang.Math.random();
- }
-
- public static double signum(double v) {
- return java.lang.Math.signum(v);
- }
- public static float signum(float v) {
- return java.lang.Math.signum(v);
- }
- public static int signum(int v) {
- int r;
- r = Integer.signum(v);
- return r;
- }
- public static int signum(long v) {
- int r;
- r = Long.signum(v);
- return r;
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix3f.java b/src/main/java/com/jozufozu/flywheel/util/joml/Matrix3f.java
deleted file mode 100644
index f30068383..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix3f.java
+++ /dev/null
@@ -1,4788 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 Richard Greenlees
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-
-
-/**
- * Contains the definition of a 3x3 matrix of floats, and associated functions to transform
- * it. The matrix is column-major to match OpenGL's interpretation, and it looks like this:
- *
- * m01 m11 m21
- * m02 m12 m22
- *
- * @author Richard Greenlees
- * @author Kai Burjack
- */
-public class Matrix3f implements Externalizable, Cloneable, Matrix3fc {
-
- private static final long serialVersionUID = 1L;
-
- public float m00, m01, m02;
- public float m10, m11, m12;
- public float m20, m21, m22;
-
- /**
- * Create a new {@link Matrix3f} and set it to {@link #identity() identity}.
- */
- public Matrix3f() {
- m00 = 1.0f;
- m11 = 1.0f;
- m22 = 1.0f;
- }
-
- /**
- * Create a new {@link Matrix3f} and make it a copy of the given matrix.
- *
- * @param mat
- * the {@link Matrix3fc} to copy the values from
- */
- public Matrix3f(Matrix3fc mat) {
- set(mat);
- }
-
- /**
- * Create a new {@link Matrix3f} and make it a copy of the upper left 3x3 of the given {@link Matrix4fc}.
- *
- * @param mat
- * the {@link Matrix4fc} to copy the values from
- */
- public Matrix3f(Matrix4fc mat) {
- set(mat);
- }
-
- /**
- * Create a new 3x3 matrix using the supplied float values. The order of the parameter is column-major,
- * so the first three parameters specify the three elements of the first column.
- *
- * @param m00
- * the value of m00
- * @param m01
- * the value of m01
- * @param m02
- * the value of m02
- * @param m10
- * the value of m10
- * @param m11
- * the value of m11
- * @param m12
- * the value of m12
- * @param m20
- * the value of m20
- * @param m21
- * the value of m21
- * @param m22
- * the value of m22
- */
- public Matrix3f(float m00, float m01, float m02,
- float m10, float m11, float m12,
- float m20, float m21, float m22) {
- this.m00 = m00;
- this.m01 = m01;
- this.m02 = m02;
- this.m10 = m10;
- this.m11 = m11;
- this.m12 = m12;
- this.m20 = m20;
- this.m21 = m21;
- this.m22 = m22;
- }
-
- /**
- * Create a new {@link Matrix3f} by reading its 9 float components from the given {@link FloatBuffer}
- * at the buffer's current position.
- * m
.
- *
- * @param m
- * the matrix to copy the elements from
- * @return this
- */
- public Matrix3f set(Matrix3fc m) {
- return
- _m00(m.m00()).
- _m01(m.m01()).
- _m02(m.m02()).
- _m10(m.m10()).
- _m11(m.m11()).
- _m12(m.m12()).
- _m20(m.m20()).
- _m21(m.m21()).
- _m22(m.m22());
- }
-
- /**
- * Store the values of the transpose of the given matrix m
into this
matrix.
- *
- * @param m
- * the matrix to copy the transposed values from
- * @return this
- */
- public Matrix3f setTransposed(Matrix3fc m) {
- float nm10 = m.m01(), nm12 = m.m21();
- float nm20 = m.m02(), nm21 = m.m12();
- return this
- ._m00(m.m00())._m01(m.m10())._m02(m.m20())
- ._m10(nm10)._m11(m.m11())._m12(nm12)
- ._m20(nm20)._m21(nm21)._m22(m.m22());
- }
-
- /**
- * Set the elements of this matrix to the upper left 3x3 of the given {@link Matrix4fc}.
- *
- * @param mat
- * the {@link Matrix4fc} to copy the values from
- * @return this
- */
- public Matrix3f set(Matrix4fc mat) {
- m00 = mat.m00();
- m01 = mat.m01();
- m02 = mat.m02();
- m10 = mat.m10();
- m11 = mat.m11();
- m12 = mat.m12();
- m20 = mat.m20();
- m21 = mat.m21();
- m22 = mat.m22();
- return this;
- }
-
- /**
- * Set this matrix to be equivalent to the rotation specified by the given {@link AxisAngle4f}.
- *
- * @param axisAngle
- * the {@link AxisAngle4f}
- * @return this
- */
- public Matrix3f set(AxisAngle4f axisAngle) {
- float x = axisAngle.x;
- float y = axisAngle.y;
- float z = axisAngle.z;
- float angle = axisAngle.angle;
- float invLength = Math.invsqrt(x*x + y*y + z*z);
- x *= invLength;
- y *= invLength;
- z *= invLength;
- float s = Math.sin(angle);
- float c = Math.cosFromSin(s, angle);
- float omc = 1.0f - c;
- m00 = c + x*x*omc;
- m11 = c + y*y*omc;
- m22 = c + z*z*omc;
- float tmp1 = x*y*omc;
- float tmp2 = z*s;
- m10 = tmp1 - tmp2;
- m01 = tmp1 + tmp2;
- tmp1 = x*z*omc;
- tmp2 = y*s;
- m20 = tmp1 + tmp2;
- m02 = tmp1 - tmp2;
- tmp1 = y*z*omc;
- tmp2 = x*s;
- m21 = tmp1 - tmp2;
- m12 = tmp1 + tmp2;
- return this;
- }
-
- /**
- * Set this matrix to be equivalent to the rotation - and possibly scaling - specified by the given {@link Quaternionfc}.
- * rotation(q)
- * right
matrix.
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param right
- * the right operand of the matrix multiplication
- * @return this
- */
- public Matrix3f mul(Matrix3fc right) {
- return mul(right, this);
- }
-
- public Matrix3f mul(Matrix3fc right, Matrix3f dest) {
- float nm00 = Math.fma(m00, right.m00(), Math.fma(m10, right.m01(), m20 * right.m02()));
- float nm01 = Math.fma(m01, right.m00(), Math.fma(m11, right.m01(), m21 * right.m02()));
- float nm02 = Math.fma(m02, right.m00(), Math.fma(m12, right.m01(), m22 * right.m02()));
- float nm10 = Math.fma(m00, right.m10(), Math.fma(m10, right.m11(), m20 * right.m12()));
- float nm11 = Math.fma(m01, right.m10(), Math.fma(m11, right.m11(), m21 * right.m12()));
- float nm12 = Math.fma(m02, right.m10(), Math.fma(m12, right.m11(), m22 * right.m12()));
- float nm20 = Math.fma(m00, right.m20(), Math.fma(m10, right.m21(), m20 * right.m22()));
- float nm21 = Math.fma(m01, right.m20(), Math.fma(m11, right.m21(), m21 * right.m22()));
- float nm22 = Math.fma(m02, right.m20(), Math.fma(m12, right.m21(), m22 * right.m22()));
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m20 = nm20;
- dest.m21 = nm21;
- dest.m22 = nm22;
- return dest;
- }
-
- /**
- * Pre-multiply this matrix by the supplied left
matrix and store the result in this
.
- * M
is this
matrix and L
the left
matrix,
- * then the new matrix will be L * M
. So when transforming a
- * vector v
with the new matrix by using L * M * v
, the
- * transformation of this
matrix will be applied first!
- *
- * @param left
- * the left operand of the matrix multiplication
- * @return this
- */
- public Matrix3f mulLocal(Matrix3fc left) {
- return mulLocal(left, this);
- }
-
- public Matrix3f mulLocal(Matrix3fc left, Matrix3f dest) {
- float nm00 = left.m00() * m00 + left.m10() * m01 + left.m20() * m02;
- float nm01 = left.m01() * m00 + left.m11() * m01 + left.m21() * m02;
- float nm02 = left.m02() * m00 + left.m12() * m01 + left.m22() * m02;
- float nm10 = left.m00() * m10 + left.m10() * m11 + left.m20() * m12;
- float nm11 = left.m01() * m10 + left.m11() * m11 + left.m21() * m12;
- float nm12 = left.m02() * m10 + left.m12() * m11 + left.m22() * m12;
- float nm20 = left.m00() * m20 + left.m10() * m21 + left.m20() * m22;
- float nm21 = left.m01() * m20 + left.m11() * m21 + left.m21() * m22;
- float nm22 = left.m02() * m20 + left.m12() * m21 + left.m22() * m22;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m20 = nm20;
- dest.m21 = nm21;
- dest.m22 = nm22;
- return dest;
- }
-
- /**
- * Set the values within this matrix to the supplied float values. The result looks like this:
- *
- * m01, m11, m21
- * m02, m12, m22
- *
- * @param m00
- * the new value of m00
- * @param m01
- * the new value of m01
- * @param m02
- * the new value of m02
- * @param m10
- * the new value of m10
- * @param m11
- * the new value of m11
- * @param m12
- * the new value of m12
- * @param m20
- * the new value of m20
- * @param m21
- * the new value of m21
- * @param m22
- * the new value of m22
- * @return this
- */
- public Matrix3f set(float m00, float m01, float m02,
- float m10, float m11, float m12,
- float m20, float m21, float m22) {
- this.m00 = m00;
- this.m01 = m01;
- this.m02 = m02;
- this.m10 = m10;
- this.m11 = m11;
- this.m12 = m12;
- this.m20 = m20;
- this.m21 = m21;
- this.m22 = m22;
- return this;
- }
-
- /**
- * Set the values in this matrix based on the supplied float array. The result looks like this:
- *
- * 1, 4, 7
- * 2, 5, 8
- *
- * This method only uses the first 9 values, all others are ignored.
- *
- * @param m
- * the array to read the matrix values from
- * @return this
- */
- public Matrix3f set(float m[]) {
- MemUtil.INSTANCE.copy(m, 0, this);
- return this;
- }
-
- /**
- * Set the three columns of this matrix to the supplied vectors, respectively.
- *
- * @param col0
- * the first column
- * @param col1
- * the second column
- * @param col2
- * the third column
- * @return this
- */
- public Matrix3f set(Vector3fc col0, Vector3fc col1, Vector3fc col2) {
- this.m00 = col0.x();
- this.m01 = col0.y();
- this.m02 = col0.z();
- this.m10 = col1.x();
- this.m11 = col1.y();
- this.m12 = col1.z();
- this.m20 = col2.x();
- this.m21 = col2.y();
- this.m22 = col2.z();
- return this;
- }
-
- public float determinant() {
- return (m00 * m11 - m01 * m10) * m22
- + (m02 * m10 - m00 * m12) * m21
- + (m01 * m12 - m02 * m11) * m20;
- }
-
- /**
- * Invert this matrix.
- *
- * @return this
- */
- public Matrix3f invert() {
- return invert(this);
- }
-
- public Matrix3f invert(Matrix3f dest) {
- float a = Math.fma(m00, m11, -m01 * m10);
- float b = Math.fma(m02, m10, -m00 * m12);
- float c = Math.fma(m01, m12, -m02 * m11);
- float d = Math.fma(a, m22, Math.fma(b, m21, c * m20));
- float s = 1.0f / d;
- float nm00 = Math.fma(m11, m22, -m21 * m12) * s;
- float nm01 = Math.fma(m21, m02, -m01 * m22) * s;
- float nm02 = c * s;
- float nm10 = Math.fma(m20, m12, -m10 * m22) * s;
- float nm11 = Math.fma(m00, m22, -m20 * m02) * s;
- float nm12 = b * s;
- float nm20 = Math.fma(m10, m21, -m20 * m11) * s;
- float nm21 = Math.fma(m20, m01, -m00 * m21) * s;
- float nm22 = a * s;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m20 = nm20;
- dest.m21 = nm21;
- dest.m22 = nm22;
- return dest;
- }
-
- /**
- * Transpose this matrix.
- *
- * @return this
- */
- public Matrix3f transpose() {
- return transpose(this);
- }
-
- public Matrix3f transpose(Matrix3f dest) {
- return dest.set(m00, m10, m20,
- m01, m11, m21,
- m02, m12, m22);
- }
-
- /**
- * Return a string representation of this matrix.
- * 0.000E0;-
".
- *
- * @return the string representation
- */
- public String toString() {
- String str = toString(Options.NUMBER_FORMAT);
- StringBuffer res = new StringBuffer();
- int eIndex = Integer.MIN_VALUE;
- for (int i = 0; i < str.length(); i++) {
- char c = str.charAt(i);
- if (c == 'E') {
- eIndex = i;
- } else if (c == ' ' && eIndex == i - 1) {
- // workaround Java 1.4 DecimalFormat bug
- res.append('+');
- continue;
- } else if (Character.isDigit(c) && eIndex == i - 1) {
- res.append('+');
- }
- res.append(c);
- }
- return res.toString();
- }
-
- /**
- * Return a string representation of this matrix by formatting the matrix elements with the given {@link NumberFormat}.
- *
- * @param formatter
- * the {@link NumberFormat} used to format the matrix values with
- * @return the string representation
- */
- public String toString(NumberFormat formatter) {
- return Runtime.format(m00, formatter) + " " + Runtime.format(m10, formatter) + " " + Runtime.format(m20, formatter) + "\n"
- + Runtime.format(m01, formatter) + " " + Runtime.format(m11, formatter) + " " + Runtime.format(m21, formatter) + "\n"
- + Runtime.format(m02, formatter) + " " + Runtime.format(m12, formatter) + " " + Runtime.format(m22, formatter) + "\n";
- }
-
- /**
- * Get the current values of this
matrix and store them into
- * dest
.
- * xyz.x
,
- * xyz.y
and xyz.z
factors, respectively.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- *
- * @param xyz
- * the factors of the x, y and z component, respectively
- * @return this
- */
- public Matrix3f scale(Vector3fc xyz) {
- return scale(xyz.x(), xyz.y(), xyz.z(), this);
- }
-
- public Matrix3f scale(float x, float y, float z, Matrix3f dest) {
- // scale matrix elements:
- // m00 = x, m11 = y, m22 = z
- // all others = 0
- dest.m00 = m00 * x;
- dest.m01 = m01 * x;
- dest.m02 = m02 * x;
- dest.m10 = m10 * y;
- dest.m11 = m11 * y;
- dest.m12 = m12 * y;
- dest.m20 = m20 * z;
- dest.m21 = m21 * z;
- dest.m22 = m22 * z;
- return dest;
- }
-
- /**
- * Apply scaling to this matrix by scaling the base axes by the given x,
- * y and z factors.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
- * , the scaling will be applied first!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @param z
- * the factor of the z component
- * @return this
- */
- public Matrix3f scale(float x, float y, float z) {
- return scale(x, y, z, this);
- }
-
- public Matrix3f scale(float xyz, Matrix3f dest) {
- return scale(xyz, xyz, xyz, dest);
- }
-
- /**
- * Apply scaling to this matrix by uniformly scaling all base axes by the given xyz
factor.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
- * , the scaling will be applied first!
- *
- * @see #scale(float, float, float)
- *
- * @param xyz
- * the factor for all components
- * @return this
- */
- public Matrix3f scale(float xyz) {
- return scale(xyz, xyz, xyz);
- }
-
- public Matrix3f scaleLocal(float x, float y, float z, Matrix3f dest) {
- float nm00 = x * m00;
- float nm01 = y * m01;
- float nm02 = z * m02;
- float nm10 = x * m10;
- float nm11 = y * m11;
- float nm12 = z * m12;
- float nm20 = x * m20;
- float nm21 = y * m21;
- float nm22 = z * m22;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m20 = nm20;
- dest.m21 = nm21;
- dest.m22 = nm22;
- return dest;
- }
-
- /**
- * Pre-multiply scaling to this matrix by scaling the base axes by the given x,
- * y and z factors.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
, the
- * scaling will be applied last!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @param z
- * the factor of the z component
- * @return this
- */
- public Matrix3f scaleLocal(float x, float y, float z) {
- return scaleLocal(x, y, z, this);
- }
-
- /**
- * Set this matrix to be a simple scale matrix, which scales all axes uniformly by the given factor.
- * xyz.x
, xyz.y
and xyz.z
respectively.
- * axis
vector needs to be a unit vector.
- * angleX
radians about the X axis, followed by a rotation
- * of angleY
radians about the Y axis and followed by a rotation of angleZ
radians about the Z axis.
- * rotationX(angleX).rotateY(angleY).rotateZ(angleZ)
- *
- * @param angleX
- * the angle to rotate about X
- * @param angleY
- * the angle to rotate about Y
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix3f rotationXYZ(float angleX, float angleY, float angleZ) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinX = -sinX;
- float m_sinY = -sinY;
- float m_sinZ = -sinZ;
-
- // rotateX
- float nm11 = cosX;
- float nm12 = sinX;
- float nm21 = m_sinX;
- float nm22 = cosX;
- // rotateY
- float nm00 = cosY;
- float nm01 = nm21 * m_sinY;
- float nm02 = nm22 * m_sinY;
- m20 = sinY;
- m21 = nm21 * cosY;
- m22 = nm22 * cosY;
- // rotateZ
- m00 = nm00 * cosZ;
- m01 = nm01 * cosZ + nm11 * sinZ;
- m02 = nm02 * cosZ + nm12 * sinZ;
- m10 = nm00 * m_sinZ;
- m11 = nm01 * m_sinZ + nm11 * cosZ;
- m12 = nm02 * m_sinZ + nm12 * cosZ;
- return this;
- }
-
- /**
- * Set this matrix to a rotation of angleZ
radians about the Z axis, followed by a rotation
- * of angleY
radians about the Y axis and followed by a rotation of angleX
radians about the X axis.
- * rotationZ(angleZ).rotateY(angleY).rotateX(angleX)
- *
- * @param angleZ
- * the angle to rotate about Z
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @return this
- */
- public Matrix3f rotationZYX(float angleZ, float angleY, float angleX) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinZ = -sinZ;
- float m_sinY = -sinY;
- float m_sinX = -sinX;
-
- // rotateZ
- float nm00 = cosZ;
- float nm01 = sinZ;
- float nm10 = m_sinZ;
- float nm11 = cosZ;
- // rotateY
- float nm20 = nm00 * sinY;
- float nm21 = nm01 * sinY;
- float nm22 = cosY;
- m00 = nm00 * cosY;
- m01 = nm01 * cosY;
- m02 = m_sinY;
- // rotateX
- m10 = nm10 * cosX + nm20 * sinX;
- m11 = nm11 * cosX + nm21 * sinX;
- m12 = nm22 * sinX;
- m20 = nm10 * m_sinX + nm20 * cosX;
- m21 = nm11 * m_sinX + nm21 * cosX;
- m22 = nm22 * cosX;
- return this;
- }
-
- /**
- * Set this matrix to a rotation of angleY
radians about the Y axis, followed by a rotation
- * of angleX
radians about the X axis and followed by a rotation of angleZ
radians about the Z axis.
- * rotationY(angleY).rotateX(angleX).rotateZ(angleZ)
- *
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix3f rotationYXZ(float angleY, float angleX, float angleZ) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinY = -sinY;
- float m_sinX = -sinX;
- float m_sinZ = -sinZ;
-
- // rotateY
- float nm00 = cosY;
- float nm02 = m_sinY;
- float nm20 = sinY;
- float nm22 = cosY;
- // rotateX
- float nm10 = nm20 * sinX;
- float nm11 = cosX;
- float nm12 = nm22 * sinX;
- m20 = nm20 * cosX;
- m21 = m_sinX;
- m22 = nm22 * cosX;
- // rotateZ
- m00 = nm00 * cosZ + nm10 * sinZ;
- m01 = nm11 * sinZ;
- m02 = nm02 * cosZ + nm12 * sinZ;
- m10 = nm00 * m_sinZ + nm10 * cosZ;
- m11 = nm11 * cosZ;
- m12 = nm02 * m_sinZ + nm12 * cosZ;
- return this;
- }
-
- /**
- * Set this matrix to the rotation - and possibly scaling - transformation of the given {@link Quaternionfc}.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
- * , the rotation will be applied first!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
- * , the rotation will be applied first!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
- * , the rotation will be applied first!
- * angles.x
radians about the X axis, followed by a rotation of angles.y
radians about the Y axis and
- * followed by a rotation of angles.z
radians about the Z axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateX(angles.x).rotateY(angles.y).rotateZ(angles.z)
- *
- * @param angles
- * the Euler angles
- * @return this
- */
- public Matrix3f rotateXYZ(Vector3f angles) {
- return rotateXYZ(angles.x, angles.y, angles.z);
- }
-
- /**
- * Apply rotation of angleX
radians about the X axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleZ
radians about the Z axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateX(angleX).rotateY(angleY).rotateZ(angleZ)
- *
- * @param angleX
- * the angle to rotate about X
- * @param angleY
- * the angle to rotate about Y
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix3f rotateXYZ(float angleX, float angleY, float angleZ) {
- return rotateXYZ(angleX, angleY, angleZ, this);
- }
-
- public Matrix3f rotateXYZ(float angleX, float angleY, float angleZ, Matrix3f dest) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinX = -sinX;
- float m_sinY = -sinY;
- float m_sinZ = -sinZ;
-
- // rotateX
- float nm10 = m10 * cosX + m20 * sinX;
- float nm11 = m11 * cosX + m21 * sinX;
- float nm12 = m12 * cosX + m22 * sinX;
- float nm20 = m10 * m_sinX + m20 * cosX;
- float nm21 = m11 * m_sinX + m21 * cosX;
- float nm22 = m12 * m_sinX + m22 * cosX;
- // rotateY
- float nm00 = m00 * cosY + nm20 * m_sinY;
- float nm01 = m01 * cosY + nm21 * m_sinY;
- float nm02 = m02 * cosY + nm22 * m_sinY;
- dest.m20 = m00 * sinY + nm20 * cosY;
- dest.m21 = m01 * sinY + nm21 * cosY;
- dest.m22 = m02 * sinY + nm22 * cosY;
- // rotateZ
- dest.m00 = nm00 * cosZ + nm10 * sinZ;
- dest.m01 = nm01 * cosZ + nm11 * sinZ;
- dest.m02 = nm02 * cosZ + nm12 * sinZ;
- dest.m10 = nm00 * m_sinZ + nm10 * cosZ;
- dest.m11 = nm01 * m_sinZ + nm11 * cosZ;
- dest.m12 = nm02 * m_sinZ + nm12 * cosZ;
- return dest;
- }
-
- /**
- * Apply rotation of angles.z
radians about the Z axis, followed by a rotation of angles.y
radians about the Y axis and
- * followed by a rotation of angles.x
radians about the X axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateZ(angles.z).rotateY(angles.y).rotateX(angles.x)
- *
- * @param angles
- * the Euler angles
- * @return this
- */
- public Matrix3f rotateZYX(Vector3f angles) {
- return rotateZYX(angles.z, angles.y, angles.x);
- }
-
- /**
- * Apply rotation of angleZ
radians about the Z axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleX
radians about the X axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateZ(angleZ).rotateY(angleY).rotateX(angleX)
- *
- * @param angleZ
- * the angle to rotate about Z
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @return this
- */
- public Matrix3f rotateZYX(float angleZ, float angleY, float angleX) {
- return rotateZYX(angleZ, angleY, angleX, this);
- }
-
- public Matrix3f rotateZYX(float angleZ, float angleY, float angleX, Matrix3f dest) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinZ = -sinZ;
- float m_sinY = -sinY;
- float m_sinX = -sinX;
-
- // rotateZ
- float nm00 = m00 * cosZ + m10 * sinZ;
- float nm01 = m01 * cosZ + m11 * sinZ;
- float nm02 = m02 * cosZ + m12 * sinZ;
- float nm10 = m00 * m_sinZ + m10 * cosZ;
- float nm11 = m01 * m_sinZ + m11 * cosZ;
- float nm12 = m02 * m_sinZ + m12 * cosZ;
- // rotateY
- float nm20 = nm00 * sinY + m20 * cosY;
- float nm21 = nm01 * sinY + m21 * cosY;
- float nm22 = nm02 * sinY + m22 * cosY;
- dest.m00 = nm00 * cosY + m20 * m_sinY;
- dest.m01 = nm01 * cosY + m21 * m_sinY;
- dest.m02 = nm02 * cosY + m22 * m_sinY;
- // rotateX
- dest.m10 = nm10 * cosX + nm20 * sinX;
- dest.m11 = nm11 * cosX + nm21 * sinX;
- dest.m12 = nm12 * cosX + nm22 * sinX;
- dest.m20 = nm10 * m_sinX + nm20 * cosX;
- dest.m21 = nm11 * m_sinX + nm21 * cosX;
- dest.m22 = nm12 * m_sinX + nm22 * cosX;
- return dest;
- }
-
- /**
- * Apply rotation of angles.y
radians about the Y axis, followed by a rotation of angles.x
radians about the X axis and
- * followed by a rotation of angles.z
radians about the Z axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateY(angles.y).rotateX(angles.x).rotateZ(angles.z)
- *
- * @param angles
- * the Euler angles
- * @return this
- */
- public Matrix3f rotateYXZ(Vector3f angles) {
- return rotateYXZ(angles.y, angles.x, angles.z);
- }
-
- /**
- * Apply rotation of angleY
radians about the Y axis, followed by a rotation of angleX
radians about the X axis and
- * followed by a rotation of angleZ
radians about the Z axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateY(angleY).rotateX(angleX).rotateZ(angleZ)
- *
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix3f rotateYXZ(float angleY, float angleX, float angleZ) {
- return rotateYXZ(angleY, angleX, angleZ, this);
- }
-
- public Matrix3f rotateYXZ(float angleY, float angleX, float angleZ, Matrix3f dest) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinY = -sinY;
- float m_sinX = -sinX;
- float m_sinZ = -sinZ;
-
- // rotateY
- float nm20 = m00 * sinY + m20 * cosY;
- float nm21 = m01 * sinY + m21 * cosY;
- float nm22 = m02 * sinY + m22 * cosY;
- float nm00 = m00 * cosY + m20 * m_sinY;
- float nm01 = m01 * cosY + m21 * m_sinY;
- float nm02 = m02 * cosY + m22 * m_sinY;
- // rotateX
- float nm10 = m10 * cosX + nm20 * sinX;
- float nm11 = m11 * cosX + nm21 * sinX;
- float nm12 = m12 * cosX + nm22 * sinX;
- dest.m20 = m10 * m_sinX + nm20 * cosX;
- dest.m21 = m11 * m_sinX + nm21 * cosX;
- dest.m22 = m12 * m_sinX + nm22 * cosX;
- // rotateZ
- dest.m00 = nm00 * cosZ + nm10 * sinZ;
- dest.m01 = nm01 * cosZ + nm11 * sinZ;
- dest.m02 = nm02 * cosZ + nm12 * sinZ;
- dest.m10 = nm00 * m_sinZ + nm10 * cosZ;
- dest.m11 = nm01 * m_sinZ + nm11 * cosZ;
- dest.m12 = nm02 * m_sinZ + nm12 * cosZ;
- return dest;
- }
-
- /**
- * Apply rotation to this matrix by rotating the given amount of radians
- * about the given axis specified as x, y and z components.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
- * , the rotation will be applied first!
- * (x, y, z)
axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * (x, y, z)
axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be Q * M
. So when transforming a
- * vector v
with the new matrix by using Q * M * v
,
- * the quaternion rotation will be applied last!
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be Q * M
. So when transforming a
- * vector v
with the new matrix by using Q * M * v
,
- * the quaternion rotation will be applied last!
- * M
is this
matrix and A
the rotation matrix obtained from the given {@link AxisAngle4f},
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the {@link AxisAngle4f} rotation will be applied first!
- * dest
.
- * M
is this
matrix and A
the rotation matrix obtained from the given {@link AxisAngle4f},
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the {@link AxisAngle4f} rotation will be applied first!
- * M
is this
matrix and A
the rotation matrix obtained from the given angle and axis,
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the axis-angle rotation will be applied first!
- * dest
.
- * M
is this
matrix and A
the rotation matrix obtained from the given angle and axis,
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the axis-angle rotation will be applied first!
- * -z
point along dir
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * -z
point along dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * -z
point along dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * -z
point along dir
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * -z
- * point along dir
.
- * -z
- * point along dir
.
- * row
index, starting with 0
.
- *
- * @param row
- * the row index in [0..2]
- * @param src
- * the row components to set
- * @return this
- * @throws IndexOutOfBoundsException if row
is not in [0..2]
- */
- public Matrix3f setRow(int row, Vector3fc src) throws IndexOutOfBoundsException {
- return setRow(row, src.x(), src.y(), src.z());
- }
-
- /**
- * Set the row at the given row
index, starting with 0
.
- *
- * @param row
- * the row index in [0..2]
- * @param x
- * the first element in the row
- * @param y
- * the second element in the row
- * @param z
- * the third element in the row
- * @return this
- * @throws IndexOutOfBoundsException if row
is not in [0..2]
- */
- public Matrix3f setRow(int row, float x, float y, float z) throws IndexOutOfBoundsException {
- switch (row) {
- case 0:
- this.m00 = x;
- this.m10 = y;
- this.m20 = z;
- break;
- case 1:
- this.m01 = x;
- this.m11 = y;
- this.m21 = z;
- break;
- case 2:
- this.m02 = x;
- this.m12 = y;
- this.m22 = z;
- break;
- default:
- throw new IndexOutOfBoundsException();
- }
- return this;
- }
-
- public Vector3f getColumn(int column, Vector3f dest) throws IndexOutOfBoundsException {
- switch (column) {
- case 0:
- return dest.set(m00, m01, m02);
- case 1:
- return dest.set(m10, m11, m12);
- case 2:
- return dest.set(m20, m21, m22);
- default:
- throw new IndexOutOfBoundsException();
- }
- }
-
- /**
- * Set the column at the given column
index, starting with 0
.
- *
- * @param column
- * the column index in [0..2]
- * @param src
- * the column components to set
- * @return this
- * @throws IndexOutOfBoundsException if column
is not in [0..2]
- */
- public Matrix3f setColumn(int column, Vector3fc src) throws IndexOutOfBoundsException {
- return setColumn(column, src.x(), src.y(), src.z());
- }
-
- /**
- * Set the column at the given column
index, starting with 0
.
- *
- * @param column
- * the column index in [0..2]
- * @param x
- * the first element in the column
- * @param y
- * the second element in the column
- * @param z
- * the third element in the column
- * @return this
- * @throws IndexOutOfBoundsException if column
is not in [0..2]
- */
- public Matrix3f setColumn(int column, float x, float y, float z) throws IndexOutOfBoundsException {
- switch (column) {
- case 0:
- this.m00 = x;
- this.m01 = y;
- this.m02 = z;
- break;
- case 1:
- this.m10 = x;
- this.m11 = y;
- this.m12 = z;
- break;
- case 2:
- this.m20 = x;
- this.m21 = y;
- this.m22 = z;
- break;
- default:
- throw new IndexOutOfBoundsException();
- }
- return this;
- }
-
- public float get(int column, int row) {
- return MemUtil.INSTANCE.get(this, column, row);
- }
-
- /**
- * Set the matrix element at the given column and row to the specified value.
- *
- * @param column
- * the colum index in [0..2]
- * @param row
- * the row index in [0..2]
- * @param value
- * the value
- * @return this
- */
- public Matrix3f set(int column, int row, float value) {
- return MemUtil.INSTANCE.set(this, column, row, value);
- }
-
- public float getRowColumn(int row, int column) {
- return MemUtil.INSTANCE.get(this, column, row);
- }
-
- /**
- * Set the matrix element at the given row and column to the specified value.
- *
- * @param row
- * the row index in [0..2]
- * @param column
- * the colum index in [0..2]
- * @param value
- * the value
- * @return this
- */
- public Matrix3f setRowColumn(int row, int column, float value) {
- return MemUtil.INSTANCE.set(this, column, row, value);
- }
-
- /**
- * Set this
matrix to its own normal matrix.
- * m
is the transpose of the inverse of m
.
- * this
is an orthogonal matrix or a matrix whose columns are orthogonal vectors,
- * then this method need not be invoked, since in that case this
itself is its normal matrix.
- * In this case, use {@link #set(Matrix3fc)} to set a given Matrix3f to this matrix.
- *
- * @see #set(Matrix3fc)
- *
- * @return this
- */
- public Matrix3f normal() {
- return normal(this);
- }
-
- /**
- * Compute a normal matrix from this
matrix and store it into dest
.
- * m
is the transpose of the inverse of m
.
- * this
is an orthogonal matrix or a matrix whose columns are orthogonal vectors,
- * then this method need not be invoked, since in that case this
itself is its normal matrix.
- * In this case, use {@link #set(Matrix3fc)} to set a given Matrix3f to this matrix.
- *
- * @see #set(Matrix3fc)
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f normal(Matrix3f dest) {
- float m00m11 = m00 * m11;
- float m01m10 = m01 * m10;
- float m02m10 = m02 * m10;
- float m00m12 = m00 * m12;
- float m01m12 = m01 * m12;
- float m02m11 = m02 * m11;
- float det = (m00m11 - m01m10) * m22 + (m02m10 - m00m12) * m21 + (m01m12 - m02m11) * m20;
- float s = 1.0f / det;
- /* Invert and transpose in one go */
- float nm00 = (m11 * m22 - m21 * m12) * s;
- float nm01 = (m20 * m12 - m10 * m22) * s;
- float nm02 = (m10 * m21 - m20 * m11) * s;
- float nm10 = (m21 * m02 - m01 * m22) * s;
- float nm11 = (m00 * m22 - m20 * m02) * s;
- float nm12 = (m20 * m01 - m00 * m21) * s;
- float nm20 = (m01m12 - m02m11) * s;
- float nm21 = (m02m10 - m00m12) * s;
- float nm22 = (m00m11 - m01m10) * s;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- dest.m20 = nm20;
- dest.m21 = nm21;
- dest.m22 = nm22;
- return dest;
- }
-
- /**
- * Compute the cofactor matrix of this
.
- * this
and store it into dest
.
- * this
matrix with the given other
matrix.
- *
- * @param other
- * the other matrix to exchange the values with
- * @return this
- */
- public Matrix3f swap(Matrix3f other) {
- MemUtil.INSTANCE.swap(this, other);
- return this;
- }
-
- /**
- * Component-wise add this
and other
.
- *
- * @param other
- * the other addend
- * @return this
- */
- public Matrix3f add(Matrix3fc other) {
- return add(other, this);
- }
-
- public Matrix3f add(Matrix3fc other, Matrix3f dest) {
- dest.m00 = m00 + other.m00();
- dest.m01 = m01 + other.m01();
- dest.m02 = m02 + other.m02();
- dest.m10 = m10 + other.m10();
- dest.m11 = m11 + other.m11();
- dest.m12 = m12 + other.m12();
- dest.m20 = m20 + other.m20();
- dest.m21 = m21 + other.m21();
- dest.m22 = m22 + other.m22();
- return dest;
- }
-
- /**
- * Component-wise subtract subtrahend
from this
.
- *
- * @param subtrahend
- * the subtrahend
- * @return this
- */
- public Matrix3f sub(Matrix3fc subtrahend) {
- return sub(subtrahend, this);
- }
-
- public Matrix3f sub(Matrix3fc subtrahend, Matrix3f dest) {
- dest.m00 = m00 - subtrahend.m00();
- dest.m01 = m01 - subtrahend.m01();
- dest.m02 = m02 - subtrahend.m02();
- dest.m10 = m10 - subtrahend.m10();
- dest.m11 = m11 - subtrahend.m11();
- dest.m12 = m12 - subtrahend.m12();
- dest.m20 = m20 - subtrahend.m20();
- dest.m21 = m21 - subtrahend.m21();
- dest.m22 = m22 - subtrahend.m22();
- return dest;
- }
-
- /**
- * Component-wise multiply this
by other
.
- *
- * @param other
- * the other matrix
- * @return this
- */
- public Matrix3f mulComponentWise(Matrix3fc other) {
- return mulComponentWise(other, this);
- }
-
- public Matrix3f mulComponentWise(Matrix3fc other, Matrix3f dest) {
- dest.m00 = m00 * other.m00();
- dest.m01 = m01 * other.m01();
- dest.m02 = m02 * other.m02();
- dest.m10 = m10 * other.m10();
- dest.m11 = m11 * other.m11();
- dest.m12 = m12 * other.m12();
- dest.m20 = m20 * other.m20();
- dest.m21 = m21 * other.m21();
- dest.m22 = m22 * other.m22();
- return dest;
- }
-
- /**
- * Set this matrix to a skew-symmetric matrix using the following layout:
- *
- * 0, a, -b
- * -a, 0, c
- * b, -c, 0
- *
- *
- * Reference: https://en.wikipedia.org
- *
- * @param a
- * the value used for the matrix elements m01 and m10
- * @param b
- * the value used for the matrix elements m02 and m20
- * @param c
- * the value used for the matrix elements m12 and m21
- * @return this
- */
- public Matrix3f setSkewSymmetric(float a, float b, float c) {
- m00 = m11 = m22 = 0;
- m01 = -a;
- m02 = b;
- m10 = a;
- m12 = -c;
- m20 = -b;
- m21 = c;
- return this;
- }
-
- /**
- * Linearly interpolate this
and other
using the given interpolation factor t
- * and store the result in this
.
- * t
is 0.0
then the result is this
. If the interpolation factor is 1.0
- * then the result is other
.
- *
- * @param other
- * the other matrix
- * @param t
- * the interpolation factor between 0.0 and 1.0
- * @return this
- */
- public Matrix3f lerp(Matrix3fc other, float t) {
- return lerp(other, t, this);
- }
-
- public Matrix3f lerp(Matrix3fc other, float t, Matrix3f dest) {
- dest.m00 = Math.fma(other.m00() - m00, t, m00);
- dest.m01 = Math.fma(other.m01() - m01, t, m01);
- dest.m02 = Math.fma(other.m02() - m02, t, m02);
- dest.m10 = Math.fma(other.m10() - m10, t, m10);
- dest.m11 = Math.fma(other.m11() - m11, t, m11);
- dest.m12 = Math.fma(other.m12() - m12, t, m12);
- dest.m20 = Math.fma(other.m20() - m20, t, m20);
- dest.m21 = Math.fma(other.m21() - m21, t, m21);
- dest.m22 = Math.fma(other.m22() - m22, t, m22);
- return dest;
- }
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with direction
- * and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mul(new Matrix3f().lookAlong(new Vector3f(dir).negate(), up).invert(), dest)
- *
- * @see #rotateTowards(float, float, float, float, float, float, Matrix3f)
- * @see #rotationTowards(Vector3fc, Vector3fc)
- *
- * @param direction
- * the direction to rotate towards
- * @param up
- * the model's up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotateTowards(Vector3fc direction, Vector3fc up, Matrix3f dest) {
- return rotateTowards(direction.x(), direction.y(), direction.z(), up.x(), up.y(), up.z(), dest);
- }
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with direction
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mul(new Matrix3f().lookAlong(new Vector3f(dir).negate(), up).invert())
- *
- * @see #rotateTowards(float, float, float, float, float, float)
- * @see #rotationTowards(Vector3fc, Vector3fc)
- *
- * @param direction
- * the direction to orient towards
- * @param up
- * the up vector
- * @return this
- */
- public Matrix3f rotateTowards(Vector3fc direction, Vector3fc up) {
- return rotateTowards(direction.x(), direction.y(), direction.z(), up.x(), up.y(), up.z(), this);
- }
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with direction
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mul(new Matrix3f().lookAlong(-dirX, -dirY, -dirZ, upX, upY, upZ).invert())
- *
- * @see #rotateTowards(Vector3fc, Vector3fc)
- * @see #rotationTowards(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to rotate towards
- * @param dirY
- * the y-coordinate of the direction to rotate towards
- * @param dirZ
- * the z-coordinate of the direction to rotate towards
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix3f rotateTowards(float dirX, float dirY, float dirZ, float upX, float upY, float upZ) {
- return rotateTowards(dirX, dirY, dirZ, upX, upY, upZ, this);
- }
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mul(new Matrix3f().lookAlong(-dirX, -dirY, -dirZ, upX, upY, upZ).invert(), dest)
- *
- * @see #rotateTowards(Vector3fc, Vector3fc)
- * @see #rotationTowards(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to rotate towards
- * @param dirY
- * the y-coordinate of the direction to rotate towards
- * @param dirZ
- * the z-coordinate of the direction to rotate towards
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f rotateTowards(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix3f dest) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- float ndirX = dirX * invDirLength;
- float ndirY = dirY * invDirLength;
- float ndirZ = dirZ * invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * ndirZ - upZ * ndirY;
- leftY = upZ * ndirX - upX * ndirZ;
- leftZ = upX * ndirY - upY * ndirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = ndirY * leftZ - ndirZ * leftY;
- float upnY = ndirZ * leftX - ndirX * leftZ;
- float upnZ = ndirX * leftY - ndirY * leftX;
- float rm00 = leftX;
- float rm01 = leftY;
- float rm02 = leftZ;
- float rm10 = upnX;
- float rm11 = upnY;
- float rm12 = upnZ;
- float rm20 = ndirX;
- float rm21 = ndirY;
- float rm22 = ndirZ;
- float nm00 = m00 * rm00 + m10 * rm01 + m20 * rm02;
- float nm01 = m01 * rm00 + m11 * rm01 + m21 * rm02;
- float nm02 = m02 * rm00 + m12 * rm01 + m22 * rm02;
- float nm10 = m00 * rm10 + m10 * rm11 + m20 * rm12;
- float nm11 = m01 * rm10 + m11 * rm11 + m21 * rm12;
- float nm12 = m02 * rm10 + m12 * rm11 + m22 * rm12;
- dest.m20 = m00 * rm20 + m10 * rm21 + m20 * rm22;
- dest.m21 = m01 * rm20 + m11 * rm21 + m21 * rm22;
- dest.m22 = m02 * rm20 + m12 * rm21 + m22 * rm22;
- dest.m00 = nm00;
- dest.m01 = nm01;
- dest.m02 = nm02;
- dest.m10 = nm10;
- dest.m11 = nm11;
- dest.m12 = nm12;
- return dest;
- }
-
- /**
- * Set this matrix to a model transformation for a right-handed coordinate system,
- * that aligns the local -z
axis with center - eye
.
- * setLookAlong(new Vector3f(dir).negate(), up).invert()
- *
- * @see #rotationTowards(Vector3fc, Vector3fc)
- * @see #rotateTowards(float, float, float, float, float, float)
- *
- * @param dir
- * the direction to orient the local -z axis towards
- * @param up
- * the up vector
- * @return this
- */
- public Matrix3f rotationTowards(Vector3fc dir, Vector3fc up) {
- return rotationTowards(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z());
- }
-
- /**
- * Set this matrix to a model transformation for a right-handed coordinate system,
- * that aligns the local -z
axis with center - eye
.
- * setLookAlong(-dirX, -dirY, -dirZ, upX, upY, upZ).invert()
- *
- * @see #rotateTowards(Vector3fc, Vector3fc)
- * @see #rotationTowards(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to rotate towards
- * @param dirY
- * the y-coordinate of the direction to rotate towards
- * @param dirZ
- * the z-coordinate of the direction to rotate towards
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix3f rotationTowards(float dirX, float dirY, float dirZ, float upX, float upY, float upZ) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- float ndirX = dirX * invDirLength;
- float ndirY = dirY * invDirLength;
- float ndirZ = dirZ * invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * ndirZ - upZ * ndirY;
- leftY = upZ * ndirX - upX * ndirZ;
- leftZ = upX * ndirY - upY * ndirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = ndirY * leftZ - ndirZ * leftY;
- float upnY = ndirZ * leftX - ndirX * leftZ;
- float upnZ = ndirX * leftY - ndirY * leftX;
- this.m00 = leftX;
- this.m01 = leftY;
- this.m02 = leftZ;
- this.m10 = upnX;
- this.m11 = upnY;
- this.m12 = upnZ;
- this.m20 = ndirX;
- this.m21 = ndirY;
- this.m22 = ndirZ;
- return this;
- }
-
- public Vector3f getEulerAnglesZYX(Vector3f dest) {
- dest.x = Math.atan2(m12, m22);
- dest.y = Math.atan2(-m02, Math.sqrt(1.0f - m02 * m02));
- dest.z = Math.atan2(m01, m00);
- return dest;
- }
-
- public Vector3f getEulerAnglesXYZ(Vector3f dest) {
- dest.x = Math.atan2(-m21, m22);
- dest.y = Math.atan2(m20, Math.sqrt(1.0f - m20 * m20));
- dest.z = Math.atan2(-m10, m00);
- return dest;
- }
-
- /**
- * Apply an oblique projection transformation to this matrix with the given values for a
and
- * b
.
- * M
is this
matrix and O
the oblique transformation matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * oblique transformation will be applied first!
- *
- * x' = x + a*z
- * y' = y + a*z
- * z' = z
- *
- * or in matrix form:
- *
- * 1 0 a
- * 0 1 b
- * 0 0 1
- *
- *
- * @param a
- * the value for the z factor that applies to x
- * @param b
- * the value for the z factor that applies to y
- * @return this
- */
- public Matrix3f obliqueZ(float a, float b) {
- this.m20 = m00 * a + m10 * b + m20;
- this.m21 = m01 * a + m11 * b + m21;
- this.m22 = m02 * a + m12 * b + m22;
- return this;
- }
-
- /**
- * Apply an oblique projection transformation to this matrix with the given values for a
and
- * b
and store the result in dest
.
- * M
is this
matrix and O
the oblique transformation matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * oblique transformation will be applied first!
- *
- * x' = x + a*z
- * y' = y + a*z
- * z' = z
- *
- * or in matrix form:
- *
- * 1 0 a
- * 0 1 b
- * 0 0 1
- *
- *
- * @param a
- * the value for the z factor that applies to x
- * @param b
- * the value for the z factor that applies to y
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f obliqueZ(float a, float b, Matrix3f dest) {
- dest.m00 = m00;
- dest.m01 = m01;
- dest.m02 = m02;
- dest.m10 = m10;
- dest.m11 = m11;
- dest.m12 = m12;
- dest.m20 = m00 * a + m10 * b + m20;
- dest.m21 = m01 * a + m11 * b + m21;
- dest.m22 = m02 * a + m12 * b + m22;
- return dest;
- }
-
- public Matrix3f reflect(float nx, float ny, float nz, Matrix3f dest) {
- float da = nx + nx, db = ny + ny, dc = nz + nz;
- float rm00 = 1.0f - da * nx;
- float rm01 = -da * ny;
- float rm02 = -da * nz;
- float rm10 = -db * nx;
- float rm11 = 1.0f - db * ny;
- float rm12 = -db * nz;
- float rm20 = -dc * nx;
- float rm21 = -dc * ny;
- float rm22 = 1.0f - dc * nz;
- float nm00 = m00 * rm00 + m10 * rm01 + m20 * rm02;
- float nm01 = m01 * rm00 + m11 * rm01 + m21 * rm02;
- float nm02 = m02 * rm00 + m12 * rm01 + m22 * rm02;
- float nm10 = m00 * rm10 + m10 * rm11 + m20 * rm12;
- float nm11 = m01 * rm10 + m11 * rm11 + m21 * rm12;
- float nm12 = m02 * rm10 + m12 * rm11 + m22 * rm12;
- return dest
- ._m20(m00 * rm20 + m10 * rm21 + m20 * rm22)
- ._m21(m01 * rm20 + m11 * rm21 + m21 * rm22)
- ._m22(m02 * rm20 + m12 * rm21 + m22 * rm22)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12);
- }
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects through the given plane
- * specified via the plane normal.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param nx
- * the x-coordinate of the plane normal
- * @param ny
- * the y-coordinate of the plane normal
- * @param nz
- * the z-coordinate of the plane normal
- * @return this
- */
- public Matrix3f reflect(float nx, float ny, float nz) {
- return reflect(nx, ny, nz, this);
- }
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects through the given plane
- * specified via the plane normal.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param normal
- * the plane normal
- * @return this
- */
- public Matrix3f reflect(Vector3fc normal) {
- return reflect(normal.x(), normal.y(), normal.z());
- }
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects about a plane
- * specified via the plane orientation.
- * (0, 0, 1)
. So, if the given {@link Quaternionfc} is
- * the identity (does not apply any additional rotation), the reflection plane will be z=0
.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param orientation
- * the plane orientation
- * @return this
- */
- public Matrix3f reflect(Quaternionfc orientation) {
- return reflect(orientation, this);
- }
-
- public Matrix3f reflect(Quaternionfc orientation, Matrix3f dest) {
- float num1 = orientation.x() + orientation.x();
- float num2 = orientation.y() + orientation.y();
- float num3 = orientation.z() + orientation.z();
- float normalX = orientation.x() * num3 + orientation.w() * num2;
- float normalY = orientation.y() * num3 - orientation.w() * num1;
- float normalZ = 1.0f - (orientation.x() * num1 + orientation.y() * num2);
- return reflect(normalX, normalY, normalZ, dest);
- }
-
- public Matrix3f reflect(Vector3fc normal, Matrix3f dest) {
- return reflect(normal.x(), normal.y(), normal.z(), dest);
- }
-
- /**
- * Set this matrix to a mirror/reflection transformation that reflects through the given plane
- * specified via the plane normal.
- *
- * @param nx
- * the x-coordinate of the plane normal
- * @param ny
- * the y-coordinate of the plane normal
- * @param nz
- * the z-coordinate of the plane normal
- * @return this
- */
- public Matrix3f reflection(float nx, float ny, float nz) {
- float da = nx + nx, db = ny + ny, dc = nz + nz;
- this._m00(1.0f - da * nx);
- this._m01(-da * ny);
- this._m02(-da * nz);
- this._m10(-db * nx);
- this._m11(1.0f - db * ny);
- this._m12(-db * nz);
- this._m20(-dc * nx);
- this._m21(-dc * ny);
- this._m22(1.0f - dc * nz);
- return this;
- }
-
- /**
- * Set this matrix to a mirror/reflection transformation that reflects through the given plane
- * specified via the plane normal.
- *
- * @param normal
- * the plane normal
- * @return this
- */
- public Matrix3f reflection(Vector3fc normal) {
- return reflection(normal.x(), normal.y(), normal.z());
- }
-
- /**
- * Set this matrix to a mirror/reflection transformation that reflects through a plane
- * specified via the plane orientation.
- * (0, 0, 1)
. So, if the given {@link Quaternionfc} is
- * the identity (does not apply any additional rotation), the reflection plane will be z=0
, offset by the given point
.
- *
- * @param orientation
- * the plane orientation
- * @return this
- */
- public Matrix3f reflection(Quaternionfc orientation) {
- float num1 = orientation.x() + orientation.x();
- float num2 = orientation.y() + orientation.y();
- float num3 = orientation.z() + orientation.z();
- float normalX = orientation.x() * num3 + orientation.w() * num2;
- float normalY = orientation.y() * num3 - orientation.w() * num1;
- float normalZ = 1.0f - (orientation.x() * num1 + orientation.y() * num2);
- return reflection(normalX, normalY, normalZ);
- }
-
- public boolean isFinite() {
- return Math.isFinite(m00) && Math.isFinite(m01) && Math.isFinite(m02) &&
- Math.isFinite(m10) && Math.isFinite(m11) && Math.isFinite(m12) &&
- Math.isFinite(m20) && Math.isFinite(m21) && Math.isFinite(m22);
- }
-
- public float quadraticFormProduct(float x, float y, float z) {
- float Axx = m00 * x + m10 * y + m20 * z;
- float Axy = m01 * x + m11 * y + m21 * z;
- float Axz = m02 * x + m12 * y + m22 * z;
- return x * Axx + y * Axy + z * Axz;
- }
-
- public float quadraticFormProduct(Vector3fc v) {
- return quadraticFormProduct(v.x(), v.y(), v.z());
- }
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 0 1
- * 0 1 0
- *
- *
- * @return this
- */
- public Matrix3f mapXZY() {
- return mapXZY(this);
- }
- public Matrix3f mapXZY(Matrix3f dest) {
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(m00)._m01(m01)._m02(m02)._m10(m20)._m11(m21)._m12(m22)._m20(m10)._m21(m11)._m22(m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 0 -1
- * 0 1 0
- *
- *
- * @return this
- */
- public Matrix3f mapXZnY() {
- return mapXZnY(this);
- }
- public Matrix3f mapXZnY(Matrix3f dest) {
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(m00)._m01(m01)._m02(m02)._m10(m20)._m11(m21)._m12(m22)._m20(-m10)._m21(-m11)._m22(-m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 -1 0
- * 0 0 -1
- *
- *
- * @return this
- */
- public Matrix3f mapXnYnZ() {
- return mapXnYnZ(this);
- }
- public Matrix3f mapXnYnZ(Matrix3f dest) {
- return dest._m00(m00)._m01(m01)._m02(m02)._m10(-m10)._m11(-m11)._m12(-m12)._m20(-m20)._m21(-m21)._m22(-m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 0 1
- * 0 -1 0
- *
- *
- * @return this
- */
- public Matrix3f mapXnZY() {
- return mapXnZY(this);
- }
- public Matrix3f mapXnZY(Matrix3f dest) {
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(m00)._m01(m01)._m02(m02)._m10(-m20)._m11(-m21)._m12(-m22)._m20(m10)._m21(m11)._m22(m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 0 -1
- * 0 -1 0
- *
- *
- * @return this
- */
- public Matrix3f mapXnZnY() {
- return mapXnZnY(this);
- }
- public Matrix3f mapXnZnY(Matrix3f dest) {
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(m00)._m01(m01)._m02(m02)._m10(-m20)._m11(-m21)._m12(-m22)._m20(-m10)._m21(-m11)._m22(-m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 1 0 0
- * 0 0 1
- *
- *
- * @return this
- */
- public Matrix3f mapYXZ() {
- return mapYXZ(this);
- }
- public Matrix3f mapYXZ(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m10)._m01(m11)._m02(m12)._m10(m00)._m11(m01)._m12(m02)._m20(m20)._m21(m21)._m22(m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 1 0 0
- * 0 0 -1
- *
- *
- * @return this
- */
- public Matrix3f mapYXnZ() {
- return mapYXnZ(this);
- }
- public Matrix3f mapYXnZ(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m10)._m01(m11)._m02(m12)._m10(m00)._m11(m01)._m12(m02)._m20(-m20)._m21(-m21)._m22(-m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 1 0 0
- * 0 1 0
- *
- *
- * @return this
- */
- public Matrix3f mapYZX() {
- return mapYZX(this);
- }
- public Matrix3f mapYZX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m10)._m01(m11)._m02(m12)._m10(m20)._m11(m21)._m12(m22)._m20(m00)._m21(m01)._m22(m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 1 0 0
- * 0 1 0
- *
- *
- * @return this
- */
- public Matrix3f mapYZnX() {
- return mapYZnX(this);
- }
- public Matrix3f mapYZnX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m10)._m01(m11)._m02(m12)._m10(m20)._m11(m21)._m12(m22)._m20(-m00)._m21(-m01)._m22(-m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 1 0 0
- * 0 0 1
- *
- *
- * @return this
- */
- public Matrix3f mapYnXZ() {
- return mapYnXZ(this);
- }
- public Matrix3f mapYnXZ(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m10)._m01(m11)._m02(m12)._m10(-m00)._m11(-m01)._m12(-m02)._m20(m20)._m21(m21)._m22(m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 1 0 0
- * 0 0 -1
- *
- *
- * @return this
- */
- public Matrix3f mapYnXnZ() {
- return mapYnXnZ(this);
- }
- public Matrix3f mapYnXnZ(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m10)._m01(m11)._m02(m12)._m10(-m00)._m11(-m01)._m12(-m02)._m20(-m20)._m21(-m21)._m22(-m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 1 0 0
- * 0 -1 0
- *
- *
- * @return this
- */
- public Matrix3f mapYnZX() {
- return mapYnZX(this);
- }
- public Matrix3f mapYnZX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m10)._m01(m11)._m02(m12)._m10(-m20)._m11(-m21)._m12(-m22)._m20(m00)._m21(m01)._m22(m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 1 0 0
- * 0 -1 0
- *
- *
- * @return this
- */
- public Matrix3f mapYnZnX() {
- return mapYnZnX(this);
- }
- public Matrix3f mapYnZnX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m10)._m01(m11)._m02(m12)._m10(-m20)._m11(-m21)._m12(-m22)._m20(-m00)._m21(-m01)._m22(-m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 0 0 1
- * 1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapZXY() {
- return mapZXY(this);
- }
- public Matrix3f mapZXY(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(m20)._m01(m21)._m02(m22)._m10(m00)._m11(m01)._m12(m02)._m20(m10)._m21(m11)._m22(m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 0 0 -1
- * 1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapZXnY() {
- return mapZXnY(this);
- }
- public Matrix3f mapZXnY(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(m20)._m01(m21)._m02(m22)._m10(m00)._m11(m01)._m12(m02)._m20(-m10)._m21(-m11)._m22(-m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 0 1 0
- * 1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapZYX() {
- return mapZYX(this);
- }
- public Matrix3f mapZYX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m20)._m01(m21)._m02(m22)._m10(m10)._m11(m11)._m12(m12)._m20(m00)._m21(m01)._m22(m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 0 1 0
- * 1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapZYnX() {
- return mapZYnX(this);
- }
- public Matrix3f mapZYnX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m20)._m01(m21)._m02(m22)._m10(m10)._m11(m11)._m12(m12)._m20(-m00)._m21(-m01)._m22(-m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 0 0 1
- * 1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapZnXY() {
- return mapZnXY(this);
- }
- public Matrix3f mapZnXY(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(m20)._m01(m21)._m02(m22)._m10(-m00)._m11(-m01)._m12(-m02)._m20(m10)._m21(m11)._m22(m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 0 0 -1
- * 1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapZnXnY() {
- return mapZnXnY(this);
- }
- public Matrix3f mapZnXnY(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(m20)._m01(m21)._m02(m22)._m10(-m00)._m11(-m01)._m12(-m02)._m20(-m10)._m21(-m11)._m22(-m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 0 -1 0
- * 1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapZnYX() {
- return mapZnYX(this);
- }
- public Matrix3f mapZnYX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m20)._m01(m21)._m02(m22)._m10(-m10)._m11(-m11)._m12(-m12)._m20(m00)._m21(m01)._m22(m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 0 -1 0
- * 1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapZnYnX() {
- return mapZnYnX(this);
- }
- public Matrix3f mapZnYnX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(m20)._m01(m21)._m02(m22)._m10(-m10)._m11(-m11)._m12(-m12)._m20(-m00)._m21(-m01)._m22(-m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 1 0
- * 0 0 -1
- *
- *
- * @return this
- */
- public Matrix3f mapnXYnZ() {
- return mapnXYnZ(this);
- }
- public Matrix3f mapnXYnZ(Matrix3f dest) {
- return dest._m00(-m00)._m01(-m01)._m02(-m02)._m10(m10)._m11(m11)._m12(m12)._m20(-m20)._m21(-m21)._m22(-m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 0 1
- * 0 1 0
- *
- *
- * @return this
- */
- public Matrix3f mapnXZY() {
- return mapnXZY(this);
- }
- public Matrix3f mapnXZY(Matrix3f dest) {
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(-m00)._m01(-m01)._m02(-m02)._m10(m20)._m11(m21)._m12(m22)._m20(m10)._m21(m11)._m22(m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 0 -1
- * 0 1 0
- *
- *
- * @return this
- */
- public Matrix3f mapnXZnY() {
- return mapnXZnY(this);
- }
- public Matrix3f mapnXZnY(Matrix3f dest) {
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(-m00)._m01(-m01)._m02(-m02)._m10(m20)._m11(m21)._m12(m22)._m20(-m10)._m21(-m11)._m22(-m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 -1 0
- * 0 0 1
- *
- *
- * @return this
- */
- public Matrix3f mapnXnYZ() {
- return mapnXnYZ(this);
- }
- public Matrix3f mapnXnYZ(Matrix3f dest) {
- return dest._m00(-m00)._m01(-m01)._m02(-m02)._m10(-m10)._m11(-m11)._m12(-m12)._m20(m20)._m21(m21)._m22(m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 -1 0
- * 0 0 -1
- *
- *
- * @return this
- */
- public Matrix3f mapnXnYnZ() {
- return mapnXnYnZ(this);
- }
- public Matrix3f mapnXnYnZ(Matrix3f dest) {
- return dest._m00(-m00)._m01(-m01)._m02(-m02)._m10(-m10)._m11(-m11)._m12(-m12)._m20(-m20)._m21(-m21)._m22(-m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 0 1
- * 0 -1 0
- *
- *
- * @return this
- */
- public Matrix3f mapnXnZY() {
- return mapnXnZY(this);
- }
- public Matrix3f mapnXnZY(Matrix3f dest) {
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(-m00)._m01(-m01)._m02(-m02)._m10(-m20)._m11(-m21)._m12(-m22)._m20(m10)._m21(m11)._m22(m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 0 -1
- * 0 -1 0
- *
- *
- * @return this
- */
- public Matrix3f mapnXnZnY() {
- return mapnXnZnY(this);
- }
- public Matrix3f mapnXnZnY(Matrix3f dest) {
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(-m00)._m01(-m01)._m02(-m02)._m10(-m20)._m11(-m21)._m12(-m22)._m20(-m10)._m21(-m11)._m22(-m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * -1 0 0
- * 0 0 1
- *
- *
- * @return this
- */
- public Matrix3f mapnYXZ() {
- return mapnYXZ(this);
- }
- public Matrix3f mapnYXZ(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m10)._m01(-m11)._m02(-m12)._m10(m00)._m11(m01)._m12(m02)._m20(m20)._m21(m21)._m22(m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * -1 0 0
- * 0 0 -1
- *
- *
- * @return this
- */
- public Matrix3f mapnYXnZ() {
- return mapnYXnZ(this);
- }
- public Matrix3f mapnYXnZ(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m10)._m01(-m11)._m02(-m12)._m10(m00)._m11(m01)._m12(m02)._m20(-m20)._m21(-m21)._m22(-m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * -1 0 0
- * 0 1 0
- *
- *
- * @return this
- */
- public Matrix3f mapnYZX() {
- return mapnYZX(this);
- }
- public Matrix3f mapnYZX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m10)._m01(-m11)._m02(-m12)._m10(m20)._m11(m21)._m12(m22)._m20(m00)._m21(m01)._m22(m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * -1 0 0
- * 0 1 0
- *
- *
- * @return this
- */
- public Matrix3f mapnYZnX() {
- return mapnYZnX(this);
- }
- public Matrix3f mapnYZnX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m10)._m01(-m11)._m02(-m12)._m10(m20)._m11(m21)._m12(m22)._m20(-m00)._m21(-m01)._m22(-m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * -1 0 0
- * 0 0 1
- *
- *
- * @return this
- */
- public Matrix3f mapnYnXZ() {
- return mapnYnXZ(this);
- }
- public Matrix3f mapnYnXZ(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m10)._m01(-m11)._m02(-m12)._m10(-m00)._m11(-m01)._m12(-m02)._m20(m20)._m21(m21)._m22(m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * -1 0 0
- * 0 0 -1
- *
- *
- * @return this
- */
- public Matrix3f mapnYnXnZ() {
- return mapnYnXnZ(this);
- }
- public Matrix3f mapnYnXnZ(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m10)._m01(-m11)._m02(-m12)._m10(-m00)._m11(-m01)._m12(-m02)._m20(-m20)._m21(-m21)._m22(-m22);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * -1 0 0
- * 0 -1 0
- *
- *
- * @return this
- */
- public Matrix3f mapnYnZX() {
- return mapnYnZX(this);
- }
- public Matrix3f mapnYnZX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m10)._m01(-m11)._m02(-m12)._m10(-m20)._m11(-m21)._m12(-m22)._m20(m00)._m21(m01)._m22(m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * -1 0 0
- * 0 -1 0
- *
- *
- * @return this
- */
- public Matrix3f mapnYnZnX() {
- return mapnYnZnX(this);
- }
- public Matrix3f mapnYnZnX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m10)._m01(-m11)._m02(-m12)._m10(-m20)._m11(-m21)._m12(-m22)._m20(-m00)._m21(-m01)._m22(-m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 0 0 1
- * -1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapnZXY() {
- return mapnZXY(this);
- }
- public Matrix3f mapnZXY(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(-m20)._m01(-m21)._m02(-m22)._m10(m00)._m11(m01)._m12(m02)._m20(m10)._m21(m11)._m22(m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 0 0 -1
- * -1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapnZXnY() {
- return mapnZXnY(this);
- }
- public Matrix3f mapnZXnY(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(-m20)._m01(-m21)._m02(-m22)._m10(m00)._m11(m01)._m12(m02)._m20(-m10)._m21(-m11)._m22(-m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 0 1 0
- * -1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapnZYX() {
- return mapnZYX(this);
- }
- public Matrix3f mapnZYX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m20)._m01(-m21)._m02(-m22)._m10(m10)._m11(m11)._m12(m12)._m20(m00)._m21(m01)._m22(m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 0 1 0
- * -1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapnZYnX() {
- return mapnZYnX(this);
- }
- public Matrix3f mapnZYnX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m20)._m01(-m21)._m02(-m22)._m10(m10)._m11(m11)._m12(m12)._m20(-m00)._m21(-m01)._m22(-m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 0 0 1
- * -1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapnZnXY() {
- return mapnZnXY(this);
- }
- public Matrix3f mapnZnXY(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(-m20)._m01(-m21)._m02(-m22)._m10(-m00)._m11(-m01)._m12(-m02)._m20(m10)._m21(m11)._m22(m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 0 0 -1
- * -1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapnZnXnY() {
- return mapnZnXnY(this);
- }
- public Matrix3f mapnZnXnY(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- float m10 = this.m10, m11 = this.m11, m12 = this.m12;
- return dest._m00(-m20)._m01(-m21)._m02(-m22)._m10(-m00)._m11(-m01)._m12(-m02)._m20(-m10)._m21(-m11)._m22(-m12);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 0 -1 0
- * -1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapnZnYX() {
- return mapnZnYX(this);
- }
- public Matrix3f mapnZnYX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m20)._m01(-m21)._m02(-m22)._m10(-m10)._m11(-m11)._m12(-m12)._m20(m00)._m21(m01)._m22(m02);
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 0 -1 0
- * -1 0 0
- *
- *
- * @return this
- */
- public Matrix3f mapnZnYnX() {
- return mapnZnYnX(this);
- }
- public Matrix3f mapnZnYnX(Matrix3f dest) {
- float m00 = this.m00, m01 = this.m01, m02 = this.m02;
- return dest._m00(-m20)._m01(-m21)._m02(-m22)._m10(-m10)._m11(-m11)._m12(-m12)._m20(-m00)._m21(-m01)._m22(-m02);
- }
-
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 1 0
- * 0 0 1
- *
- *
- * @return this
- */
- public Matrix3f negateX() {
- return _m00(-m00)._m01(-m01)._m02(-m02);
- }
- public Matrix3f negateX(Matrix3f dest) {
- return dest._m00(-m00)._m01(-m01)._m02(-m02)._m10(m10)._m11(m11)._m12(m12)._m20(m20)._m21(m21)._m22(m22);
- }
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 -1 0
- * 0 0 1
- *
- *
- * @return this
- */
- public Matrix3f negateY() {
- return _m10(-m10)._m11(-m11)._m12(-m12);
- }
- public Matrix3f negateY(Matrix3f dest) {
- return dest._m00(m00)._m01(m01)._m02(m02)._m10(-m10)._m11(-m11)._m12(-m12)._m20(m20)._m21(m21)._m22(m22);
- }
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 1 0
- * 0 0 -1
- *
- *
- * @return this
- */
- public Matrix3f negateZ() {
- return _m20(-m20)._m21(-m21)._m22(-m22);
- }
- public Matrix3f negateZ(Matrix3f dest) {
- return dest._m00(m00)._m01(m01)._m02(m02)._m10(m10)._m11(m11)._m12(m12)._m20(-m20)._m21(-m21)._m22(-m22);
- }
-
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix3fStack.java b/src/main/java/com/jozufozu/flywheel/util/joml/Matrix3fStack.java
deleted file mode 100644
index f2484fc61..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix3fStack.java
+++ /dev/null
@@ -1,186 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2018-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-/**
- * A stack of many {@link Matrix3f} instances. This resembles the matrix stack known from legacy OpenGL.
- * this
- * {@link Matrix3f}
- */
- public Matrix3fStack(int stackSize) {
- if (stackSize < 1) {
- throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
- }
- mats = new Matrix3f[stackSize - 1];
- // Allocate all matrices up front to keep the promise of being "allocation-free"
- for (int i = 0; i < mats.length; i++) {
- mats[i] = new Matrix3f();
- }
- }
-
- /**
- * Do not invoke manually! Only meant for serialization.
- * right
matrix and store the result in dest
.
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param right
- * the right operand of the matrix multiplication
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mul(Matrix3fc right, Matrix3f dest);
-
- /**
- * Pre-multiply this matrix by the supplied left
matrix and store the result in dest
.
- * M
is this
matrix and L
the left
matrix,
- * then the new matrix will be L * M
. So when transforming a
- * vector v
with the new matrix by using L * M * v
, the
- * transformation of this
matrix will be applied first!
- *
- * @param left
- * the left operand of the matrix multiplication
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix3f mulLocal(Matrix3fc left, Matrix3f dest);
-
- /**
- * Return the determinant of this matrix.
- *
- * @return the determinant
- */
- float determinant();
-
- /**
- * Invert the this
matrix and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f invert(Matrix3f dest);
-
- /**
- * Transpose this
matrix and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f transpose(Matrix3f dest);
-
- /**
- * Get the current values of this
matrix and store them into
- * dest
.
- *
- * @param dest
- * the destination matrix
- * @return the passed in destination
- */
- Matrix3f get(Matrix3f dest);
-
- /**
- * Get the current values of this
matrix and store them as
- * the rotational component of dest
. All other values of dest
will
- * be set to identity.
- *
- * @see Matrix4f#set(Matrix3fc)
- *
- * @param dest
- * the destination matrix
- * @return the passed in destination
- */
- Matrix4f get(Matrix4f dest);
-
- /**
- * Get the current values of this
matrix and store the represented rotation
- * into the given {@link AxisAngle4f}.
- *
- * @see AxisAngle4f#set(Matrix3fc)
- *
- * @param dest
- * the destination {@link AxisAngle4f}
- * @return the passed in destination
- */
- AxisAngle4f getRotation(AxisAngle4f dest);
-
- /**
- * Get the current values of this
matrix and store the represented rotation
- * into the given {@link Quaternionf}.
- * this
matrix and store the represented rotation
- * into the given {@link Quaternionf}.
- * this
matrix by scaling the base axes by the given xyz.x
,
- * xyz.y
and xyz.z
factors, respectively and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
- * , the scaling will be applied first!
- *
- * @param xyz
- * the factors of the x, y and z component, respectively
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f scale(Vector3fc xyz, Matrix3f dest);
-
- /**
- * Apply scaling to this matrix by scaling the base axes by the given x,
- * y and z factors and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
- * , the scaling will be applied first!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @param z
- * the factor of the z component
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f scale(float x, float y, float z, Matrix3f dest);
-
- /**
- * Apply scaling to this matrix by uniformly scaling all base axes by the given xyz
factor
- * and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
- * , the scaling will be applied first!
- *
- * @see #scale(float, float, float, Matrix3f)
- *
- * @param xyz
- * the factor for all components
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f scale(float xyz, Matrix3f dest);
-
- /**
- * Pre-multiply scaling to this
matrix by scaling the base axes by the given x,
- * y and z factors and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
- * , the scaling will be applied last!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @param z
- * the factor of the z component
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f scaleLocal(float x, float y, float z, Matrix3f dest);
-
- /**
- * Transform the given vector by this matrix.
- *
- * @param v
- * the vector to transform
- * @return v
- */
- Vector3f transform(Vector3f v);
-
- /**
- * Transform the given vector by this matrix and store the result in dest
.
- *
- * @param v
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transform(Vector3fc v, Vector3f dest);
-
- /**
- * Transform the vector (x, y, z)
by this matrix and store the result in dest
.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transform(float x, float y, float z, Vector3f dest);
-
- /**
- * Transform the given vector by the transpose of this matrix.
- *
- * @param v
- * the vector to transform
- * @return v
- */
- Vector3f transformTranspose(Vector3f v);
-
- /**
- * Transform the given vector by the transpose of this matrix and store the result in dest
.
- *
- * @param v
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformTranspose(Vector3fc v, Vector3f dest);
-
- /**
- * Transform the vector (x, y, z)
by the transpose of this matrix and store the result in dest
.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformTranspose(float x, float y, float z, Vector3f dest);
-
- /**
- * Apply rotation about the X axis to this matrix by rotating the given amount of radians
- * and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
- * , the rotation will be applied first!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
- * , the rotation will be applied first!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
- * , the rotation will be applied first!
- * angleX
radians about the X axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateX(angleX, dest).rotateY(angleY).rotateZ(angleZ)
- *
- * @param angleX
- * the angle to rotate about X
- * @param angleY
- * the angle to rotate about Y
- * @param angleZ
- * the angle to rotate about Z
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateXYZ(float angleX, float angleY, float angleZ, Matrix3f dest);
-
- /**
- * Apply rotation of angleZ
radians about the Z axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleX
radians about the X axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateZ(angleZ, dest).rotateY(angleY).rotateX(angleX)
- *
- * @param angleZ
- * the angle to rotate about Z
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateZYX(float angleZ, float angleY, float angleX, Matrix3f dest);
-
- /**
- * Apply rotation of angleY
radians about the Y axis, followed by a rotation of angleX
radians about the X axis and
- * followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateY(angleY, dest).rotateX(angleX).rotateZ(angleZ)
- *
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param angleZ
- * the angle to rotate about Z
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateYXZ(float angleY, float angleX, float angleZ, Matrix3f dest);
-
- /**
- * Apply rotation to this matrix by rotating the given amount of radians
- * about the given axis specified as x, y and z components, and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
- * , the rotation will be applied first!
- * (x, y, z)
axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be Q * M
. So when transforming a
- * vector v
with the new matrix by using Q * M * v
,
- * the quaternion rotation will be applied last!
- * dest
.
- * M
is this
matrix and A
the rotation matrix obtained from the given {@link AxisAngle4f},
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the {@link AxisAngle4f} rotation will be applied first!
- * dest
.
- * M
is this
matrix and A
the rotation matrix obtained from the given angle and axis,
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the axis-angle rotation will be applied first!
- * -z
point along dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- *
- * @see #lookAlong(float, float, float, float, float, float, Matrix3f)
- *
- * @param dir
- * the direction in space to look along
- * @param up
- * the direction of 'up'
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f lookAlong(Vector3fc dir, Vector3fc up, Matrix3f dest);
-
- /**
- * Apply a rotation transformation to this matrix to make -z
point along dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f lookAlong(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix3f dest);
-
- /**
- * Get the row at the given row
index, starting with 0
.
- *
- * @param row
- * the row index in [0..2]
- * @param dest
- * will hold the row components
- * @return the passed in destination
- * @throws IndexOutOfBoundsException if row
is not in [0..2]
- */
- Vector3f getRow(int row, Vector3f dest) throws IndexOutOfBoundsException;
-
- /**
- * Get the column at the given column
index, starting with 0
.
- *
- * @param column
- * the column index in [0..2]
- * @param dest
- * will hold the column components
- * @return the passed in destination
- * @throws IndexOutOfBoundsException if column
is not in [0..2]
- */
- Vector3f getColumn(int column, Vector3f dest) throws IndexOutOfBoundsException;
-
- /**
- * Get the matrix element value at the given column and row.
- *
- * @param column
- * the colum index in [0..2]
- * @param row
- * the row index in [0..2]
- * @return the element value
- */
- float get(int column, int row);
-
- /**
- * Get the matrix element value at the given row and column.
- *
- * @param row
- * the row index in [0..2]
- * @param column
- * the colum index in [0..2]
- * @return the element value
- */
- float getRowColumn(int row, int column);
-
- /**
- * Compute a normal matrix from this
matrix and store it into dest
.
- * m
is the transpose of the inverse of m
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f normal(Matrix3f dest);
-
- /**
- * Compute the cofactor matrix of this
and store it into dest
.
- * this
matrix for the three base axes.
- *
- * @param dest
- * will hold the scaling factors for x
, y
and z
- * @return dest
- */
- Vector3f getScale(Vector3f dest);
-
- /**
- * Obtain the direction of +Z
before the transformation represented by this
matrix is applied.
- *
- * Matrix3f inv = new Matrix3f(this).invert();
- * inv.transform(dir.set(0, 0, 1)).normalize();
- *
- * If this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveZ(Vector3f)} instead.
- * +Z
- * @return dir
- */
- Vector3f positiveZ(Vector3f dir);
-
- /**
- * Obtain the direction of +Z
before the transformation represented by this
orthogonal matrix is applied.
- * This method only produces correct results if this
is an orthogonal matrix.
- *
- * Matrix3f inv = new Matrix3f(this).transpose();
- * inv.transform(dir.set(0, 0, 1));
- *
- * +Z
- * @return dir
- */
- Vector3f normalizedPositiveZ(Vector3f dir);
-
- /**
- * Obtain the direction of +X
before the transformation represented by this
matrix is applied.
- *
- * Matrix3f inv = new Matrix3f(this).invert();
- * inv.transform(dir.set(1, 0, 0)).normalize();
- *
- * If this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveX(Vector3f)} instead.
- * +X
- * @return dir
- */
- Vector3f positiveX(Vector3f dir);
-
- /**
- * Obtain the direction of +X
before the transformation represented by this
orthogonal matrix is applied.
- * This method only produces correct results if this
is an orthogonal matrix.
- *
- * Matrix3f inv = new Matrix3f(this).transpose();
- * inv.transform(dir.set(1, 0, 0));
- *
- * +X
- * @return dir
- */
- Vector3f normalizedPositiveX(Vector3f dir);
-
- /**
- * Obtain the direction of +Y
before the transformation represented by this
matrix is applied.
- *
- * Matrix3f inv = new Matrix3f(this).invert();
- * inv.transform(dir.set(0, 1, 0)).normalize();
- *
- * If this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveY(Vector3f)} instead.
- * +Y
- * @return dir
- */
- Vector3f positiveY(Vector3f dir);
-
- /**
- * Obtain the direction of +Y
before the transformation represented by this
orthogonal matrix is applied.
- * This method only produces correct results if this
is an orthogonal matrix.
- *
- * Matrix3f inv = new Matrix3f(this).transpose();
- * inv.transform(dir.set(0, 1, 0));
- *
- * +Y
- * @return dir
- */
- Vector3f normalizedPositiveY(Vector3f dir);
-
- /**
- * Component-wise add this
and other
and store the result in dest
.
- *
- * @param other
- * the other addend
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f add(Matrix3fc other, Matrix3f dest);
-
- /**
- * Component-wise subtract subtrahend
from this
and store the result in dest
.
- *
- * @param subtrahend
- * the subtrahend
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f sub(Matrix3fc subtrahend, Matrix3f dest);
-
- /**
- * Component-wise multiply this
by other
and store the result in dest
.
- *
- * @param other
- * the other matrix
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mulComponentWise(Matrix3fc other, Matrix3f dest);
-
- /**
- * Linearly interpolate this
and other
using the given interpolation factor t
- * and store the result in dest
.
- * t
is 0.0
then the result is this
. If the interpolation factor is 1.0
- * then the result is other
.
- *
- * @param other
- * the other matrix
- * @param t
- * the interpolation factor between 0.0 and 1.0
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f lerp(Matrix3fc other, float t, Matrix3f dest);
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with direction
- * and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mul(new Matrix3f().lookAlong(new Vector3f(dir).negate(), up).invert(), dest)
- *
- * @see #rotateTowards(float, float, float, float, float, float, Matrix3f)
- *
- * @param direction
- * the direction to rotate towards
- * @param up
- * the model's up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateTowards(Vector3fc direction, Vector3fc up, Matrix3f dest);
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mul(new Matrix3f().lookAlong(-dirX, -dirY, -dirZ, upX, upY, upZ).invert(), dest)
- *
- * @see #rotateTowards(Vector3fc, Vector3fc, Matrix3f)
- *
- * @param dirX
- * the x-coordinate of the direction to rotate towards
- * @param dirY
- * the y-coordinate of the direction to rotate towards
- * @param dirZ
- * the z-coordinate of the direction to rotate towards
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f rotateTowards(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix3f dest);
-
- /**
- * Extract the Euler angles from the rotation represented by this
matrix and store the extracted Euler angles in dest
.
- * this
matrix only represents a rotation without scaling.
- * X * Y * Z
to obtain the identical matrix.
- * This means that calling {@link Matrix3fc#rotateXYZ(float, float, float, Matrix3f)} using the obtained Euler angles will yield
- * the same rotation as the original matrix from which the Euler angles were obtained, so in the below code the matrix
- * m2
should be identical to m
(disregarding possible floating-point inaccuracies).
- *
- * Matrix3f m = ...; // <- matrix only representing rotation
- * Matrix3f n = new Matrix3f();
- * n.rotateXYZ(m.getEulerAnglesXYZ(new Vector3f()));
- *
- * this
matrix and store the extracted Euler angles in dest
.
- * this
matrix only represents a rotation without scaling.
- * Z * Y * X
to obtain the identical matrix.
- * This means that calling {@link Matrix3fc#rotateZYX(float, float, float, Matrix3f)} using the obtained Euler angles will yield
- * the same rotation as the original matrix from which the Euler angles were obtained, so in the below code the matrix
- * m2
should be identical to m
(disregarding possible floating-point inaccuracies).
- *
- * Matrix3f m = ...; // <- matrix only representing rotation
- * Matrix3f n = new Matrix3f();
- * n.rotateZYX(m.getEulerAnglesZYX(new Vector3f()));
- *
- * a
and
- * b
and store the result in dest
.
- * M
is this
matrix and O
the oblique transformation matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * oblique transformation will be applied first!
- *
- * x' = x + a*z
- * y' = y + a*z
- * z' = z
- *
- * or in matrix form:
- *
- * 1 0 a
- * 0 1 b
- * 0 0 1
- *
- *
- * @param a
- * the value for the z factor that applies to x
- * @param b
- * the value for the z factor that applies to y
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f obliqueZ(float a, float b, Matrix3f dest);
-
- /**
- * Compare the matrix elements of this
matrix with the given matrix using the given delta
- * and return whether all of them are equal within a maximum difference of delta
.
- * true
whether all of the matrix elements are equal; false
otherwise
- */
- boolean equals(Matrix3fc m, float delta);
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects through the given plane
- * specified via the plane normal (nx, ny, nz)
, and store the result in dest
.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param nx
- * the x-coordinate of the plane normal
- * @param ny
- * the y-coordinate of the plane normal
- * @param nz
- * the z-coordinate of the plane normal
- * @param dest
- * will hold the result
- * @return this
- */
- Matrix3f reflect(float nx, float ny, float nz, Matrix3f dest);
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects through a plane
- * specified via the plane orientation, and store the result in dest
.
- * (0, 0, 1)
. So, if the given {@link Quaternionfc} is
- * the identity (does not apply any additional rotation), the reflection plane will be z=0
.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param orientation
- * the plane orientation
- * @param dest
- * will hold the result
- * @return this
- */
- Matrix3f reflect(Quaternionfc orientation, Matrix3f dest);
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects through the given plane
- * specified via the plane normal, and store the result in dest
.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param normal
- * the plane normal
- * @param dest
- * will hold the result
- * @return this
- */
- Matrix3f reflect(Vector3fc normal, Matrix3f dest);
-
- /**
- * Determine whether all matrix elements are finite floating-point values, that
- * is, they are not {@link Float#isNaN() NaN} and not
- * {@link Float#isInfinite() infinity}.
- *
- * @return {@code true} if all components are finite floating-point values;
- * {@code false} otherwise
- */
- boolean isFinite();
-
- /**
- * Compute (x, y, z)^T * this * (x, y, z)
.
- *
- * @param x
- * the x coordinate of the vector to multiply
- * @param y
- * the y coordinate of the vector to multiply
- * @param z
- * the z coordinate of the vector to multiply
- * @return the result
- */
- float quadraticFormProduct(float x, float y, float z);
-
- /**
- * Compute v^T * this * v
.
- *
- * @param v
- * the vector to multiply
- * @return the result
- */
- float quadraticFormProduct(Vector3fc v);
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 0 1
- * 0 1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapXZY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 0 -1
- * 0 1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapXZnY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 -1 0
- * 0 0 -1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapXnYnZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 0 1
- * 0 -1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapXnZY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 0 -1
- * 0 -1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapXnZnY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 1 0 0
- * 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapYXZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 1 0 0
- * 0 0 -1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapYXnZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 1 0 0
- * 0 1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapYZX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 1 0 0
- * 0 1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapYZnX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 1 0 0
- * 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapYnXZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 1 0 0
- * 0 0 -1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapYnXnZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 1 0 0
- * 0 -1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapYnZX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 1 0 0
- * 0 -1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapYnZnX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 0 0 1
- * 1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapZXY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 0 0 -1
- * 1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapZXnY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 0 1 0
- * 1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapZYX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 0 1 0
- * 1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapZYnX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 0 0 1
- * 1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapZnXY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 0 0 -1
- * 1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapZnXnY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 0 -1 0
- * 1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapZnYX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 0 -1 0
- * 1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapZnYnX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 1 0
- * 0 0 -1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnXYnZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 0 1
- * 0 1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnXZY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 0 -1
- * 0 1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnXZnY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 -1 0
- * 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnXnYZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 -1 0
- * 0 0 -1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnXnYnZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 0 1
- * 0 -1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnXnZY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 0 -1
- * 0 -1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnXnZnY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * -1 0 0
- * 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnYXZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * -1 0 0
- * 0 0 -1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnYXnZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * -1 0 0
- * 0 1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnYZX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * -1 0 0
- * 0 1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnYZnX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * -1 0 0
- * 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnYnXZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * -1 0 0
- * 0 0 -1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnYnXnZ(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * -1 0 0
- * 0 -1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnYnZX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * -1 0 0
- * 0 -1 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnYnZnX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 0 0 1
- * -1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnZXY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0
- * 0 0 -1
- * -1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnZXnY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 0 1 0
- * -1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnZYX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 0 1 0
- * -1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnZYnX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 0 0 1
- * -1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnZnXY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0
- * 0 0 -1
- * -1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnZnXnY(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1
- * 0 -1 0
- * -1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnZnYX(Matrix3f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1
- * 0 -1 0
- * -1 0 0
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f mapnZnYnX(Matrix3f dest);
-
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0
- * 0 1 0
- * 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f negateX(Matrix3f dest);
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 -1 0
- * 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f negateY(Matrix3f dest);
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0
- * 0 1 0
- * 0 0 -1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f negateZ(Matrix3f dest);
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix4f.java b/src/main/java/com/jozufozu/flywheel/util/joml/Matrix4f.java
deleted file mode 100644
index 394db3726..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix4f.java
+++ /dev/null
@@ -1,15320 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 Richard Greenlees
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-
-
-/**
- * Contains the definition of a 4x4 matrix of floats, and associated functions to transform
- * it. The matrix is column-major to match OpenGL's interpretation, and it looks like this:
- *
- * m01 m11 m21 m31
- * m02 m12 m22 m32
- * m03 m13 m23 m33
- *
- * @author Richard Greenlees
- * @author Kai Burjack
- */
-public class Matrix4f implements Externalizable, Cloneable, Matrix4fc {
-
- private static final long serialVersionUID = 1L;
-
- float m00, m01, m02, m03;
- float m10, m11, m12, m13;
- float m20, m21, m22, m23;
- float m30, m31, m32, m33;
-
- int properties;
-
- /**
- * Create a new {@link Matrix4f} and set it to {@link #identity() identity}.
- */
- public Matrix4f() {
- this._m00(1.0f)
- ._m11(1.0f)
- ._m22(1.0f)
- ._m33(1.0f)
- ._properties(PROPERTY_IDENTITY | PROPERTY_AFFINE | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Create a new {@link Matrix4f} by setting its uppper left 3x3 submatrix to the values of the given {@link Matrix3fc}
- * and the rest to identity.
- *
- * @param mat
- * the {@link Matrix3fc}
- */
- public Matrix4f(Matrix3fc mat) {
- set(mat);
- }
-
- /**
- * Create a new {@link Matrix4f} and make it a copy of the given matrix.
- *
- * @param mat
- * the {@link Matrix4fc} to copy the values from
- */
- public Matrix4f(Matrix4fc mat) {
- set(mat);
- }
-
- /**
- * Create a new 4x4 matrix using the supplied float values.
- *
- * m00, m10, m20, m30
- * m01, m11, m21, m31
- * m02, m12, m22, m32
- * m03, m13, m23, m33
- *
- * @param m00
- * the value of m00
- * @param m01
- * the value of m01
- * @param m02
- * the value of m02
- * @param m03
- * the value of m03
- * @param m10
- * the value of m10
- * @param m11
- * the value of m11
- * @param m12
- * the value of m12
- * @param m13
- * the value of m13
- * @param m20
- * the value of m20
- * @param m21
- * the value of m21
- * @param m22
- * the value of m22
- * @param m23
- * the value of m23
- * @param m30
- * the value of m30
- * @param m31
- * the value of m31
- * @param m32
- * the value of m32
- * @param m33
- * the value of m33
- */
- public Matrix4f(float m00, float m01, float m02, float m03,
- float m10, float m11, float m12, float m13,
- float m20, float m21, float m22, float m23,
- float m30, float m31, float m32, float m33) {
- this._m00(m00)
- ._m01(m01)
- ._m02(m02)
- ._m03(m03)
- ._m10(m10)
- ._m11(m11)
- ._m12(m12)
- ._m13(m13)
- ._m20(m20)
- ._m21(m21)
- ._m22(m22)
- ._m23(m23)
- ._m30(m30)
- ._m31(m31)
- ._m32(m32)
- ._m33(m33)
- .determineProperties();
- }
-
- /**
- * Create a new {@link Matrix4f} by reading its 16 float components from the given {@link FloatBuffer}
- * at the buffer's current position.
- * m
into this
matrix.
- *
- * @see #Matrix4f(Matrix4fc)
- * @see #get(Matrix4f)
- *
- * @param m
- * the matrix to copy the values from
- * @return this
- */
- public Matrix4f set(Matrix4fc m) {
- return
- _m00(m.m00()).
- _m01(m.m01()).
- _m02(m.m02()).
- _m03(m.m03()).
- _m10(m.m10()).
- _m11(m.m11()).
- _m12(m.m12()).
- _m13(m.m13()).
- _m20(m.m20()).
- _m21(m.m21()).
- _m22(m.m22()).
- _m23(m.m23()).
- _m30(m.m30()).
- _m31(m.m31()).
- _m32(m.m32()).
- _m33(m.m33()).
- _properties(m.properties());
- }
-
- /**
- * Store the values of the transpose of the given matrix m
into this
matrix.
- *
- * @param m
- * the matrix to copy the transposed values from
- * @return this
- */
- public Matrix4f setTransposed(Matrix4fc m) {
- if ((m.properties() & PROPERTY_IDENTITY) != 0)
- return this.identity();
- return setTransposedInternal(m);
- }
- private Matrix4f setTransposedInternal(Matrix4fc m) {
- float nm10 = m.m01(), nm12 = m.m21(), nm13 = m.m31();
- float nm20 = m.m02(), nm21 = m.m12(), nm30 = m.m03();
- float nm31 = m.m13(), nm32 = m.m23();
- return this
- ._m00(m.m00())._m01(m.m10())._m02(m.m20())._m03(m.m30())
- ._m10(nm10)._m11(m.m11())._m12(nm12)._m13(nm13)
- ._m20(nm20)._m21(nm21)._m22(m.m22())._m23(m.m32())
- ._m30(nm30)._m31(nm31)._m32(nm32)._m33(m.m33())
- ._properties(m.properties() & PROPERTY_IDENTITY);
- }
-
- /**
- * Set the upper left 3x3 submatrix of this {@link Matrix4f} to the given {@link Matrix3fc}
- * and the rest to identity.
- *
- * @see #Matrix4f(Matrix3fc)
- *
- * @param mat
- * the {@link Matrix3fc}
- * @return this
- */
- public Matrix4f set(Matrix3fc mat) {
- return this
- ._m00(mat.m00())
- ._m01(mat.m01())
- ._m02(mat.m02())
- ._m03(0.0f)
- ._m10(mat.m10())
- ._m11(mat.m11())
- ._m12(mat.m12())
- ._m13(0.0f)
- ._m20(mat.m20())
- ._m21(mat.m21())
- ._m22(mat.m22())
- ._m23(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(1.0f).
- _properties(PROPERTY_AFFINE);
- }
-
- /**
- * Set this matrix to be equivalent to the rotation specified by the given {@link AxisAngle4f}.
- *
- * @param axisAngle
- * the {@link AxisAngle4f}
- * @return this
- */
- public Matrix4f set(AxisAngle4f axisAngle) {
- float x = axisAngle.x;
- float y = axisAngle.y;
- float z = axisAngle.z;
- float angle = axisAngle.angle;
- double n = Math.sqrt(x*x + y*y + z*z);
- n = 1/n;
- x *= n;
- y *= n;
- z *= n;
- float s = Math.sin(angle);
- float c = Math.cosFromSin(s, angle);
- float omc = 1.0f - c;
- this._m00((float)(c + x*x*omc))
- ._m11((float)(c + y*y*omc))
- ._m22((float)(c + z*z*omc));
- float tmp1 = x*y*omc;
- float tmp2 = z*s;
- this._m10((float)(tmp1 - tmp2))
- ._m01((float)(tmp1 + tmp2));
- tmp1 = x*z*omc;
- tmp2 = y*s;
- this._m20((float)(tmp1 + tmp2))
- ._m02((float)(tmp1 - tmp2));
- tmp1 = y*z*omc;
- tmp2 = x*s;
- return this
- ._m21((float)(tmp1 - tmp2))
- ._m12((float)(tmp1 + tmp2))
- ._m03(0.0f)
- ._m13(0.0f)
- ._m23(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set this matrix to be equivalent to the rotation specified by the given {@link Quaternionfc}.
- * rotation(q)
- * right
matrix and store the result in this
.
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param right
- * the right operand of the matrix multiplication
- * @return this
- */
- public Matrix4f mul(Matrix4fc right) {
- return mul(right, this);
- }
-
- public Matrix4f mul(Matrix4fc right, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.set(right);
- else if ((right.properties() & PROPERTY_IDENTITY) != 0)
- return dest.set(this);
- else if ((properties & PROPERTY_TRANSLATION) != 0 && (right.properties() & PROPERTY_AFFINE) != 0)
- return mulTranslationAffine(right, dest);
- else if ((properties & PROPERTY_AFFINE) != 0 && (right.properties() & PROPERTY_AFFINE) != 0)
- return mulAffine(right, dest);
- else if ((properties & PROPERTY_PERSPECTIVE) != 0 && (right.properties() & PROPERTY_AFFINE) != 0)
- return mulPerspectiveAffine(right, dest);
- else if ((right.properties() & PROPERTY_AFFINE) != 0)
- return mulAffineR(right, dest);
- return mul0(right, dest);
- }
-
- /**
- * Multiply this matrix by the supplied right
matrix.
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- * this
or right
- * and will always perform a complete 4x4 matrix multiplication. This method should only be used whenever the
- * multiplied matrices do not have any properties for which there are optimized multiplication methods available.
- *
- * @param right
- * the right operand of the matrix multiplication
- * @return this
- */
- public Matrix4f mul0(Matrix4fc right) {
- return mul0(right, this);
- }
-
- public Matrix4f mul0(Matrix4fc right, Matrix4f dest) {
- float nm00 = Math.fma(m00(), right.m00(), Math.fma(m10(), right.m01(), Math.fma(m20(), right.m02(), m30() * right.m03())));
- float nm01 = Math.fma(m01(), right.m00(), Math.fma(m11(), right.m01(), Math.fma(m21(), right.m02(), m31() * right.m03())));
- float nm02 = Math.fma(m02(), right.m00(), Math.fma(m12(), right.m01(), Math.fma(m22(), right.m02(), m32() * right.m03())));
- float nm03 = Math.fma(m03(), right.m00(), Math.fma(m13(), right.m01(), Math.fma(m23(), right.m02(), m33() * right.m03())));
- float nm10 = Math.fma(m00(), right.m10(), Math.fma(m10(), right.m11(), Math.fma(m20(), right.m12(), m30() * right.m13())));
- float nm11 = Math.fma(m01(), right.m10(), Math.fma(m11(), right.m11(), Math.fma(m21(), right.m12(), m31() * right.m13())));
- float nm12 = Math.fma(m02(), right.m10(), Math.fma(m12(), right.m11(), Math.fma(m22(), right.m12(), m32() * right.m13())));
- float nm13 = Math.fma(m03(), right.m10(), Math.fma(m13(), right.m11(), Math.fma(m23(), right.m12(), m33() * right.m13())));
- float nm20 = Math.fma(m00(), right.m20(), Math.fma(m10(), right.m21(), Math.fma(m20(), right.m22(), m30() * right.m23())));
- float nm21 = Math.fma(m01(), right.m20(), Math.fma(m11(), right.m21(), Math.fma(m21(), right.m22(), m31() * right.m23())));
- float nm22 = Math.fma(m02(), right.m20(), Math.fma(m12(), right.m21(), Math.fma(m22(), right.m22(), m32() * right.m23())));
- float nm23 = Math.fma(m03(), right.m20(), Math.fma(m13(), right.m21(), Math.fma(m23(), right.m22(), m33() * right.m23())));
- float nm30 = Math.fma(m00(), right.m30(), Math.fma(m10(), right.m31(), Math.fma(m20(), right.m32(), m30() * right.m33())));
- float nm31 = Math.fma(m01(), right.m30(), Math.fma(m11(), right.m31(), Math.fma(m21(), right.m32(), m31() * right.m33())));
- float nm32 = Math.fma(m02(), right.m30(), Math.fma(m12(), right.m31(), Math.fma(m22(), right.m32(), m32() * right.m33())));
- float nm33 = Math.fma(m03(), right.m30(), Math.fma(m13(), right.m31(), Math.fma(m23(), right.m32(), m33() * right.m33())));
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(nm33)
- ._properties(0);
- }
-
- /**
- * Multiply this matrix by the matrix with the supplied elements.
- * M
is this
matrix and R
the right
matrix whose
- * elements are supplied via the parameters, then the new matrix will be M * R
.
- * So when transforming a vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param r00
- * the m00 element of the right matrix
- * @param r01
- * the m01 element of the right matrix
- * @param r02
- * the m02 element of the right matrix
- * @param r03
- * the m03 element of the right matrix
- * @param r10
- * the m10 element of the right matrix
- * @param r11
- * the m11 element of the right matrix
- * @param r12
- * the m12 element of the right matrix
- * @param r13
- * the m13 element of the right matrix
- * @param r20
- * the m20 element of the right matrix
- * @param r21
- * the m21 element of the right matrix
- * @param r22
- * the m22 element of the right matrix
- * @param r23
- * the m23 element of the right matrix
- * @param r30
- * the m30 element of the right matrix
- * @param r31
- * the m31 element of the right matrix
- * @param r32
- * the m32 element of the right matrix
- * @param r33
- * the m33 element of the right matrix
- * @return this
- */
- public Matrix4f mul(
- float r00, float r01, float r02, float r03,
- float r10, float r11, float r12, float r13,
- float r20, float r21, float r22, float r23,
- float r30, float r31, float r32, float r33) {
- return mul(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33, this);
- }
-
- public Matrix4f mul(
- float r00, float r01, float r02, float r03,
- float r10, float r11, float r12, float r13,
- float r20, float r21, float r22, float r23,
- float r30, float r31, float r32, float r33, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.set(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33);
- else if ((properties & PROPERTY_AFFINE) != 0)
- return mulAffineL(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33, dest);
- return mulGeneric(r00, r01, r02, r03, r10, r11, r12, r13, r20, r21, r22, r23, r30, r31, r32, r33, dest);
- }
- private Matrix4f mulAffineL(
- float r00, float r01, float r02, float r03,
- float r10, float r11, float r12, float r13,
- float r20, float r21, float r22, float r23,
- float r30, float r31, float r32, float r33, Matrix4f dest) {
- float nm00 = Math.fma(m00(), r00, Math.fma(m10(), r01, Math.fma(m20(), r02, m30() * r03)));
- float nm01 = Math.fma(m01(), r00, Math.fma(m11(), r01, Math.fma(m21(), r02, m31() * r03)));
- float nm02 = Math.fma(m02(), r00, Math.fma(m12(), r01, Math.fma(m22(), r02, m32() * r03)));
- float nm03 = r03;
- float nm10 = Math.fma(m00(), r10, Math.fma(m10(), r11, Math.fma(m20(), r12, m30() * r13)));
- float nm11 = Math.fma(m01(), r10, Math.fma(m11(), r11, Math.fma(m21(), r12, m31() * r13)));
- float nm12 = Math.fma(m02(), r10, Math.fma(m12(), r11, Math.fma(m22(), r12, m32() * r13)));
- float nm13 = r13;
- float nm20 = Math.fma(m00(), r20, Math.fma(m10(), r21, Math.fma(m20(), r22, m30() * r23)));
- float nm21 = Math.fma(m01(), r20, Math.fma(m11(), r21, Math.fma(m21(), r22, m31() * r23)));
- float nm22 = Math.fma(m02(), r20, Math.fma(m12(), r21, Math.fma(m22(), r22, m32() * r23)));
- float nm23 = r23;
- float nm30 = Math.fma(m00(), r30, Math.fma(m10(), r31, Math.fma(m20(), r32, m30() * r33)));
- float nm31 = Math.fma(m01(), r30, Math.fma(m11(), r31, Math.fma(m21(), r32, m31() * r33)));
- float nm32 = Math.fma(m02(), r30, Math.fma(m12(), r31, Math.fma(m22(), r32, m32() * r33)));
- float nm33 = r33;
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(nm33)
- ._properties(PROPERTY_AFFINE);
- }
- private Matrix4f mulGeneric(
- float r00, float r01, float r02, float r03,
- float r10, float r11, float r12, float r13,
- float r20, float r21, float r22, float r23,
- float r30, float r31, float r32, float r33, Matrix4f dest) {
- float nm00 = Math.fma(m00(), r00, Math.fma(m10(), r01, Math.fma(m20(), r02, m30() * r03)));
- float nm01 = Math.fma(m01(), r00, Math.fma(m11(), r01, Math.fma(m21(), r02, m31() * r03)));
- float nm02 = Math.fma(m02(), r00, Math.fma(m12(), r01, Math.fma(m22(), r02, m32() * r03)));
- float nm03 = Math.fma(m03(), r00, Math.fma(m13(), r01, Math.fma(m23(), r02, m33() * r03)));
- float nm10 = Math.fma(m00(), r10, Math.fma(m10(), r11, Math.fma(m20(), r12, m30() * r13)));
- float nm11 = Math.fma(m01(), r10, Math.fma(m11(), r11, Math.fma(m21(), r12, m31() * r13)));
- float nm12 = Math.fma(m02(), r10, Math.fma(m12(), r11, Math.fma(m22(), r12, m32() * r13)));
- float nm13 = Math.fma(m03(), r10, Math.fma(m13(), r11, Math.fma(m23(), r12, m33() * r13)));
- float nm20 = Math.fma(m00(), r20, Math.fma(m10(), r21, Math.fma(m20(), r22, m30() * r23)));
- float nm21 = Math.fma(m01(), r20, Math.fma(m11(), r21, Math.fma(m21(), r22, m31() * r23)));
- float nm22 = Math.fma(m02(), r20, Math.fma(m12(), r21, Math.fma(m22(), r22, m32() * r23)));
- float nm23 = Math.fma(m03(), r20, Math.fma(m13(), r21, Math.fma(m23(), r22, m33() * r23)));
- float nm30 = Math.fma(m00(), r30, Math.fma(m10(), r31, Math.fma(m20(), r32, m30() * r33)));
- float nm31 = Math.fma(m01(), r30, Math.fma(m11(), r31, Math.fma(m21(), r32, m31() * r33)));
- float nm32 = Math.fma(m02(), r30, Math.fma(m12(), r31, Math.fma(m22(), r32, m32() * r33)));
- float nm33 = Math.fma(m03(), r30, Math.fma(m13(), r31, Math.fma(m23(), r32, m33() * r33)));
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(nm33)
- ._properties(0);
- }
-
- /**
- * Multiply this matrix by the 3x3 matrix with the supplied elements expanded to a 4x4 matrix with
- * all other matrix elements set to identity.
- * M
is this
matrix and R
the right
matrix whose
- * elements are supplied via the parameters, then the new matrix will be M * R
.
- * So when transforming a vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param r00
- * the m00 element of the right matrix
- * @param r01
- * the m01 element of the right matrix
- * @param r02
- * the m02 element of the right matrix
- * @param r10
- * the m10 element of the right matrix
- * @param r11
- * the m11 element of the right matrix
- * @param r12
- * the m12 element of the right matrix
- * @param r20
- * the m20 element of the right matrix
- * @param r21
- * the m21 element of the right matrix
- * @param r22
- * the m22 element of the right matrix
- * @return this
- */
- public Matrix4f mul3x3(
- float r00, float r01, float r02,
- float r10, float r11, float r12,
- float r20, float r21, float r22) {
- return mul3x3(r00, r01, r02, r10, r11, r12, r20, r21, r22, this);
- }
- public Matrix4f mul3x3(
- float r00, float r01, float r02,
- float r10, float r11, float r12,
- float r20, float r21, float r22, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.set(r00, r01, r02, 0, r10, r11, r12, 0, r20, r21, r22, 0, 0, 0, 0, 1);
- return mulGeneric3x3(r00, r01, r02, r10, r11, r12, r20, r21, r22, dest);
- }
- private Matrix4f mulGeneric3x3(
- float r00, float r01, float r02,
- float r10, float r11, float r12,
- float r20, float r21, float r22, Matrix4f dest) {
- float nm00 = Math.fma(m00(), r00, Math.fma(m10(), r01, m20() * r02));
- float nm01 = Math.fma(m01(), r00, Math.fma(m11(), r01, m21() * r02));
- float nm02 = Math.fma(m02(), r00, Math.fma(m12(), r01, m22() * r02));
- float nm03 = Math.fma(m03(), r00, Math.fma(m13(), r01, m23() * r02));
- float nm10 = Math.fma(m00(), r10, Math.fma(m10(), r11, m20() * r12));
- float nm11 = Math.fma(m01(), r10, Math.fma(m11(), r11, m21() * r12));
- float nm12 = Math.fma(m02(), r10, Math.fma(m12(), r11, m22() * r12));
- float nm13 = Math.fma(m03(), r10, Math.fma(m13(), r11, m23() * r12));
- float nm20 = Math.fma(m00(), r20, Math.fma(m10(), r21, m20() * r22));
- float nm21 = Math.fma(m01(), r20, Math.fma(m11(), r21, m21() * r22));
- float nm22 = Math.fma(m02(), r20, Math.fma(m12(), r21, m22() * r22));
- float nm23 = Math.fma(m03(), r20, Math.fma(m13(), r21, m23() * r22));
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(this.properties & PROPERTY_AFFINE);
- }
-
- /**
- * Pre-multiply this matrix by the supplied left
matrix and store the result in this
.
- * M
is this
matrix and L
the left
matrix,
- * then the new matrix will be L * M
. So when transforming a
- * vector v
with the new matrix by using L * M * v
, the
- * transformation of this
matrix will be applied first!
- *
- * @param left
- * the left operand of the matrix multiplication
- * @return this
- */
- public Matrix4f mulLocal(Matrix4fc left) {
- return mulLocal(left, this);
- }
-
- public Matrix4f mulLocal(Matrix4fc left, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.set(left);
- else if ((left.properties() & PROPERTY_IDENTITY) != 0)
- return dest.set(this);
- else if ((properties & PROPERTY_AFFINE) != 0 && (left.properties() & PROPERTY_AFFINE) != 0)
- return mulLocalAffine(left, dest);
- return mulLocalGeneric(left, dest);
- }
- private Matrix4f mulLocalGeneric(Matrix4fc left, Matrix4f dest) {
- float nm00 = Math.fma(left.m00(), m00(), Math.fma(left.m10(), m01(), Math.fma(left.m20(), m02(), left.m30() * m03())));
- float nm01 = Math.fma(left.m01(), m00(), Math.fma(left.m11(), m01(), Math.fma(left.m21(), m02(), left.m31() * m03())));
- float nm02 = Math.fma(left.m02(), m00(), Math.fma(left.m12(), m01(), Math.fma(left.m22(), m02(), left.m32() * m03())));
- float nm03 = Math.fma(left.m03(), m00(), Math.fma(left.m13(), m01(), Math.fma(left.m23(), m02(), left.m33() * m03())));
- float nm10 = Math.fma(left.m00(), m10(), Math.fma(left.m10(), m11(), Math.fma(left.m20(), m12(), left.m30() * m13())));
- float nm11 = Math.fma(left.m01(), m10(), Math.fma(left.m11(), m11(), Math.fma(left.m21(), m12(), left.m31() * m13())));
- float nm12 = Math.fma(left.m02(), m10(), Math.fma(left.m12(), m11(), Math.fma(left.m22(), m12(), left.m32() * m13())));
- float nm13 = Math.fma(left.m03(), m10(), Math.fma(left.m13(), m11(), Math.fma(left.m23(), m12(), left.m33() * m13())));
- float nm20 = Math.fma(left.m00(), m20(), Math.fma(left.m10(), m21(), Math.fma(left.m20(), m22(), left.m30() * m23())));
- float nm21 = Math.fma(left.m01(), m20(), Math.fma(left.m11(), m21(), Math.fma(left.m21(), m22(), left.m31() * m23())));
- float nm22 = Math.fma(left.m02(), m20(), Math.fma(left.m12(), m21(), Math.fma(left.m22(), m22(), left.m32() * m23())));
- float nm23 = Math.fma(left.m03(), m20(), Math.fma(left.m13(), m21(), Math.fma(left.m23(), m22(), left.m33() * m23())));
- float nm30 = Math.fma(left.m00(), m30(), Math.fma(left.m10(), m31(), Math.fma(left.m20(), m32(), left.m30() * m33())));
- float nm31 = Math.fma(left.m01(), m30(), Math.fma(left.m11(), m31(), Math.fma(left.m21(), m32(), left.m31() * m33())));
- float nm32 = Math.fma(left.m02(), m30(), Math.fma(left.m12(), m31(), Math.fma(left.m22(), m32(), left.m32() * m33())));
- float nm33 = Math.fma(left.m03(), m30(), Math.fma(left.m13(), m31(), Math.fma(left.m23(), m32(), left.m33() * m33())));
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(nm33)
- ._properties(0);
- }
-
- /**
- * Pre-multiply this matrix by the supplied left
matrix, both of which are assumed to be {@link #isAffine() affine}, and store the result in this
.
- * this
matrix and the given left
matrix both represent an {@link #isAffine() affine} transformation
- * (i.e. their last rows are equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrices only represent affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * this
or the last row of left
.
- * M
is this
matrix and L
the left
matrix,
- * then the new matrix will be L * M
. So when transforming a
- * vector v
with the new matrix by using L * M * v
, the
- * transformation of this
matrix will be applied first!
- *
- * @param left
- * the left operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
- * @return this
- */
- public Matrix4f mulLocalAffine(Matrix4fc left) {
- return mulLocalAffine(left, this);
- }
-
- public Matrix4f mulLocalAffine(Matrix4fc left, Matrix4f dest) {
- float nm00 = left.m00() * m00() + left.m10() * m01() + left.m20() * m02();
- float nm01 = left.m01() * m00() + left.m11() * m01() + left.m21() * m02();
- float nm02 = left.m02() * m00() + left.m12() * m01() + left.m22() * m02();
- float nm03 = left.m03();
- float nm10 = left.m00() * m10() + left.m10() * m11() + left.m20() * m12();
- float nm11 = left.m01() * m10() + left.m11() * m11() + left.m21() * m12();
- float nm12 = left.m02() * m10() + left.m12() * m11() + left.m22() * m12();
- float nm13 = left.m13();
- float nm20 = left.m00() * m20() + left.m10() * m21() + left.m20() * m22();
- float nm21 = left.m01() * m20() + left.m11() * m21() + left.m21() * m22();
- float nm22 = left.m02() * m20() + left.m12() * m21() + left.m22() * m22();
- float nm23 = left.m23();
- float nm30 = left.m00() * m30() + left.m10() * m31() + left.m20() * m32() + left.m30();
- float nm31 = left.m01() * m30() + left.m11() * m31() + left.m21() * m32() + left.m31();
- float nm32 = left.m02() * m30() + left.m12() * m31() + left.m22() * m32() + left.m32();
- float nm33 = left.m33();
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(nm33)
- ._properties(PROPERTY_AFFINE | (this.properties() & left.properties() & PROPERTY_ORTHONORMAL));
- }
-
- /**
- * Multiply this
symmetric perspective projection matrix by the supplied {@link #isAffine() affine} view
matrix.
- * P
is this
matrix and V
the view
matrix,
- * then the new matrix will be P * V
. So when transforming a
- * vector v
with the new matrix by using P * V * v
, the
- * transformation of the view
matrix will be applied first!
- *
- * @param view
- * the {@link #isAffine() affine} matrix to multiply this
symmetric perspective projection matrix by
- * @return this
- */
- public Matrix4f mulPerspectiveAffine(Matrix4fc view) {
- return mulPerspectiveAffine(view, this);
- }
-
- public Matrix4f mulPerspectiveAffine(Matrix4fc view, Matrix4f dest) {
- float nm00 = m00() * view.m00(), nm01 = m11() * view.m01(), nm02 = m22() * view.m02(), nm03 = m23() * view.m02();
- float nm10 = m00() * view.m10(), nm11 = m11() * view.m11(), nm12 = m22() * view.m12(), nm13 = m23() * view.m12();
- float nm20 = m00() * view.m20(), nm21 = m11() * view.m21(), nm22 = m22() * view.m22(), nm23 = m23() * view.m22();
- float nm30 = m00() * view.m30(), nm31 = m11() * view.m31(), nm32 = m22() * view.m32() + m32(), nm33 = m23() * view.m32();
- return dest
- ._m00(nm00)._m01(nm01)._m02(nm02)._m03(nm03)
- ._m10(nm10)._m11(nm11)._m12(nm12)._m13(nm13)
- ._m20(nm20)._m21(nm21)._m22(nm22)._m23(nm23)
- ._m30(nm30)._m31(nm31)._m32(nm32)._m33(nm33)
- ._properties(0);
- }
-
- /**
- * Multiply this matrix by the supplied right
matrix, which is assumed to be {@link #isAffine() affine}, and store the result in this
.
- * right
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param right
- * the right operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
- * @return this
- */
- public Matrix4f mulAffineR(Matrix4fc right) {
- return mulAffineR(right, this);
- }
-
- public Matrix4f mulAffineR(Matrix4fc right, Matrix4f dest) {
- float nm00 = Math.fma(m00(), right.m00(), Math.fma(m10(), right.m01(), m20() * right.m02()));
- float nm01 = Math.fma(m01(), right.m00(), Math.fma(m11(), right.m01(), m21() * right.m02()));
- float nm02 = Math.fma(m02(), right.m00(), Math.fma(m12(), right.m01(), m22() * right.m02()));
- float nm03 = Math.fma(m03(), right.m00(), Math.fma(m13(), right.m01(), m23() * right.m02()));
- float nm10 = Math.fma(m00(), right.m10(), Math.fma(m10(), right.m11(), m20() * right.m12()));
- float nm11 = Math.fma(m01(), right.m10(), Math.fma(m11(), right.m11(), m21() * right.m12()));
- float nm12 = Math.fma(m02(), right.m10(), Math.fma(m12(), right.m11(), m22() * right.m12()));
- float nm13 = Math.fma(m03(), right.m10(), Math.fma(m13(), right.m11(), m23() * right.m12()));
- float nm20 = Math.fma(m00(), right.m20(), Math.fma(m10(), right.m21(), m20() * right.m22()));
- float nm21 = Math.fma(m01(), right.m20(), Math.fma(m11(), right.m21(), m21() * right.m22()));
- float nm22 = Math.fma(m02(), right.m20(), Math.fma(m12(), right.m21(), m22() * right.m22()));
- float nm23 = Math.fma(m03(), right.m20(), Math.fma(m13(), right.m21(), m23() * right.m22()));
- float nm30 = Math.fma(m00(), right.m30(), Math.fma(m10(), right.m31(), Math.fma(m20(), right.m32(), m30())));
- float nm31 = Math.fma(m01(), right.m30(), Math.fma(m11(), right.m31(), Math.fma(m21(), right.m32(), m31())));
- float nm32 = Math.fma(m02(), right.m30(), Math.fma(m12(), right.m31(), Math.fma(m22(), right.m32(), m32())));
- float nm33 = Math.fma(m03(), right.m30(), Math.fma(m13(), right.m31(), Math.fma(m23(), right.m32(), m33())));
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(nm33)
- ._properties(properties & ~(PROPERTY_IDENTITY | PROPERTY_PERSPECTIVE | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- }
-
- /**
- * Multiply this matrix by the supplied right
matrix, both of which are assumed to be {@link #isAffine() affine}, and store the result in this
.
- * this
matrix and the given right
matrix both represent an {@link #isAffine() affine} transformation
- * (i.e. their last rows are equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrices only represent affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * this
or the last row of right
.
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param right
- * the right operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
- * @return this
- */
- public Matrix4f mulAffine(Matrix4fc right) {
- return mulAffine(right, this);
- }
-
- public Matrix4f mulAffine(Matrix4fc right, Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- float m20 = this.m20(), m21 = this.m21(), m22 = this.m22();
- float rm00 = right.m00(), rm01 = right.m01(), rm02 = right.m02();
- float rm10 = right.m10(), rm11 = right.m11(), rm12 = right.m12();
- float rm20 = right.m20(), rm21 = right.m21(), rm22 = right.m22();
- float rm30 = right.m30(), rm31 = right.m31(), rm32 = right.m32();
- return dest
- ._m00(Math.fma(m00, rm00, Math.fma(m10, rm01, m20 * rm02)))
- ._m01(Math.fma(m01, rm00, Math.fma(m11, rm01, m21 * rm02)))
- ._m02(Math.fma(m02, rm00, Math.fma(m12, rm01, m22 * rm02)))
- ._m03(m03())
- ._m10(Math.fma(m00, rm10, Math.fma(m10, rm11, m20 * rm12)))
- ._m11(Math.fma(m01, rm10, Math.fma(m11, rm11, m21 * rm12)))
- ._m12(Math.fma(m02, rm10, Math.fma(m12, rm11, m22 * rm12)))
- ._m13(m13())
- ._m20(Math.fma(m00, rm20, Math.fma(m10, rm21, m20 * rm22)))
- ._m21(Math.fma(m01, rm20, Math.fma(m11, rm21, m21 * rm22)))
- ._m22(Math.fma(m02, rm20, Math.fma(m12, rm21, m22 * rm22)))
- ._m23(m23())
- ._m30(Math.fma(m00, rm30, Math.fma(m10, rm31, Math.fma(m20, rm32, m30()))))
- ._m31(Math.fma(m01, rm30, Math.fma(m11, rm31, Math.fma(m21, rm32, m31()))))
- ._m32(Math.fma(m02, rm30, Math.fma(m12, rm31, Math.fma(m22, rm32, m32()))))
- ._m33(m33())
- ._properties(PROPERTY_AFFINE | (this.properties & right.properties() & PROPERTY_ORTHONORMAL));
- }
-
- public Matrix4f mulTranslationAffine(Matrix4fc right, Matrix4f dest) {
- return dest
- ._m00(right.m00())
- ._m01(right.m01())
- ._m02(right.m02())
- ._m03(m03())
- ._m10(right.m10())
- ._m11(right.m11())
- ._m12(right.m12())
- ._m13(m13())
- ._m20(right.m20())
- ._m21(right.m21())
- ._m22(right.m22())
- ._m23(m23())
- ._m30(right.m30() + m30())
- ._m31(right.m31() + m31())
- ._m32(right.m32() + m32())
- ._m33(m33())
- ._properties(PROPERTY_AFFINE | (right.properties() & PROPERTY_ORTHONORMAL));
- }
-
- /**
- * Multiply this
orthographic projection matrix by the supplied {@link #isAffine() affine} view
matrix.
- * M
is this
matrix and V
the view
matrix,
- * then the new matrix will be M * V
. So when transforming a
- * vector v
with the new matrix by using M * V * v
, the
- * transformation of the view
matrix will be applied first!
- *
- * @param view
- * the affine matrix which to multiply this
with
- * @return this
- */
- public Matrix4f mulOrthoAffine(Matrix4fc view) {
- return mulOrthoAffine(view, this);
- }
-
- public Matrix4f mulOrthoAffine(Matrix4fc view, Matrix4f dest) {
- float nm00 = m00() * view.m00();
- float nm01 = m11() * view.m01();
- float nm02 = m22() * view.m02();
- float nm10 = m00() * view.m10();
- float nm11 = m11() * view.m11();
- float nm12 = m22() * view.m12();
- float nm20 = m00() * view.m20();
- float nm21 = m11() * view.m21();
- float nm22 = m22() * view.m22();
- float nm30 = m00() * view.m30() + m30();
- float nm31 = m11() * view.m31() + m31();
- float nm32 = m22() * view.m32() + m32();
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(0.0f)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(0.0f)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(0.0f)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE);
- }
-
- /**
- * Component-wise add the upper 4x3 submatrices of this
and other
- * by first multiplying each component of other
's 4x3 submatrix by otherFactor
and
- * adding that result to this
.
- * other
will not be changed.
- *
- * @param other
- * the other matrix
- * @param otherFactor
- * the factor to multiply each of the other matrix's 4x3 components
- * @return this
- */
- public Matrix4f fma4x3(Matrix4fc other, float otherFactor) {
- return fma4x3(other, otherFactor, this);
- }
-
- public Matrix4f fma4x3(Matrix4fc other, float otherFactor, Matrix4f dest) {
- dest._m00(Math.fma(other.m00(), otherFactor, m00()))
- ._m01(Math.fma(other.m01(), otherFactor, m01()))
- ._m02(Math.fma(other.m02(), otherFactor, m02()))
- ._m03(m03())
- ._m10(Math.fma(other.m10(), otherFactor, m10()))
- ._m11(Math.fma(other.m11(), otherFactor, m11()))
- ._m12(Math.fma(other.m12(), otherFactor, m12()))
- ._m13(m13())
- ._m20(Math.fma(other.m20(), otherFactor, m20()))
- ._m21(Math.fma(other.m21(), otherFactor, m21()))
- ._m22(Math.fma(other.m22(), otherFactor, m22()))
- ._m23(m23())
- ._m30(Math.fma(other.m30(), otherFactor, m30()))
- ._m31(Math.fma(other.m31(), otherFactor, m31()))
- ._m32(Math.fma(other.m32(), otherFactor, m32()))
- ._m33(m33())
- ._properties(0);
- return dest;
- }
-
- /**
- * Component-wise add this
and other
.
- *
- * @param other
- * the other addend
- * @return this
- */
- public Matrix4f add(Matrix4fc other) {
- return add(other, this);
- }
-
- public Matrix4f add(Matrix4fc other, Matrix4f dest) {
- dest._m00(m00() + other.m00())
- ._m01(m01() + other.m01())
- ._m02(m02() + other.m02())
- ._m03(m03() + other.m03())
- ._m10(m10() + other.m10())
- ._m11(m11() + other.m11())
- ._m12(m12() + other.m12())
- ._m13(m13() + other.m13())
- ._m20(m20() + other.m20())
- ._m21(m21() + other.m21())
- ._m22(m22() + other.m22())
- ._m23(m23() + other.m23())
- ._m30(m30() + other.m30())
- ._m31(m31() + other.m31())
- ._m32(m32() + other.m32())
- ._m33(m33() + other.m33())
- ._properties(0);
- return dest;
- }
-
- /**
- * Component-wise subtract subtrahend
from this
.
- *
- * @param subtrahend
- * the subtrahend
- * @return this
- */
- public Matrix4f sub(Matrix4fc subtrahend) {
- return sub(subtrahend, this);
- }
-
- public Matrix4f sub(Matrix4fc subtrahend, Matrix4f dest) {
- dest._m00(m00() - subtrahend.m00())
- ._m01(m01() - subtrahend.m01())
- ._m02(m02() - subtrahend.m02())
- ._m03(m03() - subtrahend.m03())
- ._m10(m10() - subtrahend.m10())
- ._m11(m11() - subtrahend.m11())
- ._m12(m12() - subtrahend.m12())
- ._m13(m13() - subtrahend.m13())
- ._m20(m20() - subtrahend.m20())
- ._m21(m21() - subtrahend.m21())
- ._m22(m22() - subtrahend.m22())
- ._m23(m23() - subtrahend.m23())
- ._m30(m30() - subtrahend.m30())
- ._m31(m31() - subtrahend.m31())
- ._m32(m32() - subtrahend.m32())
- ._m33(m33() - subtrahend.m33())
- ._properties(0);
- return dest;
- }
-
- /**
- * Component-wise multiply this
by other
.
- *
- * @param other
- * the other matrix
- * @return this
- */
- public Matrix4f mulComponentWise(Matrix4fc other) {
- return mulComponentWise(other, this);
- }
-
- public Matrix4f mulComponentWise(Matrix4fc other, Matrix4f dest) {
- dest._m00(m00() * other.m00())
- ._m01(m01() * other.m01())
- ._m02(m02() * other.m02())
- ._m03(m03() * other.m03())
- ._m10(m10() * other.m10())
- ._m11(m11() * other.m11())
- ._m12(m12() * other.m12())
- ._m13(m13() * other.m13())
- ._m20(m20() * other.m20())
- ._m21(m21() * other.m21())
- ._m22(m22() * other.m22())
- ._m23(m23() * other.m23())
- ._m30(m30() * other.m30())
- ._m31(m31() * other.m31())
- ._m32(m32() * other.m32())
- ._m33(m33() * other.m33())
- ._properties(0);
- return dest;
- }
-
- /**
- * Component-wise add the upper 4x3 submatrices of this
and other
.
- *
- * @param other
- * the other addend
- * @return this
- */
- public Matrix4f add4x3(Matrix4fc other) {
- return add4x3(other, this);
- }
-
- public Matrix4f add4x3(Matrix4fc other, Matrix4f dest) {
- dest._m00(m00() + other.m00())
- ._m01(m01() + other.m01())
- ._m02(m02() + other.m02())
- ._m03(m03())
- ._m10(m10() + other.m10())
- ._m11(m11() + other.m11())
- ._m12(m12() + other.m12())
- ._m13(m13())
- ._m20(m20() + other.m20())
- ._m21(m21() + other.m21())
- ._m22(m22() + other.m22())
- ._m23(m23())
- ._m30(m30() + other.m30())
- ._m31(m31() + other.m31())
- ._m32(m32() + other.m32())
- ._m33(m33())
- ._properties(0);
- return dest;
- }
-
- /**
- * Component-wise subtract the upper 4x3 submatrices of subtrahend
from this
.
- *
- * @param subtrahend
- * the subtrahend
- * @return this
- */
- public Matrix4f sub4x3(Matrix4f subtrahend) {
- return sub4x3(subtrahend, this);
- }
-
- public Matrix4f sub4x3(Matrix4fc subtrahend, Matrix4f dest) {
- dest._m00(m00() - subtrahend.m00())
- ._m01(m01() - subtrahend.m01())
- ._m02(m02() - subtrahend.m02())
- ._m03(m03())
- ._m10(m10() - subtrahend.m10())
- ._m11(m11() - subtrahend.m11())
- ._m12(m12() - subtrahend.m12())
- ._m13(m13())
- ._m20(m20() - subtrahend.m20())
- ._m21(m21() - subtrahend.m21())
- ._m22(m22() - subtrahend.m22())
- ._m23(m23())
- ._m30(m30() - subtrahend.m30())
- ._m31(m31() - subtrahend.m31())
- ._m32(m32() - subtrahend.m32())
- ._m33(m33())
- ._properties(0);
- return dest;
- }
-
- /**
- * Component-wise multiply the upper 4x3 submatrices of this
by other
.
- *
- * @param other
- * the other matrix
- * @return this
- */
- public Matrix4f mul4x3ComponentWise(Matrix4fc other) {
- return mul4x3ComponentWise(other, this);
- }
-
- public Matrix4f mul4x3ComponentWise(Matrix4fc other, Matrix4f dest) {
- dest._m00(m00() * other.m00())
- ._m01(m01() * other.m01())
- ._m02(m02() * other.m02())
- ._m03(m03())
- ._m10(m10() * other.m10())
- ._m11(m11() * other.m11())
- ._m12(m12() * other.m12())
- ._m13(m13())
- ._m20(m20() * other.m20())
- ._m21(m21() * other.m21())
- ._m22(m22() * other.m22())
- ._m23(m23())
- ._m30(m30() * other.m30())
- ._m31(m31() * other.m31())
- ._m32(m32() * other.m32())
- ._m33(m33())
- ._properties(0);
- return dest;
- }
-
- /**
- * Set the values within this matrix to the supplied float values. The matrix will look like this:
- *
- * m00, m10, m20, m30
- * m01, m11, m21, m31
- * m02, m12, m22, m32
- * m03, m13, m23, m33
- *
- * @param m00
- * the new value of m00
- * @param m01
- * the new value of m01
- * @param m02
- * the new value of m02
- * @param m03
- * the new value of m03
- * @param m10
- * the new value of m10
- * @param m11
- * the new value of m11
- * @param m12
- * the new value of m12
- * @param m13
- * the new value of m13
- * @param m20
- * the new value of m20
- * @param m21
- * the new value of m21
- * @param m22
- * the new value of m22
- * @param m23
- * the new value of m23
- * @param m30
- * the new value of m30
- * @param m31
- * the new value of m31
- * @param m32
- * the new value of m32
- * @param m33
- * the new value of m33
- * @return this
- */
- public Matrix4f set(float m00, float m01, float m02, float m03,
- float m10, float m11, float m12, float m13,
- float m20, float m21, float m22, float m23,
- float m30, float m31, float m32, float m33) {
- return this
- ._m00(m00)
- ._m10(m10)
- ._m20(m20)
- ._m30(m30)
- ._m01(m01)
- ._m11(m11)
- ._m21(m21)
- ._m31(m31)
- ._m02(m02)
- ._m12(m12)
- ._m22(m22)
- ._m32(m32)
- ._m03(m03)
- ._m13(m13)
- ._m23(m23)
- ._m33(m33)
- .determineProperties();
- }
-
- /**
- * Set the values in the matrix using a float array that contains the matrix elements in column-major order.
- *
- *
- * 0, 4, 8, 12
- * 1, 5, 9, 13
- * 2, 6, 10, 14
- * 3, 7, 11, 15
- *
- * @see #set(float[])
- *
- * @param m
- * the array to read the matrix values from
- * @param off
- * the offset into the array
- * @return this
- */
- public Matrix4f set(float m[], int off) {
- MemUtil.INSTANCE.copy(m, off, this);
- return determineProperties();
- }
-
- /**
- * Set the values in the matrix using a float array that contains the matrix elements in column-major order.
- *
- *
- * 0, 4, 8, 12
- * 1, 5, 9, 13
- * 2, 6, 10, 14
- * 3, 7, 11, 15
- *
- * @see #set(float[], int)
- *
- * @param m
- * the array to read the matrix values from
- * @return this
- */
- public Matrix4f set(float m[]) {
- return set(m, 0);
- }
-
- /**
- * Set the values in the matrix using a float array that contains the matrix elements in row-major order.
- *
- *
- * 0, 1, 2, 3
- * 4, 5, 6, 7
- * 8, 9, 10, 11
- * 12, 13, 14, 15
- *
- * @see #setTransposed(float[])
- *
- * @param m
- * the array to read the matrix values from
- * @param off
- * the offset into the array
- * @return this
- */
- public Matrix4f setTransposed(float m[], int off) {
- MemUtil.INSTANCE.copyTransposed(m, off, this);
- return determineProperties();
- }
-
- /**
- * Set the values in the matrix using a float array that contains the matrix elements in row-major order.
- *
- *
- * 0, 1, 2, 3
- * 4, 5, 6, 7
- * 8, 9, 10, 11
- * 12, 13, 14, 15
- *
- * @see #setTransposed(float[], int)
- *
- * @param m
- * the array to read the matrix values from
- * @return this
- */
- public Matrix4f setTransposed(float m[]) {
- return setTransposed(m, 0);
- }
-
- /**
- * Set the values of this matrix by reading 16 float values from the given {@link FloatBuffer} in column-major order,
- * starting at its current position.
- * this
matrix represents an {@link #isAffine() affine} transformation, such as translation, rotation, scaling and shearing,
- * and thus its last row is equal to (0, 0, 0, 1)
, then {@link #invertAffine()} can be used instead of this method.
- *
- * @see #invertAffine()
- *
- * @return this
- */
- public Matrix4f invert() {
- return invert(this);
- }
-
- /**
- * If this
is a perspective projection matrix obtained via one of the {@link #perspective(float, float, float, float) perspective()} methods
- * or via {@link #setPerspective(float, float, float, float) setPerspective()}, that is, if this
is a symmetrical perspective frustum transformation,
- * then this method builds the inverse of this
and stores it into the given dest
.
- * this
- * @return dest
- */
- public Matrix4f invertPerspective(Matrix4f dest) {
- float a = 1.0f / (m00() * m11());
- float l = -1.0f / (m23() * m32());
- return dest
- .set(m11() * a, 0, 0, 0,
- 0, m00() * a, 0, 0,
- 0, 0, 0, -m23() * l,
- 0, 0, -m32() * l, m22() * l)
- ._properties(0);
- }
-
- /**
- * If this
is a perspective projection matrix obtained via one of the {@link #perspective(float, float, float, float) perspective()} methods
- * or via {@link #setPerspective(float, float, float, float) setPerspective()}, that is, if this
is a symmetrical perspective frustum transformation,
- * then this method builds the inverse of this
.
- * this
is an arbitrary perspective projection matrix obtained via one of the {@link #frustum(float, float, float, float, float, float) frustum()} methods
- * or via {@link #setFrustum(float, float, float, float, float, float) setFrustum()},
- * then this method builds the inverse of this
and stores it into the given dest
.
- * this
- * @return dest
- */
- public Matrix4f invertFrustum(Matrix4f dest) {
- float invM00 = 1.0f / m00();
- float invM11 = 1.0f / m11();
- float invM23 = 1.0f / m23();
- float invM32 = 1.0f / m32();
- return dest
- .set(invM00, 0, 0, 0,
- 0, invM11, 0, 0,
- 0, 0, 0, invM32,
- -m20() * invM00 * invM23, -m21() * invM11 * invM23, invM23, -m22() * invM23 * invM32);
- }
-
- /**
- * If this
is an arbitrary perspective projection matrix obtained via one of the {@link #frustum(float, float, float, float, float, float) frustum()} methods
- * or via {@link #setFrustum(float, float, float, float, float, float) setFrustum()},
- * then this method builds the inverse of this
.
- * this
orthographic projection matrix.
- * this
is a perspective projection matrix obtained via one of the {@link #perspective(float, float, float, float) perspective()} methods
- * or via {@link #setPerspective(float, float, float, float) setPerspective()}, that is, if this
is a symmetrical perspective frustum transformation
- * and the given view
matrix is {@link #isAffine() affine} and has unit scaling (for example by being obtained via {@link #lookAt(float, float, float, float, float, float, float, float, float) lookAt()}),
- * then this method builds the inverse of this * view
and stores it into the given dest
.
- * this
and view
mentioned above, this method is equivalent to the following code:
- *
- * dest.set(this).mul(view).invert();
- *
- *
- * @param view
- * the view transformation (must be {@link #isAffine() affine} and have unit scaling)
- * @param dest
- * will hold the inverse of this * view
- * @return dest
- */
- public Matrix4f invertPerspectiveView(Matrix4fc view, Matrix4f dest) {
- float a = 1.0f / (m00() * m11());
- float l = -1.0f / (m23() * m32());
- float pm00 = m11() * a;
- float pm11 = m00() * a;
- float pm23 = -m23() * l;
- float pm32 = -m32() * l;
- float pm33 = m22() * l;
- float vm30 = -view.m00() * view.m30() - view.m01() * view.m31() - view.m02() * view.m32();
- float vm31 = -view.m10() * view.m30() - view.m11() * view.m31() - view.m12() * view.m32();
- float vm32 = -view.m20() * view.m30() - view.m21() * view.m31() - view.m22() * view.m32();
- float nm10 = view.m01() * pm11;
- float nm30 = view.m02() * pm32 + vm30 * pm33;
- float nm31 = view.m12() * pm32 + vm31 * pm33;
- float nm32 = view.m22() * pm32 + vm32 * pm33;
- return dest
- ._m00(view.m00() * pm00)
- ._m01(view.m10() * pm00)
- ._m02(view.m20() * pm00)
- ._m03(0.0f)
- ._m10(nm10)
- ._m11(view.m11() * pm11)
- ._m12(view.m21() * pm11)
- ._m13(0.0f)
- ._m20(vm30 * pm23)
- ._m21(vm31 * pm23)
- ._m22(vm32 * pm23)
- ._m23(pm23)
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(pm33)
- ._properties(0);
- }
-
- public Matrix4f invertAffine(Matrix4f dest) {
- float m11m00 = m00() * m11(), m10m01 = m01() * m10(), m10m02 = m02() * m10();
- float m12m00 = m00() * m12(), m12m01 = m01() * m12(), m11m02 = m02() * m11();
- float det = (m11m00 - m10m01) * m22() + (m10m02 - m12m00) * m21() + (m12m01 - m11m02) * m20();
- float s = 1.0f / det;
- float m10m22 = m10() * m22(), m10m21 = m10() * m21(), m11m22 = m11() * m22();
- float m11m20 = m11() * m20(), m12m21 = m12() * m21(), m12m20 = m12() * m20();
- float m20m02 = m20() * m02(), m20m01 = m20() * m01(), m21m02 = m21() * m02();
- float m21m00 = m21() * m00(), m22m01 = m22() * m01(), m22m00 = m22() * m00();
- float nm31 = (m20m02 * m31() - m20m01 * m32() + m21m00 * m32() - m21m02 * m30() + m22m01 * m30() - m22m00 * m31()) * s;
- float nm32 = (m11m02 * m30() - m12m01 * m30() + m12m00 * m31() - m10m02 * m31() + m10m01 * m32() - m11m00 * m32()) * s;
- return dest
- ._m00((m11m22 - m12m21) * s)
- ._m01((m21m02 - m22m01) * s)
- ._m02((m12m01 - m11m02) * s)
- ._m03(0.0f)
- ._m10((m12m20 - m10m22) * s)
- ._m11((m22m00 - m20m02) * s)
- ._m12((m10m02 - m12m00) * s)
- ._m13(0.0f)
- ._m20((m10m21 - m11m20) * s)
- ._m21((m20m01 - m21m00) * s)
- ._m22((m11m00 - m10m01) * s)
- ._m23(0.0f)
- ._m30((m10m22 * m31() - m10m21 * m32() + m11m20 * m32() - m11m22 * m30() + m12m21 * m30() - m12m20 * m31()) * s)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE);
- }
-
- /**
- * Invert this matrix by assuming that it is an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
).
- *
- * @return this
- */
- public Matrix4f invertAffine() {
- return invertAffine(this);
- }
-
- public Matrix4f transpose(Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.identity();
- else if (this != dest)
- return transposeNonThisGeneric(dest);
- return transposeThisGeneric(dest);
- }
- private Matrix4f transposeNonThisGeneric(Matrix4f dest) {
- return dest
- ._m00(m00())
- ._m01(m10())
- ._m02(m20())
- ._m03(m30())
- ._m10(m01())
- ._m11(m11())
- ._m12(m21())
- ._m13(m31())
- ._m20(m02())
- ._m21(m12())
- ._m22(m22())
- ._m23(m32())
- ._m30(m03())
- ._m31(m13())
- ._m32(m23())
- ._m33(m33())
- ._properties(0);
- }
- private Matrix4f transposeThisGeneric(Matrix4f dest) {
- float nm10 = m01();
- float nm20 = m02();
- float nm21 = m12();
- float nm30 = m03();
- float nm31 = m13();
- float nm32 = m23();
- return dest
- ._m01(m10())
- ._m02(m20())
- ._m03(m30())
- ._m10(nm10)
- ._m12(m21())
- ._m13(m31())
- ._m20(nm20)
- ._m21(nm21)
- ._m23(m32())
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._properties(0);
- }
-
- /**
- * Transpose only the upper left 3x3 submatrix of this matrix.
- * (m30, m31, m32)
of this matrix to the given values (x, y, z)
.
- * (m30, m31, m32)
of this matrix to the values (xyz.x, xyz.y, xyz.z)
.
- * (x, y, z)
- * @return this
- */
- public Matrix4f setTranslation(Vector3fc xyz) {
- return setTranslation(xyz.x(), xyz.y(), xyz.z());
- }
-
- public Vector3f getTranslation(Vector3f dest) {
- dest.x = m30();
- dest.y = m31();
- dest.z = m32();
- return dest;
- }
-
- public Vector3f getScale(Vector3f dest) {
- dest.x = Math.sqrt(m00() * m00() + m01() * m01() + m02() * m02());
- dest.y = Math.sqrt(m10() * m10() + m11() * m11() + m12() * m12());
- dest.z = Math.sqrt(m20() * m20() + m21() * m21() + m22() * m22());
- return dest;
- }
-
- /**
- * Return a string representation of this matrix.
- * 0.000E0;-
".
- *
- * @return the string representation
- */
- public String toString() {
- String str = toString(Options.NUMBER_FORMAT);
- StringBuffer res = new StringBuffer();
- int eIndex = Integer.MIN_VALUE;
- for (int i = 0; i < str.length(); i++) {
- char c = str.charAt(i);
- if (c == 'E') {
- eIndex = i;
- } else if (c == ' ' && eIndex == i - 1) {
- // workaround Java 1.4 DecimalFormat bug
- res.append('+');
- continue;
- } else if (Character.isDigit(c) && eIndex == i - 1) {
- res.append('+');
- }
- res.append(c);
- }
- return res.toString();
- }
-
- /**
- * Return a string representation of this matrix by formatting the matrix elements with the given {@link NumberFormat}.
- *
- * @param formatter
- * the {@link NumberFormat} used to format the matrix values with
- * @return the string representation
- */
- public String toString(NumberFormat formatter) {
- return Runtime.format(m00(), formatter) + " " + Runtime.format(m10(), formatter) + " " + Runtime.format(m20(), formatter) + " " + Runtime.format(m30(), formatter) + "\n"
- + Runtime.format(m01(), formatter) + " " + Runtime.format(m11(), formatter) + " " + Runtime.format(m21(), formatter) + " " + Runtime.format(m31(), formatter) + "\n"
- + Runtime.format(m02(), formatter) + " " + Runtime.format(m12(), formatter) + " " + Runtime.format(m22(), formatter) + " " + Runtime.format(m32(), formatter) + "\n"
- + Runtime.format(m03(), formatter) + " " + Runtime.format(m13(), formatter) + " " + Runtime.format(m23(), formatter) + " " + Runtime.format(m33(), formatter) + "\n";
- }
-
- /**
- * Get the current values of this
matrix and store them into
- * dest
.
- * 0
.
- *
- * @return this
- */
- public Matrix4f zero() {
- MemUtil.INSTANCE.zero(this);
- return _properties(0);
- }
-
- /**
- * Set this matrix to be a simple scale matrix, which scales all axes uniformly by the given factor.
- * xyz.x
, xyz.y
and xyz.z
respectively.
- * axis
vector needs to be a unit vector.
- * +X
towards (dirX, dirY)
.
- * (dirX, dirY)
must be a unit vector.
- *
- * @param dirX
- * the x component of the normalized direction
- * @param dirY
- * the y component of the normalized direction
- * @return this
- */
- public Matrix4f rotationTowardsXY(float dirX, float dirY) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- return this._m00(dirY)._m01(dirX)._m10(-dirX)._m11(dirY)._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set this matrix to a rotation of angleX
radians about the X axis, followed by a rotation
- * of angleY
radians about the Y axis and followed by a rotation of angleZ
radians about the Z axis.
- * rotationX(angleX).rotateY(angleY).rotateZ(angleZ)
- *
- * @param angleX
- * the angle to rotate about X
- * @param angleY
- * the angle to rotate about Y
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix4f rotationXYZ(float angleX, float angleY, float angleZ) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- float nm01 = -sinX * -sinY, nm02 = cosX * -sinY;
- return this
- ._m20(sinY)
- ._m21(-sinX * cosY)
- ._m22(cosX * cosY)
- ._m00(cosY * cosZ)
- ._m01(nm01 * cosZ + cosX * sinZ)
- ._m02(nm02 * cosZ + sinX * sinZ)
- ._m10(cosY * -sinZ)
- ._m11(nm01 * -sinZ + cosX * cosZ)
- ._m12(nm02 * -sinZ + sinX * cosZ)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set this matrix to a rotation of angleZ
radians about the Z axis, followed by a rotation
- * of angleY
radians about the Y axis and followed by a rotation of angleX
radians about the X axis.
- * rotationZ(angleZ).rotateY(angleY).rotateX(angleX)
- *
- * @param angleZ
- * the angle to rotate about Z
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @return this
- */
- public Matrix4f rotationZYX(float angleZ, float angleY, float angleX) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float nm20 = cosZ * sinY;
- float nm21 = sinZ * sinY;
- return this
- ._m00(cosZ * cosY)
- ._m01(sinZ * cosY)
- ._m02(-sinY)
- ._m03(0.0f)
- ._m10(-sinZ * cosX + nm20 * sinX)
- ._m11(cosZ * cosX + nm21 * sinX)
- ._m12(cosY * sinX)
- ._m13(0.0f)
- ._m20(-sinZ * -sinX + nm20 * cosX)
- ._m21(cosZ * -sinX + nm21 * cosX)
- ._m22(cosY * cosX)
- ._m23(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set this matrix to a rotation of angleY
radians about the Y axis, followed by a rotation
- * of angleX
radians about the X axis and followed by a rotation of angleZ
radians about the Z axis.
- * rotationY(angleY).rotateX(angleX).rotateZ(angleZ)
- *
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix4f rotationYXZ(float angleY, float angleX, float angleZ) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float nm10 = sinY * sinX, nm12 = cosY * sinX;
- return this
- ._m20(sinY * cosX)
- ._m21(-sinX)
- ._m22(cosY * cosX)
- ._m23(0.0f)
- ._m00(cosY * cosZ + nm10 * sinZ)
- ._m01(cosX * sinZ)
- ._m02(-sinY * cosZ + nm12 * sinZ)
- ._m03(0.0f)
- ._m10(cosY * -sinZ + nm10 * cosZ)
- ._m11(cosX * cosZ)
- ._m12(-sinY * -sinZ + nm12 * cosZ)
- ._m13(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set only the upper left 3x3 submatrix of this matrix to a rotation of angleX
radians about the X axis, followed by a rotation
- * of angleY
radians about the Y axis and followed by a rotation of angleZ
radians about the Z axis.
- * angleZ
radians about the Z axis, followed by a rotation
- * of angleY
radians about the Y axis and followed by a rotation of angleX
radians about the X axis.
- * angleY
radians about the Y axis, followed by a rotation
- * of angleX
radians about the X axis and followed by a rotation of angleZ
radians about the Z axis.
- * this
matrix to T * R * S
, where T
is a translation by the given (tx, ty, tz)
,
- * R
is a rotation transformation specified by the quaternion (qx, qy, qz, qw)
, and S
is a scaling transformation
- * which scales the three axes x, y and z by (sx, sy, sz)
.
- * translation(tx, ty, tz).rotate(quat).scale(sx, sy, sz)
- *
- * @see #translation(float, float, float)
- * @see #rotate(Quaternionfc)
- * @see #scale(float, float, float)
- *
- * @param tx
- * the number of units by which to translate the x-component
- * @param ty
- * the number of units by which to translate the y-component
- * @param tz
- * the number of units by which to translate the z-component
- * @param qx
- * the x-coordinate of the vector part of the quaternion
- * @param qy
- * the y-coordinate of the vector part of the quaternion
- * @param qz
- * the z-coordinate of the vector part of the quaternion
- * @param qw
- * the scalar part of the quaternion
- * @param sx
- * the scaling factor for the x-axis
- * @param sy
- * the scaling factor for the y-axis
- * @param sz
- * the scaling factor for the z-axis
- * @return this
- */
- public Matrix4f translationRotateScale(float tx, float ty, float tz,
- float qx, float qy, float qz, float qw,
- float sx, float sy, float sz) {
- float dqx = qx + qx;
- float dqy = qy + qy;
- float dqz = qz + qz;
- float q00 = dqx * qx;
- float q11 = dqy * qy;
- float q22 = dqz * qz;
- float q01 = dqx * qy;
- float q02 = dqx * qz;
- float q03 = dqx * qw;
- float q12 = dqy * qz;
- float q13 = dqy * qw;
- float q23 = dqz * qw;
- boolean one = Math.absEqualsOne(sx) && Math.absEqualsOne(sy) && Math.absEqualsOne(sz);
- return this
- ._m00(sx - (q11 + q22) * sx)
- ._m01((q01 + q23) * sx)
- ._m02((q02 - q13) * sx)
- ._m03(0.0f)
- ._m10((q01 - q23) * sy)
- ._m11(sy - (q22 + q00) * sy)
- ._m12((q12 + q03) * sy)
- ._m13(0.0f)
- ._m20((q02 + q13) * sz)
- ._m21((q12 - q03) * sz)
- ._m22(sz - (q11 + q00) * sz)
- ._m23(0.0f)
- ._m30(tx)
- ._m31(ty)
- ._m32(tz)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | (one ? PROPERTY_ORTHONORMAL : 0));
- }
-
- /**
- * Set this
matrix to T * R * S
, where T
is the given translation
,
- * R
is a rotation transformation specified by the given quaternion, and S
is a scaling transformation
- * which scales the axes by scale
.
- * translation(translation).rotate(quat).scale(scale)
- *
- * @see #translation(Vector3fc)
- * @see #rotate(Quaternionfc)
- * @see #scale(Vector3fc)
- *
- * @param translation
- * the translation
- * @param quat
- * the quaternion representing a rotation
- * @param scale
- * the scaling factors
- * @return this
- */
- public Matrix4f translationRotateScale(Vector3fc translation,
- Quaternionfc quat,
- Vector3fc scale) {
- return translationRotateScale(translation.x(), translation.y(), translation.z(), quat.x(), quat.y(), quat.z(), quat.w(), scale.x(), scale.y(), scale.z());
- }
-
- /**
- * Set this
matrix to T * R * S
, where T
is a translation by the given (tx, ty, tz)
,
- * R
is a rotation transformation specified by the quaternion (qx, qy, qz, qw)
, and S
is a scaling transformation
- * which scales all three axes by scale
.
- * translation(tx, ty, tz).rotate(quat).scale(scale)
- *
- * @see #translation(float, float, float)
- * @see #rotate(Quaternionfc)
- * @see #scale(float)
- *
- * @param tx
- * the number of units by which to translate the x-component
- * @param ty
- * the number of units by which to translate the y-component
- * @param tz
- * the number of units by which to translate the z-component
- * @param qx
- * the x-coordinate of the vector part of the quaternion
- * @param qy
- * the y-coordinate of the vector part of the quaternion
- * @param qz
- * the z-coordinate of the vector part of the quaternion
- * @param qw
- * the scalar part of the quaternion
- * @param scale
- * the scaling factor for all three axes
- * @return this
- */
- public Matrix4f translationRotateScale(float tx, float ty, float tz,
- float qx, float qy, float qz, float qw,
- float scale) {
- return translationRotateScale(tx, ty, tz, qx, qy, qz, qw, scale, scale, scale);
- }
-
- /**
- * Set this
matrix to T * R * S
, where T
is the given translation
,
- * R
is a rotation transformation specified by the given quaternion, and S
is a scaling transformation
- * which scales all three axes by scale
.
- * translation(translation).rotate(quat).scale(scale)
- *
- * @see #translation(Vector3fc)
- * @see #rotate(Quaternionfc)
- * @see #scale(float)
- *
- * @param translation
- * the translation
- * @param quat
- * the quaternion representing a rotation
- * @param scale
- * the scaling factors
- * @return this
- */
- public Matrix4f translationRotateScale(Vector3fc translation,
- Quaternionfc quat,
- float scale) {
- return translationRotateScale(translation.x(), translation.y(), translation.z(), quat.x(), quat.y(), quat.z(), quat.w(), scale, scale, scale);
- }
-
- /**
- * Set this
matrix to (T * R * S)-1
, where T
is a translation by the given (tx, ty, tz)
,
- * R
is a rotation transformation specified by the quaternion (qx, qy, qz, qw)
, and S
is a scaling transformation
- * which scales the three axes x, y and z by (sx, sy, sz)
.
- * translationRotateScale(...).invert()
- *
- * @see #translationRotateScale(float, float, float, float, float, float, float, float, float, float)
- * @see #invert()
- *
- * @param tx
- * the number of units by which to translate the x-component
- * @param ty
- * the number of units by which to translate the y-component
- * @param tz
- * the number of units by which to translate the z-component
- * @param qx
- * the x-coordinate of the vector part of the quaternion
- * @param qy
- * the y-coordinate of the vector part of the quaternion
- * @param qz
- * the z-coordinate of the vector part of the quaternion
- * @param qw
- * the scalar part of the quaternion
- * @param sx
- * the scaling factor for the x-axis
- * @param sy
- * the scaling factor for the y-axis
- * @param sz
- * the scaling factor for the z-axis
- * @return this
- */
- public Matrix4f translationRotateScaleInvert(float tx, float ty, float tz,
- float qx, float qy, float qz, float qw,
- float sx, float sy, float sz) {
- boolean one = Math.absEqualsOne(sx) && Math.absEqualsOne(sy) && Math.absEqualsOne(sz);
- if (one)
- return translationRotateInvert(tx, ty, tz, qx, qy, qz, qw);
- float nqx = -qx, nqy = -qy, nqz = -qz;
- float dqx = nqx + nqx;
- float dqy = nqy + nqy;
- float dqz = nqz + nqz;
- float q00 = dqx * nqx;
- float q11 = dqy * nqy;
- float q22 = dqz * nqz;
- float q01 = dqx * nqy;
- float q02 = dqx * nqz;
- float q03 = dqx * qw;
- float q12 = dqy * nqz;
- float q13 = dqy * qw;
- float q23 = dqz * qw;
- float isx = 1/sx, isy = 1/sy, isz = 1/sz;
- return this
- ._m00(isx * (1.0f - q11 - q22))
- ._m01(isy * (q01 + q23))
- ._m02(isz * (q02 - q13))
- ._m03(0.0f)
- ._m10(isx * (q01 - q23))
- ._m11(isy * (1.0f - q22 - q00))
- ._m12(isz * (q12 + q03))
- ._m13(0.0f)
- ._m20(isx * (q02 + q13))
- ._m21(isy * (q12 - q03))
- ._m22(isz * (1.0f - q11 - q00))
- ._m23(0.0f)
- ._m30(-m00() * tx - m10() * ty - m20() * tz)
- ._m31(-m01() * tx - m11() * ty - m21() * tz)
- ._m32(-m02() * tx - m12() * ty - m22() * tz)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE);
- }
-
- /**
- * Set this
matrix to (T * R * S)-1
, where T
is the given translation
,
- * R
is a rotation transformation specified by the given quaternion, and S
is a scaling transformation
- * which scales the axes by scale
.
- * translationRotateScale(...).invert()
- *
- * @see #translationRotateScale(Vector3fc, Quaternionfc, Vector3fc)
- * @see #invert()
- *
- * @param translation
- * the translation
- * @param quat
- * the quaternion representing a rotation
- * @param scale
- * the scaling factors
- * @return this
- */
- public Matrix4f translationRotateScaleInvert(Vector3fc translation,
- Quaternionfc quat,
- Vector3fc scale) {
- return translationRotateScaleInvert(translation.x(), translation.y(), translation.z(), quat.x(), quat.y(), quat.z(), quat.w(), scale.x(), scale.y(), scale.z());
- }
-
- /**
- * Set this
matrix to (T * R * S)-1
, where T
is the given translation
,
- * R
is a rotation transformation specified by the given quaternion, and S
is a scaling transformation
- * which scales all three axes by scale
.
- * translationRotateScale(...).invert()
- *
- * @see #translationRotateScale(Vector3fc, Quaternionfc, float)
- * @see #invert()
- *
- * @param translation
- * the translation
- * @param quat
- * the quaternion representing a rotation
- * @param scale
- * the scaling factors
- * @return this
- */
- public Matrix4f translationRotateScaleInvert(Vector3fc translation,
- Quaternionfc quat,
- float scale) {
- return translationRotateScaleInvert(translation.x(), translation.y(), translation.z(), quat.x(), quat.y(), quat.z(), quat.w(), scale, scale, scale);
- }
-
- /**
- * Set this
matrix to T * R * S * M
, where T
is a translation by the given (tx, ty, tz)
,
- * R
is a rotation - and possibly scaling - transformation specified by the quaternion (qx, qy, qz, qw)
, S
is a scaling transformation
- * which scales the three axes x, y and z by (sx, sy, sz)
and M
is an {@link #isAffine() affine} matrix.
- * M
will be applied first, then the scaling, then rotation and
- * at last the translation.
- * translation(tx, ty, tz).rotate(quat).scale(sx, sy, sz).mulAffine(m)
- *
- * @see #translation(float, float, float)
- * @see #rotate(Quaternionfc)
- * @see #scale(float, float, float)
- * @see #mulAffine(Matrix4fc)
- *
- * @param tx
- * the number of units by which to translate the x-component
- * @param ty
- * the number of units by which to translate the y-component
- * @param tz
- * the number of units by which to translate the z-component
- * @param qx
- * the x-coordinate of the vector part of the quaternion
- * @param qy
- * the y-coordinate of the vector part of the quaternion
- * @param qz
- * the z-coordinate of the vector part of the quaternion
- * @param qw
- * the scalar part of the quaternion
- * @param sx
- * the scaling factor for the x-axis
- * @param sy
- * the scaling factor for the y-axis
- * @param sz
- * the scaling factor for the z-axis
- * @param m
- * the {@link #isAffine() affine} matrix to multiply by
- * @return this
- */
- public Matrix4f translationRotateScaleMulAffine(float tx, float ty, float tz,
- float qx, float qy, float qz, float qw,
- float sx, float sy, float sz,
- Matrix4f m) {
- float w2 = qw * qw;
- float x2 = qx * qx;
- float y2 = qy * qy;
- float z2 = qz * qz;
- float zw = qz * qw;
- float xy = qx * qy;
- float xz = qx * qz;
- float yw = qy * qw;
- float yz = qy * qz;
- float xw = qx * qw;
- float nm00 = w2 + x2 - z2 - y2;
- float nm01 = xy + zw + zw + xy;
- float nm02 = xz - yw + xz - yw;
- float nm10 = -zw + xy - zw + xy;
- float nm11 = y2 - z2 + w2 - x2;
- float nm12 = yz + yz + xw + xw;
- float nm20 = yw + xz + xz + yw;
- float nm21 = yz + yz - xw - xw;
- float nm22 = z2 - y2 - x2 + w2;
- float m00 = nm00 * m.m00() + nm10 * m.m01() + nm20 * m.m02();
- float m01 = nm01 * m.m00() + nm11 * m.m01() + nm21 * m.m02();
- this._m02(nm02 * m.m00() + nm12 * m.m01() + nm22 * m.m02())
- ._m00(m00)
- ._m01(m01)
- ._m03(0.0f);
- float m10 = nm00 * m.m10() + nm10 * m.m11() + nm20 * m.m12();
- float m11 = nm01 * m.m10() + nm11 * m.m11() + nm21 * m.m12();
- this._m12(nm02 * m.m10() + nm12 * m.m11() + nm22 * m.m12())
- ._m10(m10)
- ._m11(m11)
- ._m13(0.0f);
- float m20 = nm00 * m.m20() + nm10 * m.m21() + nm20 * m.m22();
- float m21 = nm01 * m.m20() + nm11 * m.m21() + nm21 * m.m22();
- this._m22(nm02 * m.m20() + nm12 * m.m21() + nm22 * m.m22())
- ._m20(m20)
- ._m21(m21)
- ._m23(0.0f);
- float m30 = nm00 * m.m30() + nm10 * m.m31() + nm20 * m.m32() + tx;
- float m31 = nm01 * m.m30() + nm11 * m.m31() + nm21 * m.m32() + ty;
- this._m32(nm02 * m.m30() + nm12 * m.m31() + nm22 * m.m32() + tz)
- ._m30(m30)
- ._m31(m31)
- ._m33(1.0f);
- boolean one = Math.absEqualsOne(sx) && Math.absEqualsOne(sy) && Math.absEqualsOne(sz);
- return _properties(PROPERTY_AFFINE | (one && (m.properties & PROPERTY_ORTHONORMAL) != 0 ? PROPERTY_ORTHONORMAL : 0));
- }
-
- /**
- * Set this
matrix to T * R * S * M
, where T
is the given translation
,
- * R
is a rotation - and possibly scaling - transformation specified by the given quaternion, S
is a scaling transformation
- * which scales the axes by scale
and M
is an {@link #isAffine() affine} matrix.
- * M
will be applied first, then the scaling, then rotation and
- * at last the translation.
- * translation(translation).rotate(quat).scale(scale).mulAffine(m)
- *
- * @see #translation(Vector3fc)
- * @see #rotate(Quaternionfc)
- * @see #mulAffine(Matrix4fc)
- *
- * @param translation
- * the translation
- * @param quat
- * the quaternion representing a rotation
- * @param scale
- * the scaling factors
- * @param m
- * the {@link #isAffine() affine} matrix to multiply by
- * @return this
- */
- public Matrix4f translationRotateScaleMulAffine(Vector3fc translation,
- Quaternionfc quat,
- Vector3fc scale,
- Matrix4f m) {
- return translationRotateScaleMulAffine(translation.x(), translation.y(), translation.z(), quat.x(), quat.y(), quat.z(), quat.w(), scale.x(), scale.y(), scale.z(), m);
- }
-
- /**
- * Set this
matrix to T * R
, where T
is a translation by the given (tx, ty, tz)
and
- * R
is a rotation - and possibly scaling - transformation specified by the quaternion (qx, qy, qz, qw)
.
- * translation(tx, ty, tz).rotate(quat)
- *
- * @see #translation(float, float, float)
- * @see #rotate(Quaternionfc)
- *
- * @param tx
- * the number of units by which to translate the x-component
- * @param ty
- * the number of units by which to translate the y-component
- * @param tz
- * the number of units by which to translate the z-component
- * @param qx
- * the x-coordinate of the vector part of the quaternion
- * @param qy
- * the y-coordinate of the vector part of the quaternion
- * @param qz
- * the z-coordinate of the vector part of the quaternion
- * @param qw
- * the scalar part of the quaternion
- * @return this
- */
- public Matrix4f translationRotate(float tx, float ty, float tz, float qx, float qy, float qz, float qw) {
- float w2 = qw * qw;
- float x2 = qx * qx;
- float y2 = qy * qy;
- float z2 = qz * qz;
- float zw = qz * qw;
- float xy = qx * qy;
- float xz = qx * qz;
- float yw = qy * qw;
- float yz = qy * qz;
- float xw = qx * qw;
- return this
- ._m00(w2 + x2 - z2 - y2)
- ._m01(xy + zw + zw + xy)
- ._m02(xz - yw + xz - yw)
- ._m10(-zw + xy - zw + xy)
- ._m11(y2 - z2 + w2 - x2)
- ._m12(yz + yz + xw + xw)
- ._m20(yw + xz + xz + yw)
- ._m21(yz + yz - xw - xw)
- ._m22(z2 - y2 - x2 + w2)
- ._m30(tx)
- ._m31(ty)
- ._m32(tz)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set this
matrix to T * R
, where T
is a translation by the given (tx, ty, tz)
and
- * R
is a rotation - and possibly scaling - transformation specified by the given quaternion.
- * translation(tx, ty, tz).rotate(quat)
- *
- * @see #translation(float, float, float)
- * @see #rotate(Quaternionfc)
- *
- * @param tx
- * the number of units by which to translate the x-component
- * @param ty
- * the number of units by which to translate the y-component
- * @param tz
- * the number of units by which to translate the z-component
- * @param quat
- * the quaternion representing a rotation
- * @return this
- */
- public Matrix4f translationRotate(float tx, float ty, float tz, Quaternionfc quat) {
- return translationRotate(tx, ty, tz, quat.x(), quat.y(), quat.z(), quat.w());
- }
-
- /**
- * Set this
matrix to T * R
, where T
is the given translation
and
- * R
is a rotation transformation specified by the given quaternion.
- * translation(translation).rotate(quat)
- *
- * @see #translation(Vector3fc)
- * @see #rotate(Quaternionfc)
- *
- * @param translation
- * the translation
- * @param quat
- * the quaternion representing a rotation
- * @return this
- */
- public Matrix4f translationRotate(Vector3fc translation,
- Quaternionfc quat) {
- return translationRotate(translation.x(), translation.y(), translation.z(), quat.x(), quat.y(), quat.z(), quat.w());
- }
-
- /**
- * Set this
matrix to (T * R)-1
, where T
is a translation by the given (tx, ty, tz)
and
- * R
is a rotation transformation specified by the quaternion (qx, qy, qz, qw)
.
- * translationRotate(...).invert()
- *
- * @see #translationRotate(float, float, float, float, float, float, float)
- * @see #invert()
- *
- * @param tx
- * the number of units by which to translate the x-component
- * @param ty
- * the number of units by which to translate the y-component
- * @param tz
- * the number of units by which to translate the z-component
- * @param qx
- * the x-coordinate of the vector part of the quaternion
- * @param qy
- * the y-coordinate of the vector part of the quaternion
- * @param qz
- * the z-coordinate of the vector part of the quaternion
- * @param qw
- * the scalar part of the quaternion
- * @return this
- */
- public Matrix4f translationRotateInvert(float tx, float ty, float tz, float qx, float qy, float qz, float qw) {
- float nqx = -qx, nqy = -qy, nqz = -qz;
- float dqx = nqx + nqx;
- float dqy = nqy + nqy;
- float dqz = nqz + nqz;
- float q00 = dqx * nqx;
- float q11 = dqy * nqy;
- float q22 = dqz * nqz;
- float q01 = dqx * nqy;
- float q02 = dqx * nqz;
- float q03 = dqx * qw;
- float q12 = dqy * nqz;
- float q13 = dqy * qw;
- float q23 = dqz * qw;
- return this
- ._m00(1.0f - q11 - q22)
- ._m01(q01 + q23)
- ._m02(q02 - q13)
- ._m03(0.0f)
- ._m10(q01 - q23)
- ._m11(1.0f - q22 - q00)
- ._m12(q12 + q03)
- ._m13(0.0f)
- ._m20(q02 + q13)
- ._m21(q12 - q03)
- ._m22(1.0f - q11 - q00)
- ._m23(0.0f)
- ._m30(-m00() * tx - m10() * ty - m20() * tz)
- ._m31(-m01() * tx - m11() * ty - m21() * tz)
- ._m32(-m02() * tx - m12() * ty - m22() * tz)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
-
- /**
- * Set this
matrix to (T * R)-1
, where T
is the given translation
and
- * R
is a rotation transformation specified by the given quaternion.
- * translationRotate(...).invert()
- *
- * @see #translationRotate(Vector3fc, Quaternionfc)
- * @see #invert()
- *
- * @param translation
- * the translation
- * @param quat
- * the quaternion representing a rotation
- * @return this
- */
- public Matrix4f translationRotateInvert(Vector3fc translation,
- Quaternionfc quat) {
- return translationRotateInvert(translation.x(), translation.y(), translation.z(), quat.x(), quat.y(), quat.z(), quat.w());
- }
-
- /**
- * Set the upper left 3x3 submatrix of this {@link Matrix4f} to the given {@link Matrix3fc} and don't change the other elements.
- *
- * @param mat
- * the 3x3 matrix
- * @return this
- */
- public Matrix4f set3x3(Matrix3fc mat) {
- return
- set3x3Matrix3fc(mat).
- _properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- }
- private Matrix4f set3x3Matrix3fc(Matrix3fc mat) {
- return this
- ._m00(mat.m00())
- ._m01(mat.m01())
- ._m02(mat.m02())
- ._m10(mat.m10())
- ._m11(mat.m11())
- ._m12(mat.m12())
- ._m20(mat.m20())
- ._m21(mat.m21())
- ._m22(mat.m22());
- }
-
- public Vector4f transform(Vector4f v) {
- return v.mul(this);
- }
-
- public Vector4f transform(Vector4fc v, Vector4f dest) {
- return v.mul(this, dest);
- }
-
- public Vector4f transform(float x, float y, float z, float w, Vector4f dest) {
- return dest.set(x, y, z, w).mul(this);
- }
-
- public Vector4f transformTranspose(Vector4f v) {
- return v.mulTranspose(this);
- }
- public Vector4f transformTranspose(Vector4fc v, Vector4f dest) {
- return v.mulTranspose(this, dest);
- }
- public Vector4f transformTranspose(float x, float y, float z, float w, Vector4f dest) {
- return dest.set(x, y, z, w).mulTranspose(this);
- }
-
- public Vector4f transformProject(Vector4f v) {
- return v.mulProject(this);
- }
-
- public Vector4f transformProject(Vector4fc v, Vector4f dest) {
- return v.mulProject(this, dest);
- }
-
- public Vector4f transformProject(float x, float y, float z, float w, Vector4f dest) {
- return dest.set(x, y, z, w).mulProject(this);
- }
-
- public Vector3f transformProject(Vector4fc v, Vector3f dest) {
- return v.mulProject(this, dest);
- }
-
- public Vector3f transformProject(float x, float y, float z, float w, Vector3f dest) {
- return dest.set(x, y, z).mulProject(this, w, dest);
- }
-
- public Vector3f transformProject(Vector3f v) {
- return v.mulProject(this);
- }
-
- public Vector3f transformProject(Vector3fc v, Vector3f dest) {
- return v.mulProject(this, dest);
- }
-
- public Vector3f transformProject(float x, float y, float z, Vector3f dest) {
- return dest.set(x, y, z).mulProject(this);
- }
-
- public Vector3f transformPosition(Vector3f v) {
- return v.mulPosition(this);
- }
-
- public Vector3f transformPosition(Vector3fc v, Vector3f dest) {
- return transformPosition(v.x(), v.y(), v.z(), dest);
- }
-
- public Vector3f transformPosition(float x, float y, float z, Vector3f dest) {
- return dest.set(x, y, z).mulPosition(this);
- }
-
- public Vector3f transformDirection(Vector3f v) {
- return transformDirection(v.x, v.y, v.z, v);
- }
-
- public Vector3f transformDirection(Vector3fc v, Vector3f dest) {
- return transformDirection(v.x(), v.y(), v.z(), dest);
- }
-
- public Vector3f transformDirection(float x, float y, float z, Vector3f dest) {
- return dest.set(x, y, z).mulDirection(this);
- }
-
- public Vector4f transformAffine(Vector4f v) {
- return v.mulAffine(this, v);
- }
-
- public Vector4f transformAffine(Vector4fc v, Vector4f dest) {
- return transformAffine(v.x(), v.y(), v.z(), v.w(), dest);
- }
-
- public Vector4f transformAffine(float x, float y, float z, float w, Vector4f dest) {
- return dest.set(x, y, z, w).mulAffine(this, dest);
- }
-
- public Matrix4f scale(Vector3fc xyz, Matrix4f dest) {
- return scale(xyz.x(), xyz.y(), xyz.z(), dest);
- }
-
- /**
- * Apply scaling to this matrix by scaling the base axes by the given xyz.x
,
- * xyz.y
and xyz.z
factors, respectively.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- *
- * @param xyz
- * the factors of the x, y and z component, respectively
- * @return this
- */
- public Matrix4f scale(Vector3fc xyz) {
- return scale(xyz.x(), xyz.y(), xyz.z(), this);
- }
-
- public Matrix4f scale(float xyz, Matrix4f dest) {
- return scale(xyz, xyz, xyz, dest);
- }
-
- /**
- * Apply scaling to this matrix by uniformly scaling all base axes by the given xyz
factor.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- * x
and the Y axis by y
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @return this
- */
- public Matrix4f scaleXY(float x, float y) {
- return scale(x, y, 1.0f);
- }
-
- public Matrix4f scale(float x, float y, float z, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.scaling(x, y, z);
- return scaleGeneric(x, y, z, dest);
- }
- private Matrix4f scaleGeneric(float x, float y, float z, Matrix4f dest) {
- boolean one = Math.absEqualsOne(x) && Math.absEqualsOne(y) && Math.absEqualsOne(z);
- return dest
- ._m00(m00() * x)
- ._m01(m01() * x)
- ._m02(m02() * x)
- ._m03(m03() * x)
- ._m10(m10() * y)
- ._m11(m11() * y)
- ._m12(m12() * y)
- ._m13(m13() * y)
- ._m20(m20() * z)
- ._m21(m21() * z)
- ._m22(m22() * z)
- ._m23(m23() * z)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION
- | (one ? 0 : PROPERTY_ORTHONORMAL)));
- }
-
- /**
- * Apply scaling to this matrix by scaling the base axes by the given sx,
- * sy and sz factors.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @param z
- * the factor of the z component
- * @return this
- */
- public Matrix4f scale(float x, float y, float z) {
- return scale(x, y, z, this);
- }
-
- public Matrix4f scaleAround(float sx, float sy, float sz, float ox, float oy, float oz, Matrix4f dest) {
- float nm30 = m00() * ox + m10() * oy + m20() * oz + m30();
- float nm31 = m01() * ox + m11() * oy + m21() * oz + m31();
- float nm32 = m02() * ox + m12() * oy + m22() * oz + m32();
- float nm33 = m03() * ox + m13() * oy + m23() * oz + m33();
- boolean one = Math.absEqualsOne(sx) && Math.absEqualsOne(sy) && Math.absEqualsOne(sz);
- return dest
- ._m00(m00() * sx)
- ._m01(m01() * sx)
- ._m02(m02() * sx)
- ._m03(m03() * sx)
- ._m10(m10() * sy)
- ._m11(m11() * sy)
- ._m12(m12() * sy)
- ._m13(m13() * sy)
- ._m20(m20() * sz)
- ._m21(m21() * sz)
- ._m22(m22() * sz)
- ._m23(m23() * sz)
- ._m30(-dest.m00() * ox - dest.m10() * oy - dest.m20() * oz + nm30)
- ._m31(-dest.m01() * ox - dest.m11() * oy - dest.m21() * oz + nm31)
- ._m32(-dest.m02() * ox - dest.m12() * oy - dest.m22() * oz + nm32)
- ._m33(-dest.m03() * ox - dest.m13() * oy - dest.m23() * oz + nm33)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION
- | (one ? 0 : PROPERTY_ORTHONORMAL)));
- }
-
- /**
- * Apply scaling to this matrix by scaling the base axes by the given sx,
- * sy and sz factors while using (ox, oy, oz)
as the scaling origin.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- * translate(ox, oy, oz).scale(sx, sy, sz).translate(-ox, -oy, -oz)
- *
- * @param sx
- * the scaling factor of the x component
- * @param sy
- * the scaling factor of the y component
- * @param sz
- * the scaling factor of the z component
- * @param ox
- * the x coordinate of the scaling origin
- * @param oy
- * the y coordinate of the scaling origin
- * @param oz
- * the z coordinate of the scaling origin
- * @return this
- */
- public Matrix4f scaleAround(float sx, float sy, float sz, float ox, float oy, float oz) {
- return scaleAround(sx, sy, sz, ox, oy, oz, this);
- }
-
- /**
- * Apply scaling to this matrix by scaling all three base axes by the given factor
- * while using (ox, oy, oz)
as the scaling origin.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- * translate(ox, oy, oz).scale(factor).translate(-ox, -oy, -oz)
- *
- * @param factor
- * the scaling factor for all three axes
- * @param ox
- * the x coordinate of the scaling origin
- * @param oy
- * the y coordinate of the scaling origin
- * @param oz
- * the z coordinate of the scaling origin
- * @return this
- */
- public Matrix4f scaleAround(float factor, float ox, float oy, float oz) {
- return scaleAround(factor, factor, factor, ox, oy, oz, this);
- }
-
- public Matrix4f scaleAround(float factor, float ox, float oy, float oz, Matrix4f dest) {
- return scaleAround(factor, factor, factor, ox, oy, oz, dest);
- }
-
- public Matrix4f scaleLocal(float x, float y, float z, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.scaling(x, y, z);
- return scaleLocalGeneric(x, y, z, dest);
- }
- private Matrix4f scaleLocalGeneric(float x, float y, float z, Matrix4f dest) {
- float nm00 = x * m00();
- float nm01 = y * m01();
- float nm02 = z * m02();
- float nm10 = x * m10();
- float nm11 = y * m11();
- float nm12 = z * m12();
- float nm20 = x * m20();
- float nm21 = y * m21();
- float nm22 = z * m22();
- float nm30 = x * m30();
- float nm31 = y * m31();
- float nm32 = z * m32();
- boolean one = Math.absEqualsOne(x) && Math.absEqualsOne(y) && Math.absEqualsOne(z);
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(m03())
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(m13())
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(m23())
- ._m30(nm30)
- ._m31(nm31)
- ._m32(nm32)
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION
- | (one ? 0 : PROPERTY_ORTHONORMAL)));
- }
-
- public Matrix4f scaleLocal(float xyz, Matrix4f dest) {
- return scaleLocal(xyz, xyz, xyz, dest);
- }
-
- /**
- * Pre-multiply scaling to this matrix by scaling the base axes by the given xyz factor.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
, the
- * scaling will be applied last!
- *
- * @param xyz
- * the factor of the x, y and z component
- * @return this
- */
- public Matrix4f scaleLocal(float xyz) {
- return scaleLocal(xyz, this);
- }
-
- /**
- * Pre-multiply scaling to this matrix by scaling the base axes by the given x,
- * y and z factors.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
, the
- * scaling will be applied last!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @param z
- * the factor of the z component
- * @return this
- */
- public Matrix4f scaleLocal(float x, float y, float z) {
- return scaleLocal(x, y, z, this);
- }
-
- public Matrix4f scaleAroundLocal(float sx, float sy, float sz, float ox, float oy, float oz, Matrix4f dest) {
- boolean one = Math.absEqualsOne(sx) && Math.absEqualsOne(sy) && Math.absEqualsOne(sz);
- return dest
- ._m00(sx * (m00() - ox * m03()) + ox * m03())
- ._m01(sy * (m01() - oy * m03()) + oy * m03())
- ._m02(sz * (m02() - oz * m03()) + oz * m03())
- ._m03(m03())
- ._m10(sx * (m10() - ox * m13()) + ox * m13())
- ._m11(sy * (m11() - oy * m13()) + oy * m13())
- ._m12(sz * (m12() - oz * m13()) + oz * m13())
- ._m13(m13())
- ._m20(sx * (m20() - ox * m23()) + ox * m23())
- ._m21(sy * (m21() - oy * m23()) + oy * m23())
- ._m22(sz * (m22() - oz * m23()) + oz * m23())
- ._m23(m23())
- ._m30(sx * (m30() - ox * m33()) + ox * m33())
- ._m31(sy * (m31() - oy * m33()) + oy * m33())
- ._m32(sz * (m32() - oz * m33()) + oz * m33())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION
- | (one ? 0 : PROPERTY_ORTHONORMAL)));
- }
-
- /**
- * Pre-multiply scaling to this matrix by scaling the base axes by the given sx,
- * sy and sz factors while using (ox, oy, oz)
as the scaling origin.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
, the
- * scaling will be applied last!
- * new Matrix4f().translate(ox, oy, oz).scale(sx, sy, sz).translate(-ox, -oy, -oz).mul(this, this)
- *
- * @param sx
- * the scaling factor of the x component
- * @param sy
- * the scaling factor of the y component
- * @param sz
- * the scaling factor of the z component
- * @param ox
- * the x coordinate of the scaling origin
- * @param oy
- * the y coordinate of the scaling origin
- * @param oz
- * the z coordinate of the scaling origin
- * @return this
- */
- public Matrix4f scaleAroundLocal(float sx, float sy, float sz, float ox, float oy, float oz) {
- return scaleAroundLocal(sx, sy, sz, ox, oy, oz, this);
- }
-
- /**
- * Pre-multiply scaling to this matrix by scaling all three base axes by the given factor
- * while using (ox, oy, oz)
as the scaling origin.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
, the
- * scaling will be applied last!
- * new Matrix4f().translate(ox, oy, oz).scale(factor).translate(-ox, -oy, -oz).mul(this, this)
- *
- * @param factor
- * the scaling factor for all three axes
- * @param ox
- * the x coordinate of the scaling origin
- * @param oy
- * the y coordinate of the scaling origin
- * @param oz
- * the z coordinate of the scaling origin
- * @return this
- */
- public Matrix4f scaleAroundLocal(float factor, float ox, float oy, float oz) {
- return scaleAroundLocal(factor, factor, factor, ox, oy, oz, this);
- }
-
- public Matrix4f scaleAroundLocal(float factor, float ox, float oy, float oz, Matrix4f dest) {
- return scaleAroundLocal(factor, factor, factor, ox, oy, oz, dest);
- }
-
- public Matrix4f rotateX(float ang, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotationX(ang);
- else if ((properties & PROPERTY_TRANSLATION) != 0) {
- float x = m30(), y = m31(), z = m32();
- return dest.rotationX(ang).setTranslation(x, y, z);
- }
- return rotateXInternal(ang, dest);
- }
- private Matrix4f rotateXInternal(float ang, Matrix4f dest) {
- float sin = Math.sin(ang), cos = Math.cosFromSin(sin, ang);
- float lm10 = m10(), lm11 = m11(), lm12 = m12(), lm13 = m13(), lm20 = m20(), lm21 = m21(), lm22 = m22(), lm23 = m23();
- return dest
- ._m20(Math.fma(lm10, -sin, lm20 * cos))
- ._m21(Math.fma(lm11, -sin, lm21 * cos))
- ._m22(Math.fma(lm12, -sin, lm22 * cos))
- ._m23(Math.fma(lm13, -sin, lm23 * cos))
- ._m10(Math.fma(lm10, cos, lm20 * sin))
- ._m11(Math.fma(lm11, cos, lm21 * sin))
- ._m12(Math.fma(lm12, cos, lm22 * sin))
- ._m13(Math.fma(lm13, cos, lm23 * sin))
- ._m00(m00())
- ._m01(m01())
- ._m02(m02())
- ._m03(m03())
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation about the X axis to this matrix by rotating the given amount of radians.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * +X
towards (dirX, dirY)
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (dirX, dirY)
must be a unit vector.
- *
- * @param dirX
- * the x component of the normalized direction
- * @param dirY
- * the y component of the normalized direction
- * @return this
- */
- public Matrix4f rotateTowardsXY(float dirX, float dirY) {
- return rotateTowardsXY(dirX, dirY, this);
- }
-
- public Matrix4f rotateTowardsXY(float dirX, float dirY, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotationTowardsXY(dirX, dirY);
- float nm00 = Math.fma(m00(), dirY, m10() * dirX);
- float nm01 = Math.fma(m01(), dirY, m11() * dirX);
- float nm02 = Math.fma(m02(), dirY, m12() * dirX);
- float nm03 = Math.fma(m03(), dirY, m13() * dirX);
- return dest
- ._m10(Math.fma(m00(), -dirX, m10() * dirY))
- ._m11(Math.fma(m01(), -dirX, m11() * dirY))
- ._m12(Math.fma(m02(), -dirX, m12() * dirY))
- ._m13(Math.fma(m03(), -dirX, m13() * dirY))
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m20(m20())
- ._m21(m21())
- ._m22(m22())
- ._m23(m23())
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation of angles.x
radians about the X axis, followed by a rotation of angles.y
radians about the Y axis and
- * followed by a rotation of angles.z
radians about the Z axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateX(angles.x()).rotateY(angles.y()).rotateZ(angles.z())
- *
- * @param angles
- * the Euler angles
- * @return this
- */
- public Matrix4f rotateXYZ(Vector3fc angles) {
- return rotateXYZ(angles.x(), angles.y(), angles.z());
- }
-
- /**
- * Apply rotation of angleX
radians about the X axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleZ
radians about the Z axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateX(angleX).rotateY(angleY).rotateZ(angleZ)
- *
- * @param angleX
- * the angle to rotate about X
- * @param angleY
- * the angle to rotate about Y
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix4f rotateXYZ(float angleX, float angleY, float angleZ) {
- return rotateXYZ(angleX, angleY, angleZ, this);
- }
-
- public Matrix4f rotateXYZ(float angleX, float angleY, float angleZ, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotationXYZ(angleX, angleY, angleZ);
- else if ((properties & PROPERTY_TRANSLATION) != 0) {
- float tx = m30(), ty = m31(), tz = m32();
- return dest.rotationXYZ(angleX, angleY, angleZ).setTranslation(tx, ty, tz);
- } else if ((properties & PROPERTY_AFFINE) != 0)
- return dest.rotateAffineXYZ(angleX, angleY, angleZ);
- return rotateXYZInternal(angleX, angleY, angleZ, dest);
- }
- private Matrix4f rotateXYZInternal(float angleX, float angleY, float angleZ, Matrix4f dest) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinX = -sinX;
- float m_sinY = -sinY;
- float m_sinZ = -sinZ;
-
- // rotateX
- float nm10 = Math.fma(m10(), cosX, m20() * sinX);
- float nm11 = Math.fma(m11(), cosX, m21() * sinX);
- float nm12 = Math.fma(m12(), cosX, m22() * sinX);
- float nm13 = Math.fma(m13(), cosX, m23() * sinX);
- float nm20 = Math.fma(m10(), m_sinX, m20() * cosX);
- float nm21 = Math.fma(m11(), m_sinX, m21() * cosX);
- float nm22 = Math.fma(m12(), m_sinX, m22() * cosX);
- float nm23 = Math.fma(m13(), m_sinX, m23() * cosX);
- // rotateY
- float nm00 = Math.fma(m00(), cosY, nm20 * m_sinY);
- float nm01 = Math.fma(m01(), cosY, nm21 * m_sinY);
- float nm02 = Math.fma(m02(), cosY, nm22 * m_sinY);
- float nm03 = Math.fma(m03(), cosY, nm23 * m_sinY);
- return dest
- ._m20(Math.fma(m00(), sinY, nm20 * cosY))
- ._m21(Math.fma(m01(), sinY, nm21 * cosY))
- ._m22(Math.fma(m02(), sinY, nm22 * cosY))
- ._m23(Math.fma(m03(), sinY, nm23 * cosY))
- // rotateZ
- ._m00(Math.fma(nm00, cosZ, nm10 * sinZ))
- ._m01(Math.fma(nm01, cosZ, nm11 * sinZ))
- ._m02(Math.fma(nm02, cosZ, nm12 * sinZ))
- ._m03(Math.fma(nm03, cosZ, nm13 * sinZ))
- ._m10(Math.fma(nm00, m_sinZ, nm10 * cosZ))
- ._m11(Math.fma(nm01, m_sinZ, nm11 * cosZ))
- ._m12(Math.fma(nm02, m_sinZ, nm12 * cosZ))
- ._m13(Math.fma(nm03, m_sinZ, nm13 * cosZ))
- // copy last column from 'this'
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation of angleX
radians about the X axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleZ
radians about the Z axis.
- * this
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateX(angleX).rotateY(angleY).rotateZ(angleZ)
- *
- * @param angleX
- * the angle to rotate about X
- * @param angleY
- * the angle to rotate about Y
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix4f rotateAffineXYZ(float angleX, float angleY, float angleZ) {
- return rotateAffineXYZ(angleX, angleY, angleZ, this);
- }
-
- public Matrix4f rotateAffineXYZ(float angleX, float angleY, float angleZ, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotationXYZ(angleX, angleY, angleZ);
- else if ((properties & PROPERTY_TRANSLATION) != 0) {
- float tx = m30(), ty = m31(), tz = m32();
- return dest.rotationXYZ(angleX, angleY, angleZ).setTranslation(tx, ty, tz);
- }
- return rotateAffineXYZInternal(angleX, angleY, angleZ, dest);
- }
- private Matrix4f rotateAffineXYZInternal(float angleX, float angleY, float angleZ, Matrix4f dest) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinX = -sinX;
- float m_sinY = -sinY;
- float m_sinZ = -sinZ;
-
- // rotateX
- float nm10 = Math.fma(m10(), cosX, m20() * sinX);
- float nm11 = Math.fma(m11(), cosX, m21() * sinX);
- float nm12 = Math.fma(m12(), cosX, m22() * sinX);
- float nm20 = Math.fma(m10(), m_sinX, m20() * cosX);
- float nm21 = Math.fma(m11(), m_sinX, m21() * cosX);
- float nm22 = Math.fma(m12(), m_sinX, m22() * cosX);
- // rotateY
- float nm00 = Math.fma(m00(), cosY, nm20 * m_sinY);
- float nm01 = Math.fma(m01(), cosY, nm21 * m_sinY);
- float nm02 = Math.fma(m02(), cosY, nm22 * m_sinY);
- return dest
- ._m20(Math.fma(m00(), sinY, nm20 * cosY))
- ._m21(Math.fma(m01(), sinY, nm21 * cosY))
- ._m22(Math.fma(m02(), sinY, nm22 * cosY))
- ._m23(0.0f)
- // rotateZ
- ._m00(Math.fma(nm00, cosZ, nm10 * sinZ))
- ._m01(Math.fma(nm01, cosZ, nm11 * sinZ))
- ._m02(Math.fma(nm02, cosZ, nm12 * sinZ))
- ._m03(0.0f)
- ._m10(Math.fma(nm00, m_sinZ, nm10 * cosZ))
- ._m11(Math.fma(nm01, m_sinZ, nm11 * cosZ))
- ._m12(Math.fma(nm02, m_sinZ, nm12 * cosZ))
- ._m13(0.0f)
- // copy last column from 'this'
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation of angles.z
radians about the Z axis, followed by a rotation of angles.y
radians about the Y axis and
- * followed by a rotation of angles.x
radians about the X axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateZ(angles.z).rotateY(angles.y).rotateX(angles.x)
- *
- * @param angles
- * the Euler angles
- * @return this
- */
- public Matrix4f rotateZYX(Vector3f angles) {
- return rotateZYX(angles.z, angles.y, angles.x);
- }
-
- /**
- * Apply rotation of angleZ
radians about the Z axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleX
radians about the X axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateZ(angleZ).rotateY(angleY).rotateX(angleX)
- *
- * @param angleZ
- * the angle to rotate about Z
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @return this
- */
- public Matrix4f rotateZYX(float angleZ, float angleY, float angleX) {
- return rotateZYX(angleZ, angleY, angleX, this);
- }
-
- public Matrix4f rotateZYX(float angleZ, float angleY, float angleX, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotationZYX(angleZ, angleY, angleX);
- else if ((properties & PROPERTY_TRANSLATION) != 0) {
- float tx = m30(), ty = m31(), tz = m32();
- return dest.rotationZYX(angleZ, angleY, angleX).setTranslation(tx, ty, tz);
- } else if ((properties & PROPERTY_AFFINE) != 0)
- return dest.rotateAffineZYX(angleZ, angleY, angleX);
- return rotateZYXInternal(angleZ, angleY, angleX, dest);
- }
- private Matrix4f rotateZYXInternal(float angleZ, float angleY, float angleX, Matrix4f dest) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinZ = -sinZ;
- float m_sinY = -sinY;
- float m_sinX = -sinX;
-
- // rotateZ
- float nm00 = m00() * cosZ + m10() * sinZ;
- float nm01 = m01() * cosZ + m11() * sinZ;
- float nm02 = m02() * cosZ + m12() * sinZ;
- float nm03 = m03() * cosZ + m13() * sinZ;
- float nm10 = m00() * m_sinZ + m10() * cosZ;
- float nm11 = m01() * m_sinZ + m11() * cosZ;
- float nm12 = m02() * m_sinZ + m12() * cosZ;
- float nm13 = m03() * m_sinZ + m13() * cosZ;
- // rotateY
- float nm20 = nm00 * sinY + m20() * cosY;
- float nm21 = nm01 * sinY + m21() * cosY;
- float nm22 = nm02 * sinY + m22() * cosY;
- float nm23 = nm03 * sinY + m23() * cosY;
- return dest
- ._m00(nm00 * cosY + m20() * m_sinY)
- ._m01(nm01 * cosY + m21() * m_sinY)
- ._m02(nm02 * cosY + m22() * m_sinY)
- ._m03(nm03 * cosY + m23() * m_sinY)
- ._m10(nm10 * cosX + nm20 * sinX)
- ._m11(nm11 * cosX + nm21 * sinX)
- ._m12(nm12 * cosX + nm22 * sinX)
- ._m13(nm13 * cosX + nm23 * sinX)
- ._m20(nm10 * m_sinX + nm20 * cosX)
- ._m21(nm11 * m_sinX + nm21 * cosX)
- ._m22(nm12 * m_sinX + nm22 * cosX)
- ._m23(nm13 * m_sinX + nm23 * cosX)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation of angleZ
radians about the Z axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleX
radians about the X axis.
- * this
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- *
- * @param angleZ
- * the angle to rotate about Z
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @return this
- */
- public Matrix4f rotateAffineZYX(float angleZ, float angleY, float angleX) {
- return rotateAffineZYX(angleZ, angleY, angleX, this);
- }
-
- public Matrix4f rotateAffineZYX(float angleZ, float angleY, float angleX, Matrix4f dest) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinZ = -sinZ;
- float m_sinY = -sinY;
- float m_sinX = -sinX;
-
- // rotateZ
- float nm00 = m00() * cosZ + m10() * sinZ;
- float nm01 = m01() * cosZ + m11() * sinZ;
- float nm02 = m02() * cosZ + m12() * sinZ;
- float nm10 = m00() * m_sinZ + m10() * cosZ;
- float nm11 = m01() * m_sinZ + m11() * cosZ;
- float nm12 = m02() * m_sinZ + m12() * cosZ;
- // rotateY
- float nm20 = nm00 * sinY + m20() * cosY;
- float nm21 = nm01 * sinY + m21() * cosY;
- float nm22 = nm02 * sinY + m22() * cosY;
- return dest
- ._m00(nm00 * cosY + m20() * m_sinY)
- ._m01(nm01 * cosY + m21() * m_sinY)
- ._m02(nm02 * cosY + m22() * m_sinY)
- ._m03(0.0f)
- ._m10(nm10 * cosX + nm20 * sinX)
- ._m11(nm11 * cosX + nm21 * sinX)
- ._m12(nm12 * cosX + nm22 * sinX)
- ._m13(0.0f)
- ._m20(nm10 * m_sinX + nm20 * cosX)
- ._m21(nm11 * m_sinX + nm21 * cosX)
- ._m22(nm12 * m_sinX + nm22 * cosX)
- ._m23(0.0f)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation of angles.y
radians about the Y axis, followed by a rotation of angles.x
radians about the X axis and
- * followed by a rotation of angles.z
radians about the Z axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateY(angles.y).rotateX(angles.x).rotateZ(angles.z)
- *
- * @param angles
- * the Euler angles
- * @return this
- */
- public Matrix4f rotateYXZ(Vector3f angles) {
- return rotateYXZ(angles.y, angles.x, angles.z);
- }
-
- /**
- * Apply rotation of angleY
radians about the Y axis, followed by a rotation of angleX
radians about the X axis and
- * followed by a rotation of angleZ
radians about the Z axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateY(angleY).rotateX(angleX).rotateZ(angleZ)
- *
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix4f rotateYXZ(float angleY, float angleX, float angleZ) {
- return rotateYXZ(angleY, angleX, angleZ, this);
- }
-
- public Matrix4f rotateYXZ(float angleY, float angleX, float angleZ, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.rotationYXZ(angleY, angleX, angleZ);
- else if ((properties & PROPERTY_TRANSLATION) != 0) {
- float tx = m30(), ty = m31(), tz = m32();
- return dest.rotationYXZ(angleY, angleX, angleZ).setTranslation(tx, ty, tz);
- } else if ((properties & PROPERTY_AFFINE) != 0)
- return dest.rotateAffineYXZ(angleY, angleX, angleZ);
- return rotateYXZInternal(angleY, angleX, angleZ, dest);
- }
- private Matrix4f rotateYXZInternal(float angleY, float angleX, float angleZ, Matrix4f dest) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinY = -sinY;
- float m_sinX = -sinX;
- float m_sinZ = -sinZ;
-
- // rotateY
- float nm20 = m00() * sinY + m20() * cosY;
- float nm21 = m01() * sinY + m21() * cosY;
- float nm22 = m02() * sinY + m22() * cosY;
- float nm23 = m03() * sinY + m23() * cosY;
- float nm00 = m00() * cosY + m20() * m_sinY;
- float nm01 = m01() * cosY + m21() * m_sinY;
- float nm02 = m02() * cosY + m22() * m_sinY;
- float nm03 = m03() * cosY + m23() * m_sinY;
- // rotateX
- float nm10 = m10() * cosX + nm20 * sinX;
- float nm11 = m11() * cosX + nm21 * sinX;
- float nm12 = m12() * cosX + nm22 * sinX;
- float nm13 = m13() * cosX + nm23 * sinX;
- return dest
- ._m20(m10() * m_sinX + nm20 * cosX)
- ._m21(m11() * m_sinX + nm21 * cosX)
- ._m22(m12() * m_sinX + nm22 * cosX)
- ._m23(m13() * m_sinX + nm23 * cosX)
- ._m00(nm00 * cosZ + nm10 * sinZ)
- ._m01(nm01 * cosZ + nm11 * sinZ)
- ._m02(nm02 * cosZ + nm12 * sinZ)
- ._m03(nm03 * cosZ + nm13 * sinZ)
- ._m10(nm00 * m_sinZ + nm10 * cosZ)
- ._m11(nm01 * m_sinZ + nm11 * cosZ)
- ._m12(nm02 * m_sinZ + nm12 * cosZ)
- ._m13(nm03 * m_sinZ + nm13 * cosZ)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation of angleY
radians about the Y axis, followed by a rotation of angleX
radians about the X axis and
- * followed by a rotation of angleZ
radians about the Z axis.
- * this
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- *
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param angleZ
- * the angle to rotate about Z
- * @return this
- */
- public Matrix4f rotateAffineYXZ(float angleY, float angleX, float angleZ) {
- return rotateAffineYXZ(angleY, angleX, angleZ, this);
- }
-
- public Matrix4f rotateAffineYXZ(float angleY, float angleX, float angleZ, Matrix4f dest) {
- float sinX = Math.sin(angleX);
- float cosX = Math.cosFromSin(sinX, angleX);
- float sinY = Math.sin(angleY);
- float cosY = Math.cosFromSin(sinY, angleY);
- float sinZ = Math.sin(angleZ);
- float cosZ = Math.cosFromSin(sinZ, angleZ);
- float m_sinY = -sinY;
- float m_sinX = -sinX;
- float m_sinZ = -sinZ;
-
- // rotateY
- float nm20 = m00() * sinY + m20() * cosY;
- float nm21 = m01() * sinY + m21() * cosY;
- float nm22 = m02() * sinY + m22() * cosY;
- float nm00 = m00() * cosY + m20() * m_sinY;
- float nm01 = m01() * cosY + m21() * m_sinY;
- float nm02 = m02() * cosY + m22() * m_sinY;
- // rotateX
- float nm10 = m10() * cosX + nm20 * sinX;
- float nm11 = m11() * cosX + nm21 * sinX;
- float nm12 = m12() * cosX + nm22 * sinX;
- return dest
- ._m20(m10() * m_sinX + nm20 * cosX)
- ._m21(m11() * m_sinX + nm21 * cosX)
- ._m22(m12() * m_sinX + nm22 * cosX)
- ._m23(0.0f)
- ._m00(nm00 * cosZ + nm10 * sinZ)
- ._m01(nm01 * cosZ + nm11 * sinZ)
- ._m02(nm02 * cosZ + nm12 * sinZ)
- ._m03(0.0f)
- ._m10(nm00 * m_sinZ + nm10 * cosZ)
- ._m11(nm01 * m_sinZ + nm11 * cosZ)
- ._m12(nm02 * m_sinZ + nm12 * cosZ)
- ._m13(0.0f)
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- }
-
- /**
- * Apply rotation to this matrix by rotating the given amount of radians
- * about the specified (x, y, z)
axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (x, y, z)
axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (x, y, z)
axis and store the result in dest
.
- * this
to only contain a translation.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (x, y, z)
axis and store the result in dest
.
- * this
to be {@link #isAffine() affine}.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (x, y, z)
axis.
- * this
to be {@link #isAffine() affine}.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (x, y, z)
axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * (x, y, z)
axis.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be M * T
. So when
- * transforming a vector v
with the new matrix by using
- * M * T * v
, the translation will be applied first!
- * dest
.
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be M * T
. So when
- * transforming a vector v
with the new matrix by using
- * M * T * v
, the translation will be applied first!
- * dest
.
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be M * T
. So when
- * transforming a vector v
with the new matrix by using
- * M * T * v
, the translation will be applied first!
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be M * T
. So when
- * transforming a vector v
with the new matrix by using
- * M * T * v
, the translation will be applied first!
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be T * M
. So when
- * transforming a vector v
with the new matrix by using
- * T * M * v
, the translation will be applied last!
- * dest
.
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be T * M
. So when
- * transforming a vector v
with the new matrix by using
- * T * M * v
, the translation will be applied last!
- * dest
.
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be T * M
. So when
- * transforming a vector v
with the new matrix by using
- * T * M * v
, the translation will be applied last!
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be T * M
. So when
- * transforming a vector v
with the new matrix by using
- * T * M * v
, the translation will be applied last!
- * dest
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setOrtho(left, right, bottom, top, zNear, zFar, zZeroToOne);
- return orthoGeneric(left, right, bottom, top, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f orthoGeneric(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- // calculate right matrix elements
- float rm00 = 2.0f / (right - left);
- float rm11 = 2.0f / (top - bottom);
- float rm22 = (zZeroToOne ? 1.0f : 2.0f) / (zNear - zFar);
- float rm30 = (left + right) / (left - right);
- float rm31 = (top + bottom) / (bottom - top);
- float rm32 = (zZeroToOne ? zNear : (zFar + zNear)) / (zNear - zFar);
- // perform optimized multiplication
- // compute the last column first, because other columns do not depend on it
- dest._m30(m00() * rm30 + m10() * rm31 + m20() * rm32 + m30())
- ._m31(m01() * rm30 + m11() * rm31 + m21() * rm32 + m31())
- ._m32(m02() * rm30 + m12() * rm31 + m22() * rm32 + m32())
- ._m33(m03() * rm30 + m13() * rm31 + m23() * rm32 + m33())
- ._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m20(m20() * rm22)
- ._m21(m21() * rm22)
- ._m22(m22() * rm22)
- ._m23(m23() * rm22)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Apply an orthographic projection transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne) {
- return ortho(left, right, bottom, top, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply an orthographic projection transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * dest
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f orthoLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setOrthoLH(left, right, bottom, top, zNear, zFar, zZeroToOne);
- return orthoLHGeneric(left, right, bottom, top, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f orthoLHGeneric(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- // calculate right matrix elements
- float rm00 = 2.0f / (right - left);
- float rm11 = 2.0f / (top - bottom);
- float rm22 = (zZeroToOne ? 1.0f : 2.0f) / (zFar - zNear);
- float rm30 = (left + right) / (left - right);
- float rm31 = (top + bottom) / (bottom - top);
- float rm32 = (zZeroToOne ? zNear : (zFar + zNear)) / (zNear - zFar);
-
- // perform optimized multiplication
- // compute the last column first, because other columns do not depend on it
- dest._m30(m00() * rm30 + m10() * rm31 + m20() * rm32 + m30())
- ._m31(m01() * rm30 + m11() * rm31 + m21() * rm32 + m31())
- ._m32(m02() * rm30 + m12() * rm31 + m22() * rm32 + m32())
- ._m33(m03() * rm30 + m13() * rm31 + m23() * rm32 + m33())
- ._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m20(m20() * rm22)
- ._m21(m21() * rm22)
- ._m22(m22() * rm22)
- ._m23(m23() * rm22)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Apply an orthographic projection transformation for a left-handed coordiante system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f orthoLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne) {
- return orthoLH(left, right, bottom, top, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply an orthographic projection transformation for a left-handed coordiante system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setOrtho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00(2.0f / (right - left))
- ._m11(2.0f / (top - bottom))
- ._m22((zZeroToOne ? 1.0f : 2.0f) / (zNear - zFar))
- ._m30((right + left) / (left - right))
- ._m31((top + bottom) / (bottom - top))
- ._m32((zZeroToOne ? zNear : (zFar + zNear)) / (zNear - zFar))
- ._properties(PROPERTY_AFFINE);
- return this;
- }
-
- /**
- * Set this matrix to be an orthographic projection transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setOrthoLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00(2.0f / (right - left))
- ._m11(2.0f / (top - bottom))
- ._m22((zZeroToOne ? 1.0f : 2.0f) / (zFar - zNear))
- ._m30((right + left) / (left - right))
- ._m31((top + bottom) / (bottom - top))
- ._m32((zZeroToOne ? zNear : (zFar + zNear)) / (zNear - zFar))
- ._properties(PROPERTY_AFFINE);
- return this;
- }
-
- /**
- * Set this matrix to be an orthographic projection transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * dest
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- public Matrix4f orthoSymmetric(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setOrthoSymmetric(width, height, zNear, zFar, zZeroToOne);
- return orthoSymmetricGeneric(width, height, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f orthoSymmetricGeneric(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- // calculate right matrix elements
- float rm00 = 2.0f / width;
- float rm11 = 2.0f / height;
- float rm22 = (zZeroToOne ? 1.0f : 2.0f) / (zNear - zFar);
- float rm32 = (zZeroToOne ? zNear : (zFar + zNear)) / (zNear - zFar);
- // perform optimized multiplication
- // compute the last column first, because other columns do not depend on it
- dest._m30(m20() * rm32 + m30())
- ._m31(m21() * rm32 + m31())
- ._m32(m22() * rm32 + m32())
- ._m33(m23() * rm32 + m33())
- ._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m20(m20() * rm22)
- ._m21(m21() * rm22)
- ._m22(m22() * rm22)
- ._m23(m23() * rm22)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Apply a symmetric orthographic projection transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f orthoSymmetric(float width, float height, float zNear, float zFar, boolean zZeroToOne) {
- return orthoSymmetric(width, height, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply a symmetric orthographic projection transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * dest
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- public Matrix4f orthoSymmetricLH(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setOrthoSymmetricLH(width, height, zNear, zFar, zZeroToOne);
- return orthoSymmetricLHGeneric(width, height, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f orthoSymmetricLHGeneric(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- // calculate right matrix elements
- float rm00 = 2.0f / width;
- float rm11 = 2.0f / height;
- float rm22 = (zZeroToOne ? 1.0f : 2.0f) / (zFar - zNear);
- float rm32 = (zZeroToOne ? zNear : (zFar + zNear)) / (zNear - zFar);
- // perform optimized multiplication
- // compute the last column first, because other columns do not depend on it
- dest._m30(m20() * rm32 + m30())
- ._m31(m21() * rm32 + m31())
- ._m32(m22() * rm32 + m32())
- ._m33(m23() * rm32 + m33())
- ._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m20(m20() * rm22)
- ._m21(m21() * rm22)
- ._m22(m22() * rm22)
- ._m23(m23() * rm22)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Apply a symmetric orthographic projection transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f orthoSymmetricLH(float width, float height, float zNear, float zFar, boolean zZeroToOne) {
- return orthoSymmetricLH(width, height, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply a symmetric orthographic projection transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setOrthoSymmetric(float width, float height, float zNear, float zFar, boolean zZeroToOne) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00(2.0f / width)
- ._m11(2.0f / height)
- ._m22((zZeroToOne ? 1.0f : 2.0f) / (zNear - zFar))
- ._m32((zZeroToOne ? zNear : (zFar + zNear)) / (zNear - zFar))
- ._properties(PROPERTY_AFFINE);
- return this;
- }
-
- /**
- * Set this matrix to be a symmetric orthographic projection transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setOrthoSymmetricLH(float width, float height, float zNear, float zFar, boolean zZeroToOne) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00(2.0f / width)
- ._m11(2.0f / height)
- ._m22((zZeroToOne ? 1.0f : 2.0f) / (zFar - zNear))
- ._m32((zZeroToOne ? zNear : (zFar + zNear)) / (zNear - zFar))
- ._properties(PROPERTY_AFFINE);
- return this;
- }
-
- /**
- * Set this matrix to be a symmetric orthographic projection transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * dest
.
- * zNear=-1
and zFar=+1
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * zNear=-1
and zFar=+1
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * dest
.
- * zNear=-1
and zFar=+1
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * zNear=-1
and zFar=+1
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * zNear=-1
and zFar=+1
.
- * zNear=-1
and zFar=+1
.
- * -z
point along dir
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * eye = (0, 0, 0)
and center = dir
.
- * -z
point along dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * eye = (0, 0, 0)
and center = dir
.
- * -z
point along dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * eye = (0, 0, 0)
and center = dir
.
- * -z
point along dir
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * eye = (0, 0, 0)
and center = dir
.
- * -z
- * point along dir
.
- * eye = (0, 0, 0)
and center = dir
.
- * -z
- * point along dir
.
- * eye = (0, 0, 0)
and center = dir
.
- * -z
with center - eye
.
- * eye
, center
and up
but use primitives,
- * like in the GLU function, use {@link #setLookAt(float, float, float, float, float, float, float, float, float) setLookAt()}
- * instead.
- * -z
with center - eye
.
- * -z
with center - eye
and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * -z
with center - eye
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * -z
with center - eye
and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * -z
with center - eye
and store the result in dest
.
- * this
to be a perspective transformation, obtained via
- * {@link #frustum(float, float, float, float, float, float) frustum()} or {@link #perspective(float, float, float, float) perspective()} or
- * one of their overloads.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * -z
with center - eye
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * +z
with center - eye
.
- * eye
, center
and up
but use primitives,
- * like in the GLU function, use {@link #setLookAtLH(float, float, float, float, float, float, float, float, float) setLookAtLH()}
- * instead.
- * +z
with center - eye
.
- * +z
with center - eye
and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * +z
with center - eye
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * +z
with center - eye
and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * +z
with center - eye
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * +z
with center - eye
and store the result in dest
.
- * this
to be a perspective transformation, obtained via
- * {@link #frustumLH(float, float, float, float, float, float) frustumLH()} or {@link #perspectiveLH(float, float, float, float) perspectiveLH()} or
- * one of their overloads.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * translate(w-1-2*x, h-1-2*y, 0).scale(w, h, 1)
- * M
is this
matrix and T
the created transformation matrix,
- * then the new matrix will be M * T
. So when transforming a
- * vector v
with the new matrix by using M * T * v
, the
- * created transformation will be applied first!
- *
- * @param x
- * the tile's x coordinate/index (should be in [0..w)
)
- * @param y
- * the tile's y coordinate/index (should be in [0..h)
)
- * @param w
- * the number of tiles along the x axis
- * @param h
- * the number of tiles along the y axis
- * @return this
- */
- public Matrix4f tile(int x, int y, int w, int h) {
- return tile(x, y, w, h, this);
- }
- public Matrix4f tile(int x, int y, int w, int h, Matrix4f dest) {
- float tx = w - 1 - (x<<1), ty = h - 1 - (y<<1);
- return dest
- ._m30(Math.fma(m00(), tx, Math.fma(m10(), ty, m30())))
- ._m31(Math.fma(m01(), tx, Math.fma(m11(), ty, m31())))
- ._m32(Math.fma(m02(), tx, Math.fma(m12(), ty, m32())))
- ._m33(Math.fma(m03(), tx, Math.fma(m13(), ty, m33())))
- ._m00(m00() * w)
- ._m01(m01() * w)
- ._m02(m02() * w)
- ._m03(m03() * w)
- ._m10(m10() * h)
- ._m11(m11() * h)
- ._m12(m12() * h)
- ._m13(m13() * h)
- ._m20(m20())
- ._m21(m21())
- ._m22(m22())
- ._m23(m23())
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- public Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setPerspective(fovy, aspect, zNear, zFar, zZeroToOne);
- return perspectiveGeneric(fovy, aspect, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f perspectiveGeneric(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- float h = Math.tan(fovy * 0.5f);
- // calculate right matrix elements
- float rm00 = 1.0f / (h * aspect);
- float rm11 = 1.0f / h;
- float rm22;
- float rm32;
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- rm22 = e - 1.0f;
- rm32 = (e - (zZeroToOne ? 1.0f : 2.0f)) * zNear;
- } else if (nearInf) {
- float e = 1E-6f;
- rm22 = (zZeroToOne ? 0.0f : 1.0f) - e;
- rm32 = ((zZeroToOne ? 1.0f : 2.0f) - e) * zFar;
- } else {
- rm22 = (zZeroToOne ? zFar : zFar + zNear) / (zNear - zFar);
- rm32 = (zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar);
- }
- // perform optimized matrix multiplication
- float nm20 = m20() * rm22 - m30();
- float nm21 = m21() * rm22 - m31();
- float nm22 = m22() * rm22 - m32();
- float nm23 = m23() * rm22 - m33();
- dest._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m30(m20() * rm32)
- ._m31(m21() * rm32)
- ._m32(m22() * rm32)
- ._m33(m23() * rm32)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._properties(properties & ~(PROPERTY_AFFINE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, Matrix4f dest) {
- return perspective(fovy, aspect, zNear, zFar, false, dest);
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation using for a right-handed coordinate system
- * using the given NDC z range to this matrix.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne) {
- return perspective(fovy, aspect, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f perspective(float fovy, float aspect, float zNear, float zFar) {
- return perspective(fovy, aspect, zNear, zFar, this);
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- public Matrix4f perspectiveRect(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setPerspectiveRect(width, height, zNear, zFar, zZeroToOne);
- return perspectiveRectGeneric(width, height, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f perspectiveRectGeneric(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- float rm00 = (zNear + zNear) / width;
- float rm11 = (zNear + zNear) / height;
- float rm22, rm32;
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- rm22 = e - 1.0f;
- rm32 = (e - (zZeroToOne ? 1.0f : 2.0f)) * zNear;
- } else if (nearInf) {
- float e = 1E-6f;
- rm22 = (zZeroToOne ? 0.0f : 1.0f) - e;
- rm32 = ((zZeroToOne ? 1.0f : 2.0f) - e) * zFar;
- } else {
- rm22 = (zZeroToOne ? zFar : zFar + zNear) / (zNear - zFar);
- rm32 = (zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar);
- }
- // perform optimized matrix multiplication
- float nm20 = m20() * rm22 - m30();
- float nm21 = m21() * rm22 - m31();
- float nm22 = m22() * rm22 - m32();
- float nm23 = m23() * rm22 - m33();
- dest._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m30(m20() * rm32)
- ._m31(m21() * rm32)
- ._m32(m22() * rm32)
- ._m33(m23() * rm32)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._properties(properties & ~(PROPERTY_AFFINE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f perspectiveRect(float width, float height, float zNear, float zFar, Matrix4f dest) {
- return perspectiveRect(width, height, zNear, zFar, false, dest);
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation using for a right-handed coordinate system
- * using the given NDC z range to this matrix.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f perspectiveRect(float width, float height, float zNear, float zFar, boolean zZeroToOne) {
- return perspectiveRect(width, height, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f perspectiveRect(float width, float height, float zNear, float zFar) {
- return perspectiveRect(width, height, zNear, zFar, this);
- }
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * offAngleX
and offAngleY
are the horizontal and vertical angles between
- * the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
- * is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
- * is parallel to the XZ-plane.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- public Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setPerspectiveOffCenter(fovy, offAngleX, offAngleY, aspect, zNear, zFar, zZeroToOne);
- return perspectiveOffCenterGeneric(fovy, offAngleX, offAngleY, aspect, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f perspectiveOffCenterGeneric(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- float h = Math.tan(fovy * 0.5f);
- // calculate right matrix elements
- float xScale = 1.0f / (h * aspect);
- float yScale = 1.0f / h;
- float offX = Math.tan(offAngleX), offY = Math.tan(offAngleY);
- float rm20 = offX * xScale;
- float rm21 = offY * yScale;
- float rm22;
- float rm32;
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- rm22 = e - 1.0f;
- rm32 = (e - (zZeroToOne ? 1.0f : 2.0f)) * zNear;
- } else if (nearInf) {
- float e = 1E-6f;
- rm22 = (zZeroToOne ? 0.0f : 1.0f) - e;
- rm32 = ((zZeroToOne ? 1.0f : 2.0f) - e) * zFar;
- } else {
- rm22 = (zZeroToOne ? zFar : zFar + zNear) / (zNear - zFar);
- rm32 = (zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar);
- }
- // perform optimized matrix multiplication
- float nm20 = m00() * rm20 + m10() * rm21 + m20() * rm22 - m30();
- float nm21 = m01() * rm20 + m11() * rm21 + m21() * rm22 - m31();
- float nm22 = m02() * rm20 + m12() * rm21 + m22() * rm22 - m32();
- float nm23 = m03() * rm20 + m13() * rm21 + m23() * rm22 - m33();
- dest._m00(m00() * xScale)
- ._m01(m01() * xScale)
- ._m02(m02() * xScale)
- ._m03(m03() * xScale)
- ._m10(m10() * yScale)
- ._m11(m11() * yScale)
- ._m12(m12() * yScale)
- ._m13(m13() * yScale)
- ._m30(m20() * rm32)
- ._m31(m21() * rm32)
- ._m32(m22() * rm32)
- ._m33(m23() * rm32)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._properties(properties & ~(PROPERTY_AFFINE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION
- | PROPERTY_ORTHONORMAL | (rm20 == 0.0f && rm21 == 0.0f ? 0 : PROPERTY_PERSPECTIVE)));
- return dest;
- }
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * offAngleX
and offAngleY
are the horizontal and vertical angles between
- * the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
- * is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
- * is parallel to the XZ-plane.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar, Matrix4f dest) {
- return perspectiveOffCenter(fovy, offAngleX, offAngleY, aspect, zNear, zFar, false, dest);
- }
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation using for a right-handed coordinate system
- * using the given NDC z range to this matrix.
- * offAngleX
and offAngleY
are the horizontal and vertical angles between
- * the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
- * is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
- * is parallel to the XZ-plane.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar, boolean zZeroToOne) {
- return perspectiveOffCenter(fovy, offAngleX, offAngleY, aspect, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * offAngleX
and offAngleY
are the horizontal and vertical angles between
- * the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
- * is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
- * is parallel to the XZ-plane.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar) {
- return perspectiveOffCenter(fovy, offAngleX, offAngleY, aspect, zNear, zFar, this);
- }
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f perspectiveOffCenterFov(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, boolean zZeroToOne) {
- return perspectiveOffCenterFov(angleLeft, angleRight, angleDown, angleUp, zNear, zFar, zZeroToOne, this);
- }
- public Matrix4f perspectiveOffCenterFov(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- return frustum(Math.tan(angleLeft)*zNear, Math.tan(angleRight)*zNear, Math.tan(angleDown)*zNear, Math.tan(angleUp)*zNear, zNear, zFar, zZeroToOne, dest);
- }
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f perspectiveOffCenterFov(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar) {
- return perspectiveOffCenterFov(angleLeft, angleRight, angleDown, angleUp, zNear, zFar, this);
- }
- public Matrix4f perspectiveOffCenterFov(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, Matrix4f dest) {
- return frustum(Math.tan(angleLeft)*zNear, Math.tan(angleRight)*zNear, Math.tan(angleDown)*zNear, Math.tan(angleUp)*zNear, zNear, zFar, dest);
- }
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f perspectiveOffCenterFovLH(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, boolean zZeroToOne) {
- return perspectiveOffCenterFovLH(angleLeft, angleRight, angleDown, angleUp, zNear, zFar, zZeroToOne, this);
- }
- public Matrix4f perspectiveOffCenterFovLH(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- return frustumLH(Math.tan(angleLeft)*zNear, Math.tan(angleRight)*zNear, Math.tan(angleDown)*zNear, Math.tan(angleUp)*zNear, zNear, zFar, zZeroToOne, dest);
- }
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f perspectiveOffCenterFovLH(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar) {
- return perspectiveOffCenterFovLH(angleLeft, angleRight, angleDown, angleUp, zNear, zFar, this);
- }
- public Matrix4f perspectiveOffCenterFovLH(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, Matrix4f dest) {
- return frustumLH(Math.tan(angleLeft)*zNear, Math.tan(angleRight)*zNear, Math.tan(angleDown)*zNear, Math.tan(angleUp)*zNear, zNear, zFar, dest);
- }
-
- /**
- * Set this matrix to be a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne) {
- MemUtil.INSTANCE.zero(this);
- float h = Math.tan(fovy * 0.5f);
- this._m00(1.0f / (h * aspect))
- ._m11(1.0f / h);
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- this._m22(e - 1.0f)
- ._m32((e - (zZeroToOne ? 1.0f : 2.0f)) * zNear);
- } else if (nearInf) {
- float e = 1E-6f;
- this._m22((zZeroToOne ? 0.0f : 1.0f) - e)
- ._m32(((zZeroToOne ? 1.0f : 2.0f) - e) * zFar);
- } else {
- this._m22((zZeroToOne ? zFar : zFar + zNear) / (zNear - zFar))
- ._m32((zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar));
- }
- return this
- ._m23(-1.0f)
- ._properties(PROPERTY_PERSPECTIVE);
- }
-
- /**
- * Set this matrix to be a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f setPerspective(float fovy, float aspect, float zNear, float zFar) {
- return setPerspective(fovy, aspect, zNear, zFar, false);
- }
-
- /**
- * Set this matrix to be a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setPerspectiveRect(float width, float height, float zNear, float zFar, boolean zZeroToOne) {
- MemUtil.INSTANCE.zero(this);
- this._m00((zNear + zNear) / width)
- ._m11((zNear + zNear) / height);
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- this._m22(e - 1.0f)
- ._m32((e - (zZeroToOne ? 1.0f : 2.0f)) * zNear);
- } else if (nearInf) {
- float e = 1E-6f;
- this._m22((zZeroToOne ? 0.0f : 1.0f) - e)
- ._m32(((zZeroToOne ? 1.0f : 2.0f) - e) * zFar);
- } else {
- this._m22((zZeroToOne ? zFar : zFar + zNear) / (zNear - zFar))
- ._m32((zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar));
- }
- this._m23(-1.0f)
- ._properties(PROPERTY_PERSPECTIVE);
- return this;
- }
-
- /**
- * Set this matrix to be a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f setPerspectiveRect(float width, float height, float zNear, float zFar) {
- return setPerspectiveRect(width, height, zNear, zFar, false);
- }
-
- /**
- * Set this matrix to be an asymmetric off-center perspective projection frustum transformation for a right-handed
- * coordinate system using OpenGL's NDC z range of [-1..+1]
.
- * offAngleX
and offAngleY
are the horizontal and vertical angles between
- * the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
- * is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
- * is parallel to the XZ-plane.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f setPerspectiveOffCenter(float fovy, float offAngleX, float offAngleY,
- float aspect, float zNear, float zFar) {
- return setPerspectiveOffCenter(fovy, offAngleX, offAngleY, aspect, zNear, zFar, false);
- }
- /**
- * Set this matrix to be an asymmetric off-center perspective projection frustum transformation for a right-handed
- * coordinate system using the given NDC z range.
- * offAngleX
and offAngleY
are the horizontal and vertical angles between
- * the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
- * is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
- * is parallel to the XZ-plane.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setPerspectiveOffCenter(float fovy, float offAngleX, float offAngleY,
- float aspect, float zNear, float zFar, boolean zZeroToOne) {
- MemUtil.INSTANCE.zero(this);
- float h = Math.tan(fovy * 0.5f);
- float xScale = 1.0f / (h * aspect), yScale = 1.0f / h;
- float offX = Math.tan(offAngleX), offY = Math.tan(offAngleY);
- this._m00(xScale)
- ._m11(yScale)
- ._m20(offX * xScale)
- ._m21(offY * yScale);
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- this._m22(e - 1.0f)
- ._m32((e - (zZeroToOne ? 1.0f : 2.0f)) * zNear);
- } else if (nearInf) {
- float e = 1E-6f;
- this._m22((zZeroToOne ? 0.0f : 1.0f) - e)
- ._m32(((zZeroToOne ? 1.0f : 2.0f) - e) * zFar);
- } else {
- this._m22((zZeroToOne ? zFar : zFar + zNear) / (zNear - zFar))
- ._m32((zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar));
- }
- this._m23(-1.0f)
- ._properties(offAngleX == 0.0f && offAngleY == 0.0f ? PROPERTY_PERSPECTIVE : 0);
- return this;
- }
-
- /**
- * Set this matrix to be an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate
- * system using OpenGL's NDC z range of [-1..+1]
.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f setPerspectiveOffCenterFov(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar) {
- return setPerspectiveOffCenterFov(angleLeft, angleRight, angleDown, angleUp, zNear, zFar, false);
- }
- /**
- * Set this matrix to be an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setPerspectiveOffCenterFov(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, boolean zZeroToOne) {
- return setFrustum(Math.tan(angleLeft)*zNear, Math.tan(angleRight)*zNear, Math.tan(angleDown)*zNear, Math.tan(angleUp)*zNear, zNear, zFar, zZeroToOne);
- }
-
- /**
- * Set this matrix to be an asymmetric off-center perspective projection frustum transformation for a left-handed coordinate
- * system using OpenGL's NDC z range of [-1..+1]
.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f setPerspectiveOffCenterFovLH(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar) {
- return setPerspectiveOffCenterFovLH(angleLeft, angleRight, angleDown, angleUp, zNear, zFar, false);
- }
- /**
- * Set this matrix to be an asymmetric off-center perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setPerspectiveOffCenterFovLH(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, boolean zZeroToOne) {
- return setFrustumLH(Math.tan(angleLeft)*zNear, Math.tan(angleRight)*zNear, Math.tan(angleDown)*zNear, Math.tan(angleUp)*zNear, zNear, zFar, zZeroToOne);
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f perspectiveLH(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setPerspectiveLH(fovy, aspect, zNear, zFar, zZeroToOne);
- return perspectiveLHGeneric(fovy, aspect, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f perspectiveLHGeneric(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- float h = Math.tan(fovy * 0.5f);
- // calculate right matrix elements
- float rm00 = 1.0f / (h * aspect);
- float rm11 = 1.0f / h;
- float rm22;
- float rm32;
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- rm22 = 1.0f - e;
- rm32 = (e - (zZeroToOne ? 1.0f : 2.0f)) * zNear;
- } else if (nearInf) {
- float e = 1E-6f;
- rm22 = (zZeroToOne ? 0.0f : 1.0f) - e;
- rm32 = ((zZeroToOne ? 1.0f : 2.0f) - e) * zFar;
- } else {
- rm22 = (zZeroToOne ? zFar : zFar + zNear) / (zFar - zNear);
- rm32 = (zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar);
- }
- // perform optimized matrix multiplication
- float nm20 = m20() * rm22 + m30();
- float nm21 = m21() * rm22 + m31();
- float nm22 = m22() * rm22 + m32();
- float nm23 = m23() * rm22 + m33();
- dest._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m30(m20() * rm32)
- ._m31(m21() * rm32)
- ._m32(m22() * rm32)
- ._m33(m23() * rm32)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._properties(properties & ~(PROPERTY_AFFINE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f perspectiveLH(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne) {
- return perspectiveLH(fovy, aspect, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f perspectiveLH(float fovy, float aspect, float zNear, float zFar, Matrix4f dest) {
- return perspectiveLH(fovy, aspect, zNear, zFar, false, dest);
- }
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f perspectiveLH(float fovy, float aspect, float zNear, float zFar) {
- return perspectiveLH(fovy, aspect, zNear, zFar, this);
- }
-
- /**
- * Set this matrix to be a symmetric perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range of [-1..+1]
.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setPerspectiveLH(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne) {
- MemUtil.INSTANCE.zero(this);
- float h = Math.tan(fovy * 0.5f);
- this._m00(1.0f / (h * aspect))
- ._m11(1.0f / h);
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- this._m22(1.0f - e)
- ._m32((e - (zZeroToOne ? 1.0f : 2.0f)) * zNear);
- } else if (nearInf) {
- float e = 1E-6f;
- this._m22((zZeroToOne ? 0.0f : 1.0f) - e)
- ._m32(((zZeroToOne ? 1.0f : 2.0f) - e) * zFar);
- } else {
- this._m22((zZeroToOne ? zFar : zFar + zNear) / (zFar - zNear))
- ._m32((zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar));
- }
- this._m23(1.0f)
- ._properties(PROPERTY_PERSPECTIVE);
- return this;
- }
-
- /**
- * Set this matrix to be a symmetric perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f setPerspectiveLH(float fovy, float aspect, float zNear, float zFar) {
- return setPerspectiveLH(fovy, aspect, zNear, zFar, false);
- }
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f frustum(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setFrustum(left, right, bottom, top, zNear, zFar, zZeroToOne);
- return frustumGeneric(left, right, bottom, top, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f frustumGeneric(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- // calculate right matrix elements
- float rm00 = (zNear + zNear) / (right - left);
- float rm11 = (zNear + zNear) / (top - bottom);
- float rm20 = (right + left) / (right - left);
- float rm21 = (top + bottom) / (top - bottom);
- float rm22;
- float rm32;
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- rm22 = e - 1.0f;
- rm32 = (e - (zZeroToOne ? 1.0f : 2.0f)) * zNear;
- } else if (nearInf) {
- float e = 1E-6f;
- rm22 = (zZeroToOne ? 0.0f : 1.0f) - e;
- rm32 = ((zZeroToOne ? 1.0f : 2.0f) - e) * zFar;
- } else {
- rm22 = (zZeroToOne ? zFar : zFar + zNear) / (zNear - zFar);
- rm32 = (zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar);
- }
- // perform optimized matrix multiplication
- float nm20 = m00() * rm20 + m10() * rm21 + m20() * rm22 - m30();
- float nm21 = m01() * rm20 + m11() * rm21 + m21() * rm22 - m31();
- float nm22 = m02() * rm20 + m12() * rm21 + m22() * rm22 - m32();
- float nm23 = m03() * rm20 + m13() * rm21 + m23() * rm22 - m33();
- dest._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m30(m20() * rm32)
- ._m31(m21() * rm32)
- ._m32(m22() * rm32)
- ._m33(m23() * rm32)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._properties(0);
- return dest;
- }
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f frustum(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest) {
- return frustum(left, right, bottom, top, zNear, zFar, false, dest);
- }
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f frustum(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne) {
- return frustum(left, right, bottom, top, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f frustum(float left, float right, float bottom, float top, float zNear, float zFar) {
- return frustum(left, right, bottom, top, zNear, zFar, this);
- }
-
- /**
- * Set this matrix to be an arbitrary perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setFrustum(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00((zNear + zNear) / (right - left))
- ._m11((zNear + zNear) / (top - bottom))
- ._m20((right + left) / (right - left))
- ._m21((top + bottom) / (top - bottom));
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- this._m22(e - 1.0f)
- ._m32((e - (zZeroToOne ? 1.0f : 2.0f)) * zNear);
- } else if (nearInf) {
- float e = 1E-6f;
- this._m22((zZeroToOne ? 0.0f : 1.0f) - e)
- ._m32(((zZeroToOne ? 1.0f : 2.0f) - e) * zFar);
- } else {
- this._m22((zZeroToOne ? zFar : zFar + zNear) / (zNear - zFar))
- ._m32((zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar));
- }
- this._m23(-1.0f)
- ._m33(0.0f)
- ._properties(this.m20() == 0.0f && this.m21() == 0.0f ? PROPERTY_PERSPECTIVE : 0);
- return this;
- }
-
- /**
- * Set this matrix to be an arbitrary perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f setFrustum(float left, float right, float bottom, float top, float zNear, float zFar) {
- return setFrustum(left, right, bottom, top, zNear, zFar, false);
- }
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f frustumLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.setFrustumLH(left, right, bottom, top, zNear, zFar, zZeroToOne);
- return frustumLHGeneric(left, right, bottom, top, zNear, zFar, zZeroToOne, dest);
- }
- private Matrix4f frustumLHGeneric(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest) {
- // calculate right matrix elements
- float rm00 = (zNear + zNear) / (right - left);
- float rm11 = (zNear + zNear) / (top - bottom);
- float rm20 = (right + left) / (right - left);
- float rm21 = (top + bottom) / (top - bottom);
- float rm22;
- float rm32;
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- rm22 = 1.0f - e;
- rm32 = (e - (zZeroToOne ? 1.0f : 2.0f)) * zNear;
- } else if (nearInf) {
- float e = 1E-6f;
- rm22 = (zZeroToOne ? 0.0f : 1.0f) - e;
- rm32 = ((zZeroToOne ? 1.0f : 2.0f) - e) * zFar;
- } else {
- rm22 = (zZeroToOne ? zFar : zFar + zNear) / (zFar - zNear);
- rm32 = (zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar);
- }
- // perform optimized matrix multiplication
- float nm20 = m00() * rm20 + m10() * rm21 + m20() * rm22 + m30();
- float nm21 = m01() * rm20 + m11() * rm21 + m21() * rm22 + m31();
- float nm22 = m02() * rm20 + m12() * rm21 + m22() * rm22 + m32();
- float nm23 = m03() * rm20 + m13() * rm21 + m23() * rm22 + m33();
- dest._m00(m00() * rm00)
- ._m01(m01() * rm00)
- ._m02(m02() * rm00)
- ._m03(m03() * rm00)
- ._m10(m10() * rm11)
- ._m11(m11() * rm11)
- ._m12(m12() * rm11)
- ._m13(m13() * rm11)
- ._m30(m20() * rm32)
- ._m31(m21() * rm32)
- ._m32(m22() * rm32)
- ._m33(m23() * rm32)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._properties(0);
- return dest;
- }
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f frustumLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne) {
- return frustumLH(left, right, bottom, top, zNear, zFar, zZeroToOne, this);
- }
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f frustumLH(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest) {
- return frustumLH(left, right, bottom, top, zNear, zFar, false, dest);
- }
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f frustumLH(float left, float right, float bottom, float top, float zNear, float zFar) {
- return frustumLH(left, right, bottom, top, zNear, zFar, this);
- }
-
- /**
- * Set this matrix to be an arbitrary perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return this
- */
- public Matrix4f setFrustumLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne) {
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00((zNear + zNear) / (right - left))
- ._m11((zNear + zNear) / (top - bottom))
- ._m20((right + left) / (right - left))
- ._m21((top + bottom) / (top - bottom));
- boolean farInf = zFar > 0 && Float.isInfinite(zFar);
- boolean nearInf = zNear > 0 && Float.isInfinite(zNear);
- if (farInf) {
- // See: "Infinite Projection Matrix" (http://www.terathon.com/gdc07_lengyel.pdf)
- float e = 1E-6f;
- this._m22(1.0f - e)
- ._m32((e - (zZeroToOne ? 1.0f : 2.0f)) * zNear);
- } else if (nearInf) {
- float e = 1E-6f;
- this._m22((zZeroToOne ? 0.0f : 1.0f) - e)
- ._m32(((zZeroToOne ? 1.0f : 2.0f) - e) * zFar);
- } else {
- this._m22((zZeroToOne ? zFar : zFar + zNear) / (zFar - zNear))
- ._m32((zZeroToOne ? zFar : zFar + zFar) * zNear / (zNear - zFar));
- }
- return this
- ._m23(1.0f)
- ._m33(0.0f)
- ._properties(0);
- }
-
- /**
- * Set this matrix to be an arbitrary perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
.
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @return this
- */
- public Matrix4f setFrustumLH(float left, float right, float bottom, float top, float zNear, float zFar) {
- return setFrustumLH(left, right, bottom, top, zNear, zFar, false);
- }
-
- /**
- * Set this matrix to represent a perspective projection equivalent to the given intrinsic camera calibration parameters.
- * The resulting matrix will be suited for a right-handed coordinate system using OpenGL's NDC z range of [-1..+1]
.
- * 0
)
- * @param u0
- * the X coordinate of the principal point in image/sensor units
- * @param v0
- * the Y coordinate of the principal point in image/sensor units
- * @param imgWidth
- * the width of the sensor/image image/sensor units
- * @param imgHeight
- * the height of the sensor/image image/sensor units
- * @param near
- * the distance to the near plane
- * @param far
- * the distance to the far plane
- * @return this
- */
- public Matrix4f setFromIntrinsic(float alphaX, float alphaY, float gamma, float u0, float v0, int imgWidth, int imgHeight, float near, float far) {
- float l00 = 2.0f / imgWidth;
- float l11 = 2.0f / imgHeight;
- float l22 = 2.0f / (near - far);
- return this
- ._m00(l00 * alphaX)
- ._m01(0.0f)
- ._m02(0.0f)
- ._m03(0.0f)
- ._m10(l00 * gamma)
- ._m11(l11 * alphaY)
- ._m12(0.0f)
- ._m13(0.0f)
- ._m20(l00 * u0 - 1.0f)
- ._m21(l11 * v0 - 1.0f)
- ._m22(l22 * -(near + far) + (far + near) / (near - far))
- ._m23(-1.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(l22 * -near * far)
- ._m33(0.0f)
- ._properties(PROPERTY_PERSPECTIVE);
- }
-
- /**
- * Apply the rotation transformation of the given {@link Quaternionfc} to this matrix and store
- * the result in dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * dest
.
- * this
to be {@link #isAffine() affine}.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * this
to be {@link #isAffine() affine}.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * dest
.
- * this
to only contain a translation.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * (ox, oy, oz)
as the rotation origin.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * translate(ox, oy, oz).rotate(quat).translate(-ox, -oy, -oz)
- * (ox, oy, oz)
as the rotation origin.
- * translation(ox, oy, oz).rotate(quat).translate(-ox, -oy, -oz)
- * dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be Q * M
. So when transforming a
- * vector v
with the new matrix by using Q * M * v
,
- * the quaternion rotation will be applied last!
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be Q * M
. So when transforming a
- * vector v
with the new matrix by using Q * M * v
,
- * the quaternion rotation will be applied last!
- * (ox, oy, oz)
- * as the rotation origin.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be Q * M
. So when transforming a
- * vector v
with the new matrix by using Q * M * v
,
- * the quaternion rotation will be applied last!
- * translateLocal(-ox, -oy, -oz).rotateLocal(quat).translateLocal(ox, oy, oz)
- * M
is this
matrix and A
the rotation matrix obtained from the given {@link AxisAngle4f},
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the {@link AxisAngle4f} rotation will be applied first!
- * dest
.
- * M
is this
matrix and A
the rotation matrix obtained from the given {@link AxisAngle4f},
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the {@link AxisAngle4f} rotation will be applied first!
- * axis
vector needs to be a unit vector.
- * M
is this
matrix and A
the rotation matrix obtained from the given axis-angle,
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the axis-angle rotation will be applied first!
- * dest
.
- * axis
vector needs to be a unit vector.
- * M
is this
matrix and A
the rotation matrix obtained from the given axis-angle,
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the axis-angle rotation will be applied first!
- * x*a + y*b + z*c + d = 0
.
- * (a, b, c)
must be a unit vector.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param nx
- * the x-coordinate of the plane normal
- * @param ny
- * the y-coordinate of the plane normal
- * @param nz
- * the z-coordinate of the plane normal
- * @param px
- * the x-coordinate of a point on the plane
- * @param py
- * the y-coordinate of a point on the plane
- * @param pz
- * the z-coordinate of a point on the plane
- * @return this
- */
- public Matrix4f reflect(float nx, float ny, float nz, float px, float py, float pz) {
- return reflect(nx, ny, nz, px, py, pz, this);
- }
-
- public Matrix4f reflect(float nx, float ny, float nz, float px, float py, float pz, Matrix4f dest) {
- float invLength = Math.invsqrt(nx * nx + ny * ny + nz * nz);
- float nnx = nx * invLength;
- float nny = ny * invLength;
- float nnz = nz * invLength;
- /* See: http://mathworld.wolfram.com/Plane.html */
- return reflect(nnx, nny, nnz, -nnx * px - nny * py - nnz * pz, dest);
- }
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects about the given plane
- * specified via the plane normal and a point on the plane.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param normal
- * the plane normal
- * @param point
- * a point on the plane
- * @return this
- */
- public Matrix4f reflect(Vector3fc normal, Vector3fc point) {
- return reflect(normal.x(), normal.y(), normal.z(), point.x(), point.y(), point.z());
- }
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects about a plane
- * specified via the plane orientation and a point on the plane.
- * (0, 0, 1)
. So, if the given {@link Quaternionfc} is
- * the identity (does not apply any additional rotation), the reflection plane will be z=0
, offset by the given point
.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param orientation
- * the plane orientation
- * @param point
- * a point on the plane
- * @return this
- */
- public Matrix4f reflect(Quaternionfc orientation, Vector3fc point) {
- return reflect(orientation, point, this);
- }
-
- public Matrix4f reflect(Quaternionfc orientation, Vector3fc point, Matrix4f dest) {
- double num1 = orientation.x() + orientation.x();
- double num2 = orientation.y() + orientation.y();
- double num3 = orientation.z() + orientation.z();
- float normalX = (float) (orientation.x() * num3 + orientation.w() * num2);
- float normalY = (float) (orientation.y() * num3 - orientation.w() * num1);
- float normalZ = (float) (1.0 - (orientation.x() * num1 + orientation.y() * num2));
- return reflect(normalX, normalY, normalZ, point.x(), point.y(), point.z(), dest);
- }
-
- public Matrix4f reflect(Vector3fc normal, Vector3fc point, Matrix4f dest) {
- return reflect(normal.x(), normal.y(), normal.z(), point.x(), point.y(), point.z(), dest);
- }
-
- /**
- * Set this matrix to a mirror/reflection transformation that reflects about the given plane
- * specified via the equation x*a + y*b + z*c + d = 0
.
- * (a, b, c)
must be a unit vector.
- * (0, 0, 1)
. So, if the given {@link Quaternionfc} is
- * the identity (does not apply any additional rotation), the reflection plane will be z=0
, offset by the given point
.
- *
- * @param orientation
- * the plane orientation
- * @param point
- * a point on the plane
- * @return this
- */
- public Matrix4f reflection(Quaternionfc orientation, Vector3fc point) {
- double num1 = orientation.x() + orientation.x();
- double num2 = orientation.y() + orientation.y();
- double num3 = orientation.z() + orientation.z();
- float normalX = (float) (orientation.x() * num3 + orientation.w() * num2);
- float normalY = (float) (orientation.y() * num3 - orientation.w() * num1);
- float normalZ = (float) (1.0 - (orientation.x() * num1 + orientation.y() * num2));
- return reflection(normalX, normalY, normalZ, point.x(), point.y(), point.z());
- }
-
- public Vector4f getRow(int row, Vector4f dest) throws IndexOutOfBoundsException {
- switch (row) {
- case 0:
- return dest.set(m00(), m10(), m20(), m30());
- case 1:
- return dest.set(m01(), m11(), m21(), m31());
- case 2:
- return dest.set(m02(), m12(), m22(), m32());
- case 3:
- return dest.set(m03(), m13(), m23(), m33());
- default:
- throw new IndexOutOfBoundsException();
- }
- }
-
- public Vector3f getRow(int row, Vector3f dest) throws IndexOutOfBoundsException {
- switch (row) {
- case 0:
- return dest.set(m00(), m10(), m20());
- case 1:
- return dest.set(m01(), m11(), m21());
- case 2:
- return dest.set(m02(), m12(), m22());
- case 3:
- return dest.set(m03(), m13(), m23());
- default:
- throw new IndexOutOfBoundsException();
- }
- }
-
- /**
- * Set the row at the given row
index, starting with 0
.
- *
- * @param row
- * the row index in [0..3]
- * @param src
- * the row components to set
- * @return this
- * @throws IndexOutOfBoundsException if row
is not in [0..3]
- */
- public Matrix4f setRow(int row, Vector4fc src) throws IndexOutOfBoundsException {
- switch (row) {
- case 0:
- return _m00(src.x())._m10(src.y())._m20(src.z())._m30(src.w())._properties(0);
- case 1:
- return _m01(src.x())._m11(src.y())._m21(src.z())._m31(src.w())._properties(0);
- case 2:
- return _m02(src.x())._m12(src.y())._m22(src.z())._m32(src.w())._properties(0);
- case 3:
- return _m03(src.x())._m13(src.y())._m23(src.z())._m33(src.w())._properties(0);
- default:
- throw new IndexOutOfBoundsException();
- }
- }
-
- public Vector4f getColumn(int column, Vector4f dest) throws IndexOutOfBoundsException {
- return MemUtil.INSTANCE.getColumn(this, column, dest);
- }
-
- public Vector3f getColumn(int column, Vector3f dest) throws IndexOutOfBoundsException {
- switch (column) {
- case 0:
- return dest.set(m00(), m01(), m02());
- case 1:
- return dest.set(m10(), m11(), m12());
- case 2:
- return dest.set(m20(), m21(), m22());
- case 3:
- return dest.set(m30(), m31(), m32());
- default:
- throw new IndexOutOfBoundsException();
- }
- }
-
- /**
- * Set the column at the given column
index, starting with 0
.
- *
- * @param column
- * the column index in [0..3]
- * @param src
- * the column components to set
- * @return this
- * @throws IndexOutOfBoundsException if column
is not in [0..3]
- */
- public Matrix4f setColumn(int column, Vector4fc src) throws IndexOutOfBoundsException {
- if (src instanceof Vector4f)
- return MemUtil.INSTANCE.setColumn((Vector4f) src, column, this)._properties(0);
- return MemUtil.INSTANCE.setColumn(src, column, this)._properties(0);
- }
-
- public float get(int column, int row) {
- return MemUtil.INSTANCE.get(this, column, row);
- }
-
- /**
- * Set the matrix element at the given column and row to the specified value.
- *
- * @param column
- * the colum index in [0..3]
- * @param row
- * the row index in [0..3]
- * @param value
- * the value
- * @return this
- */
- public Matrix4f set(int column, int row, float value) {
- return MemUtil.INSTANCE.set(this, column, row, value);
- }
-
- public float getRowColumn(int row, int column) {
- return MemUtil.INSTANCE.get(this, column, row);
- }
-
- /**
- * Set the matrix element at the given row and column to the specified value.
- *
- * @param row
- * the row index in [0..3]
- * @param column
- * the colum index in [0..3]
- * @param value
- * the value
- * @return this
- */
- public Matrix4f setRowColumn(int row, int column, float value) {
- return MemUtil.INSTANCE.set(this, column, row, value);
- }
-
- /**
- * Compute a normal matrix from the upper left 3x3 submatrix of this
- * and store it into the upper left 3x3 submatrix of this
.
- * All other values of this
will be set to {@link #identity() identity}.
- * m
is the transpose of the inverse of m
.
- * this
is an orthogonal matrix or a matrix whose columns are orthogonal vectors,
- * then this method need not be invoked, since in that case this
itself is its normal matrix.
- * In that case, use {@link #set3x3(Matrix4f)} to set a given Matrix4f to only the upper left 3x3 submatrix
- * of this matrix.
- *
- * @see #set3x3(Matrix4f)
- *
- * @return this
- */
- public Matrix4f normal() {
- return normal(this);
- }
-
- /**
- * Compute a normal matrix from the upper left 3x3 submatrix of this
- * and store it into the upper left 3x3 submatrix of dest
.
- * All other values of dest
will be set to {@link #identity() identity}.
- * m
is the transpose of the inverse of m
.
- * this
is an orthogonal matrix or a matrix whose columns are orthogonal vectors,
- * then this method need not be invoked, since in that case this
itself is its normal matrix.
- * In that case, use {@link #set3x3(Matrix4f)} to set a given Matrix4f to only the upper left 3x3 submatrix
- * of this matrix.
- *
- * @see #set3x3(Matrix4f)
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f normal(Matrix4f dest) {
- if ((properties & PROPERTY_IDENTITY) != 0)
- return dest.identity();
- else if ((properties & PROPERTY_ORTHONORMAL) != 0)
- return normalOrthonormal(dest);
- return normalGeneric(dest);
- }
- private Matrix4f normalOrthonormal(Matrix4f dest) {
- if (dest != this)
- dest.set(this);
- return dest._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- }
- private Matrix4f normalGeneric(Matrix4f dest) {
- float m00m11 = m00() * m11();
- float m01m10 = m01() * m10();
- float m02m10 = m02() * m10();
- float m00m12 = m00() * m12();
- float m01m12 = m01() * m12();
- float m02m11 = m02() * m11();
- float det = (m00m11 - m01m10) * m22() + (m02m10 - m00m12) * m21() + (m01m12 - m02m11) * m20();
- float s = 1.0f / det;
- /* Invert and transpose in one go */
- float nm00 = (m11() * m22() - m21() * m12()) * s;
- float nm01 = (m20() * m12() - m10() * m22()) * s;
- float nm02 = (m10() * m21() - m20() * m11()) * s;
- float nm10 = (m21() * m02() - m01() * m22()) * s;
- float nm11 = (m00() * m22() - m20() * m02()) * s;
- float nm12 = (m20() * m01() - m00() * m21()) * s;
- float nm20 = (m01m12 - m02m11) * s;
- float nm21 = (m02m10 - m00m12) * s;
- float nm22 = (m00m11 - m01m10) * s;
- return dest
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(0.0f)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(0.0f)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(1.0f)
- ._properties((properties | PROPERTY_AFFINE) & ~(PROPERTY_TRANSLATION | PROPERTY_PERSPECTIVE));
- }
-
- /**
- * Compute a normal matrix from the upper left 3x3 submatrix of this
- * and store it into dest
.
- * m
is the transpose of the inverse of m
.
- * this
is an orthogonal matrix or a matrix whose columns are orthogonal vectors,
- * then this method need not be invoked, since in that case this
itself is its normal matrix.
- * In that case, use {@link Matrix3f#set(Matrix4fc)} to set a given Matrix3f to only the upper left 3x3 submatrix
- * of this matrix.
- *
- * @see Matrix3f#set(Matrix4fc)
- * @see #get3x3(Matrix3f)
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix3f normal(Matrix3f dest) {
- if ((properties & PROPERTY_ORTHONORMAL) != 0)
- return normalOrthonormal(dest);
- return normalGeneric(dest);
- }
- private Matrix3f normalOrthonormal(Matrix3f dest) {
- dest.set(this);
- return dest;
- }
- private Matrix3f normalGeneric(Matrix3f dest) {
- float det = (m00() * m11() - (m01() * m10())) * m22()
- + (m02() * m10() - (m00() * m12())) * m21()
- + (m01() * m12() - (m02() * m11())) * m20();
- float s = 1.0f / det;
- /* Invert and transpose in one go */
- return dest._m00((m11() * m22() - m21() * m12()) * s)
- ._m01((m20() * m12() - m10() * m22()) * s)
- ._m02((m10() * m21() - m20() * m11()) * s)
- ._m10((m21() * m02() - m01() * m22()) * s)
- ._m11((m00() * m22() - m20() * m02()) * s)
- ._m12((m20() * m01() - m00() * m21()) * s)
- ._m20((m01() * m12() - m02() * m11()) * s)
- ._m21((m02() * m10() - m00() * m12()) * s)
- ._m22((m00() * m11() - m01() * m10()) * s);
- }
-
- /**
- * Compute the cofactor matrix of the upper left 3x3 submatrix of this
.
- * this
- * and store it into dest
.
- * this
- * and store it into dest
.
- * All other values of dest
will be set to {@link #identity() identity}.
- * this
matrix,
- * which can be a projection matrix or a combined modelview-projection matrix, and store the result
- * in the given origin
.
- * this
- * transformation was applied to it in order to yield homogeneous clipping space.
- * invert(new Matrix4f()).transformProject(0, 0, -1, 0, origin)
- * and in the case of an already available inverse of this
matrix, the method {@link #perspectiveInvOrigin(Vector3f)}
- * on the inverse of the matrix should be used instead.
- * this
- * perspective projection transformation
- * @return origin
- */
- public Vector3f perspectiveOrigin(Vector3f origin) {
- /*
- * Simply compute the intersection point of the left, right and top frustum plane.
- */
- float d1, d2, d3;
- float n1x, n1y, n1z, n2x, n2y, n2z, n3x, n3y, n3z;
- n1x = m03() + m00(); n1y = m13() + m10(); n1z = m23() + m20(); d1 = m33() + m30(); // left
- n2x = m03() - m00(); n2y = m13() - m10(); n2z = m23() - m20(); d2 = m33() - m30(); // right
- n3x = m03() - m01(); n3y = m13() - m11(); n3z = m23() - m21(); d3 = m33() - m31(); // top
- float c23x, c23y, c23z;
- c23x = n2y * n3z - n2z * n3y;
- c23y = n2z * n3x - n2x * n3z;
- c23z = n2x * n3y - n2y * n3x;
- float c31x, c31y, c31z;
- c31x = n3y * n1z - n3z * n1y;
- c31y = n3z * n1x - n3x * n1z;
- c31z = n3x * n1y - n3y * n1x;
- float c12x, c12y, c12z;
- c12x = n1y * n2z - n1z * n2y;
- c12y = n1z * n2x - n1x * n2z;
- c12z = n1x * n2y - n1y * n2x;
- float invDot = 1.0f / (n1x * c23x + n1y * c23y + n1z * c23z);
- origin.x = (-c23x * d1 - c31x * d2 - c12x * d3) * invDot;
- origin.y = (-c23y * d1 - c31y * d2 - c12y * d3) * invDot;
- origin.z = (-c23z * d1 - c31z * d2 - c12z * d3) * invDot;
- return origin;
- }
-
- /**
- * Compute the eye/origin of the inverse of the perspective frustum transformation defined by this
matrix,
- * which can be the inverse of a projection matrix or the inverse of a combined modelview-projection matrix, and store the result
- * in the given dest
.
- * 0.0
.
- * this
perspective projection matrix.
- * this
is a perspective projection matrix, for example obtained via {@link #perspective(float, float, float, float)}.
- *
- * @return the near clip plane distance
- */
- public float perspectiveNear() {
- return m32() / (m23() + m22());
- }
-
- /**
- * Extract the far clip plane distance from this
perspective projection matrix.
- * this
is a perspective projection matrix, for example obtained via {@link #perspective(float, float, float, float)}.
- *
- * @return the far clip plane distance
- */
- public float perspectiveFar() {
- return m32() / (m22() - m23());
- }
-
- public Vector3f frustumRayDir(float x, float y, Vector3f dir) {
- /*
- * This method works by first obtaining the frustum plane normals,
- * then building the cross product to obtain the corner rays,
- * and finally bilinearly interpolating to obtain the desired direction.
- * The code below uses a condense form of doing all this making use
- * of some mathematical identities to simplify the overall expression.
- */
- float a = m10() * m23(), b = m13() * m21(), c = m10() * m21(), d = m11() * m23(), e = m13() * m20(), f = m11() * m20();
- float g = m03() * m20(), h = m01() * m23(), i = m01() * m20(), j = m03() * m21(), k = m00() * m23(), l = m00() * m21();
- float m = m00() * m13(), n = m03() * m11(), o = m00() * m11(), p = m01() * m13(), q = m03() * m10(), r = m01() * m10();
- float m1x, m1y, m1z;
- m1x = (d + e + f - a - b - c) * (1.0f - y) + (a - b - c + d - e + f) * y;
- m1y = (j + k + l - g - h - i) * (1.0f - y) + (g - h - i + j - k + l) * y;
- m1z = (p + q + r - m - n - o) * (1.0f - y) + (m - n - o + p - q + r) * y;
- float m2x, m2y, m2z;
- m2x = (b - c - d + e + f - a) * (1.0f - y) + (a + b - c - d - e + f) * y;
- m2y = (h - i - j + k + l - g) * (1.0f - y) + (g + h - i - j - k + l) * y;
- m2z = (n - o - p + q + r - m) * (1.0f - y) + (m + n - o - p - q + r) * y;
- dir.x = m1x + (m2x - m1x) * x;
- dir.y = m1y + (m2y - m1y) * x;
- dir.z = m1z + (m2z - m1z) * x;
- return dir.normalize(dir);
- }
-
- public Vector3f positiveZ(Vector3f dir) {
- if ((properties & PROPERTY_ORTHONORMAL) != 0)
- return normalizedPositiveZ(dir);
- return positiveZGeneric(dir);
- }
- private Vector3f positiveZGeneric(Vector3f dir) {
- return dir.set(m10() * m21() - m11() * m20(), m20() * m01() - m21() * m00(), m00() * m11() - m01() * m10()).normalize();
- }
-
- public Vector3f normalizedPositiveZ(Vector3f dir) {
- return dir.set(m02(), m12(), m22());
- }
-
- public Vector3f positiveX(Vector3f dir) {
- if ((properties & PROPERTY_ORTHONORMAL) != 0)
- return normalizedPositiveX(dir);
- return positiveXGeneric(dir);
- }
- private Vector3f positiveXGeneric(Vector3f dir) {
- return dir.set(m11() * m22() - m12() * m21(), m02() * m21() - m01() * m22(), m01() * m12() - m02() * m11()).normalize();
- }
-
- public Vector3f normalizedPositiveX(Vector3f dir) {
- return dir.set(m00(), m10(), m20());
- }
-
- public Vector3f positiveY(Vector3f dir) {
- if ((properties & PROPERTY_ORTHONORMAL) != 0)
- return normalizedPositiveY(dir);
- return positiveYGeneric(dir);
- }
- private Vector3f positiveYGeneric(Vector3f dir) {
- return dir.set(m12() * m20() - m10() * m22(), m00() * m22() - m02() * m20(), m02() * m10() - m00() * m12()).normalize();
- }
-
- public Vector3f normalizedPositiveY(Vector3f dir) {
- return dir.set(m01(), m11(), m21());
- }
-
- public Vector3f originAffine(Vector3f origin) {
- float a = m00() * m11() - m01() * m10();
- float b = m00() * m12() - m02() * m10();
- float d = m01() * m12() - m02() * m11();
- float g = m20() * m31() - m21() * m30();
- float h = m20() * m32() - m22() * m30();
- float j = m21() * m32() - m22() * m31();
- return origin.set(-m10() * j + m11() * h - m12() * g, m00() * j - m01() * h + m02() * g, -m30() * d + m31() * b - m32() * a);
- }
-
- public Vector3f origin(Vector3f dest) {
- if ((properties & PROPERTY_AFFINE) != 0)
- return originAffine(dest);
- return originGeneric(dest);
- }
- private Vector3f originGeneric(Vector3f dest) {
- float a = m00() * m11() - m01() * m10();
- float b = m00() * m12() - m02() * m10();
- float c = m00() * m13() - m03() * m10();
- float d = m01() * m12() - m02() * m11();
- float e = m01() * m13() - m03() * m11();
- float f = m02() * m13() - m03() * m12();
- float g = m20() * m31() - m21() * m30();
- float h = m20() * m32() - m22() * m30();
- float i = m20() * m33() - m23() * m30();
- float j = m21() * m32() - m22() * m31();
- float k = m21() * m33() - m23() * m31();
- float l = m22() * m33() - m23() * m32();
- float det = a * l - b * k + c * j + d * i - e * h + f * g;
- float invDet = 1.0f / det;
- float nm30 = (-m10() * j + m11() * h - m12() * g) * invDet;
- float nm31 = ( m00() * j - m01() * h + m02() * g) * invDet;
- float nm32 = (-m30() * d + m31() * b - m32() * a) * invDet;
- float nm33 = det / ( m20() * d - m21() * b + m22() * a);
- return dest.set(nm30 * nm33, nm31 * nm33, nm32 * nm33);
- }
-
- /**
- * Apply a projection transformation to this matrix that projects onto the plane specified via the general plane equation
- * x*a + y*b + z*c + d = 0
as if casting a shadow from a given light position/direction light
.
- * light.w
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
- * M
is this
matrix and S
the shadow matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * shadow projection will be applied first!
- * x*a + y*b + z*c + d = 0
as if casting a shadow from a given light position/direction (lightX, lightY, lightZ, lightW)
.
- * lightW
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
- * M
is this
matrix and S
the shadow matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * shadow projection will be applied first!
- * y = 0
as if casting a shadow from a given light position/direction light
.
- * planeTransformation
.
- * light.w
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
- * M
is this
matrix and S
the shadow matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * shadow projection will be applied first!
- *
- * @param light
- * the light's vector
- * @param planeTransform
- * the transformation to transform the implied plane y = 0
before applying the projection
- * @return this
- */
- public Matrix4f shadow(Vector4f light, Matrix4f planeTransform) {
- return shadow(light, planeTransform, this);
- }
-
- public Matrix4f shadow(float lightX, float lightY, float lightZ, float lightW, Matrix4fc planeTransform, Matrix4f dest) {
- // compute plane equation by transforming (y = 0)
- float a = planeTransform.m10();
- float b = planeTransform.m11();
- float c = planeTransform.m12();
- float d = -a * planeTransform.m30() - b * planeTransform.m31() - c * planeTransform.m32();
- return shadow(lightX, lightY, lightZ, lightW, a, b, c, d, dest);
- }
-
- /**
- * Apply a projection transformation to this matrix that projects onto the plane with the general plane equation
- * y = 0
as if casting a shadow from a given light position/direction (lightX, lightY, lightZ, lightW)
.
- * planeTransformation
.
- * lightW
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
- * M
is this
matrix and S
the shadow matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * shadow projection will be applied first!
- *
- * @param lightX
- * the x-component of the light vector
- * @param lightY
- * the y-component of the light vector
- * @param lightZ
- * the z-component of the light vector
- * @param lightW
- * the w-component of the light vector
- * @param planeTransform
- * the transformation to transform the implied plane y = 0
before applying the projection
- * @return this
- */
- public Matrix4f shadow(float lightX, float lightY, float lightZ, float lightW, Matrix4f planeTransform) {
- return shadow(lightX, lightY, lightZ, lightW, planeTransform, this);
- }
-
- /**
- * Set this matrix to a cylindrical billboard transformation that rotates the local +Z axis of a given object with position objPos
towards
- * a target position at targetPos
while constraining a cylindrical rotation around the given up
vector.
- * objPos
.
- *
- * @param objPos
- * the position of the object to rotate towards targetPos
- * @param targetPos
- * the position of the target (for example the camera) towards which to rotate the object
- * @param up
- * the rotation axis (must be {@link Vector3f#normalize() normalized})
- * @return this
- */
- public Matrix4f billboardCylindrical(Vector3fc objPos, Vector3fc targetPos, Vector3fc up) {
- float dirX = targetPos.x() - objPos.x();
- float dirY = targetPos.y() - objPos.y();
- float dirZ = targetPos.z() - objPos.z();
- // left = up x dir
- float leftX = up.y() * dirZ - up.z() * dirY;
- float leftY = up.z() * dirX - up.x() * dirZ;
- float leftZ = up.x() * dirY - up.y() * dirX;
- // normalize left
- float invLeftLen = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLen;
- leftY *= invLeftLen;
- leftZ *= invLeftLen;
- // recompute dir by constraining rotation around 'up'
- // dir = left x up
- dirX = leftY * up.z() - leftZ * up.y();
- dirY = leftZ * up.x() - leftX * up.z();
- dirZ = leftX * up.y() - leftY * up.x();
- // normalize dir
- float invDirLen = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= invDirLen;
- dirY *= invDirLen;
- dirZ *= invDirLen;
- // set matrix elements
- this._m00(leftX)
- ._m01(leftY)
- ._m02(leftZ)
- ._m03(0.0f)
- ._m10(up.x())
- ._m11(up.y())
- ._m12(up.z())
- ._m13(0.0f)
- ._m20(dirX)
- ._m21(dirY)
- ._m22(dirZ)
- ._m23(0.0f)
- ._m30(objPos.x())
- ._m31(objPos.y())
- ._m32(objPos.z())
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- /**
- * Set this matrix to a spherical billboard transformation that rotates the local +Z axis of a given object with position objPos
towards
- * a target position at targetPos
.
- * objPos
.
- * targetPos
- * @param targetPos
- * the position of the target (for example the camera) towards which to rotate the object
- * @param up
- * the up axis used to orient the object
- * @return this
- */
- public Matrix4f billboardSpherical(Vector3fc objPos, Vector3fc targetPos, Vector3fc up) {
- float dirX = targetPos.x() - objPos.x();
- float dirY = targetPos.y() - objPos.y();
- float dirZ = targetPos.z() - objPos.z();
- // normalize dir
- float invDirLen = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- dirX *= invDirLen;
- dirY *= invDirLen;
- dirZ *= invDirLen;
- // left = up x dir
- float leftX = up.y() * dirZ - up.z() * dirY;
- float leftY = up.z() * dirX - up.x() * dirZ;
- float leftZ = up.x() * dirY - up.y() * dirX;
- // normalize left
- float invLeftLen = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLen;
- leftY *= invLeftLen;
- leftZ *= invLeftLen;
- // up = dir x left
- float upX = dirY * leftZ - dirZ * leftY;
- float upY = dirZ * leftX - dirX * leftZ;
- float upZ = dirX * leftY - dirY * leftX;
- // set matrix elements
- this._m00(leftX)
- ._m01(leftY)
- ._m02(leftZ)
- ._m03(0.0f)
- ._m10(upX)
- ._m11(upY)
- ._m12(upZ)
- ._m13(0.0f)
- ._m20(dirX)
- ._m21(dirY)
- ._m22(dirZ)
- ._m23(0.0f)
- ._m30(objPos.x())
- ._m31(objPos.y())
- ._m32(objPos.z())
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- /**
- * Set this matrix to a spherical billboard transformation that rotates the local +Z axis of a given object with position objPos
towards
- * a target position at targetPos
using a shortest arc rotation by not preserving any up vector of the object.
- * objPos
.
- * targetPos
- * @param targetPos
- * the position of the target (for example the camera) towards which to rotate the object
- * @return this
- */
- public Matrix4f billboardSpherical(Vector3fc objPos, Vector3fc targetPos) {
- float toDirX = targetPos.x() - objPos.x();
- float toDirY = targetPos.y() - objPos.y();
- float toDirZ = targetPos.z() - objPos.z();
- float x = -toDirY;
- float y = toDirX;
- float w = Math.sqrt(toDirX * toDirX + toDirY * toDirY + toDirZ * toDirZ) + toDirZ;
- float invNorm = Math.invsqrt(x * x + y * y + w * w);
- x *= invNorm;
- y *= invNorm;
- w *= invNorm;
- float q00 = (x + x) * x;
- float q11 = (y + y) * y;
- float q01 = (x + x) * y;
- float q03 = (x + x) * w;
- float q13 = (y + y) * w;
- this._m00(1.0f - q11)
- ._m01(q01)
- ._m02(-q13)
- ._m03(0.0f)
- ._m10(q01)
- ._m11(1.0f - q00)
- ._m12(q03)
- ._m13(0.0f)
- ._m20(q13)
- ._m21(-q03)
- ._m22(1.0f - q11 - q00)
- ._m23(0.0f)
- ._m30(objPos.x())
- ._m31(objPos.y())
- ._m32(objPos.z())
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Float.floatToIntBits(m00());
- result = prime * result + Float.floatToIntBits(m01());
- result = prime * result + Float.floatToIntBits(m02());
- result = prime * result + Float.floatToIntBits(m03());
- result = prime * result + Float.floatToIntBits(m10());
- result = prime * result + Float.floatToIntBits(m11());
- result = prime * result + Float.floatToIntBits(m12());
- result = prime * result + Float.floatToIntBits(m13());
- result = prime * result + Float.floatToIntBits(m20());
- result = prime * result + Float.floatToIntBits(m21());
- result = prime * result + Float.floatToIntBits(m22());
- result = prime * result + Float.floatToIntBits(m23());
- result = prime * result + Float.floatToIntBits(m30());
- result = prime * result + Float.floatToIntBits(m31());
- result = prime * result + Float.floatToIntBits(m32());
- result = prime * result + Float.floatToIntBits(m33());
- return result;
- }
-
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (!(obj instanceof Matrix4f))
- return false;
- Matrix4fc other = (Matrix4fc) obj;
- if (Float.floatToIntBits(m00()) != Float.floatToIntBits(other.m00()))
- return false;
- if (Float.floatToIntBits(m01()) != Float.floatToIntBits(other.m01()))
- return false;
- if (Float.floatToIntBits(m02()) != Float.floatToIntBits(other.m02()))
- return false;
- if (Float.floatToIntBits(m03()) != Float.floatToIntBits(other.m03()))
- return false;
- if (Float.floatToIntBits(m10()) != Float.floatToIntBits(other.m10()))
- return false;
- if (Float.floatToIntBits(m11()) != Float.floatToIntBits(other.m11()))
- return false;
- if (Float.floatToIntBits(m12()) != Float.floatToIntBits(other.m12()))
- return false;
- if (Float.floatToIntBits(m13()) != Float.floatToIntBits(other.m13()))
- return false;
- if (Float.floatToIntBits(m20()) != Float.floatToIntBits(other.m20()))
- return false;
- if (Float.floatToIntBits(m21()) != Float.floatToIntBits(other.m21()))
- return false;
- if (Float.floatToIntBits(m22()) != Float.floatToIntBits(other.m22()))
- return false;
- if (Float.floatToIntBits(m23()) != Float.floatToIntBits(other.m23()))
- return false;
- if (Float.floatToIntBits(m30()) != Float.floatToIntBits(other.m30()))
- return false;
- if (Float.floatToIntBits(m31()) != Float.floatToIntBits(other.m31()))
- return false;
- if (Float.floatToIntBits(m32()) != Float.floatToIntBits(other.m32()))
- return false;
- if (Float.floatToIntBits(m33()) != Float.floatToIntBits(other.m33()))
- return false;
- return true;
- }
-
- public boolean equals(Matrix4fc m, float delta) {
- if (this == m)
- return true;
- if (m == null)
- return false;
- if (!(m instanceof Matrix4f))
- return false;
- if (!Runtime.equals(m00(), m.m00(), delta))
- return false;
- if (!Runtime.equals(m01(), m.m01(), delta))
- return false;
- if (!Runtime.equals(m02(), m.m02(), delta))
- return false;
- if (!Runtime.equals(m03(), m.m03(), delta))
- return false;
- if (!Runtime.equals(m10(), m.m10(), delta))
- return false;
- if (!Runtime.equals(m11(), m.m11(), delta))
- return false;
- if (!Runtime.equals(m12(), m.m12(), delta))
- return false;
- if (!Runtime.equals(m13(), m.m13(), delta))
- return false;
- if (!Runtime.equals(m20(), m.m20(), delta))
- return false;
- if (!Runtime.equals(m21(), m.m21(), delta))
- return false;
- if (!Runtime.equals(m22(), m.m22(), delta))
- return false;
- if (!Runtime.equals(m23(), m.m23(), delta))
- return false;
- if (!Runtime.equals(m30(), m.m30(), delta))
- return false;
- if (!Runtime.equals(m31(), m.m31(), delta))
- return false;
- if (!Runtime.equals(m32(), m.m32(), delta))
- return false;
- if (!Runtime.equals(m33(), m.m33(), delta))
- return false;
- return true;
- }
-
- public Matrix4f pick(float x, float y, float width, float height, int[] viewport, Matrix4f dest) {
- float sx = viewport[2] / width;
- float sy = viewport[3] / height;
- float tx = (viewport[2] + 2.0f * (viewport[0] - x)) / width;
- float ty = (viewport[3] + 2.0f * (viewport[1] - y)) / height;
- dest._m30(m00() * tx + m10() * ty + m30())
- ._m31(m01() * tx + m11() * ty + m31())
- ._m32(m02() * tx + m12() * ty + m32())
- ._m33(m03() * tx + m13() * ty + m33())
- ._m00(m00() * sx)
- ._m01(m01() * sx)
- ._m02(m02() * sx)
- ._m03(m03() * sx)
- ._m10(m10() * sy)
- ._m11(m11() * sy)
- ._m12(m12() * sy)
- ._m13(m13() * sy)
- ._properties(0);
- return dest;
- }
-
- /**
- * Apply a picking transformation to this matrix using the given window coordinates (x, y)
as the pick center
- * and the given (width, height)
as the size of the picking region in window coordinates.
- *
- * @param x
- * the x coordinate of the picking region center in window coordinates
- * @param y
- * the y coordinate of the picking region center in window coordinates
- * @param width
- * the width of the picking region in window coordinates
- * @param height
- * the height of the picking region in window coordinates
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @return this
- */
- public Matrix4f pick(float x, float y, float width, float height, int[] viewport) {
- return pick(x, y, width, height, viewport, this);
- }
-
- public boolean isAffine() {
- return m03() == 0.0f && m13() == 0.0f && m23() == 0.0f && m33() == 1.0f;
- }
-
- /**
- * Exchange the values of this
matrix with the given other
matrix.
- *
- * @param other
- * the other matrix to exchange the values with
- * @return this
- */
- public Matrix4f swap(Matrix4f other) {
- MemUtil.INSTANCE.swap(this, other);
- int props = properties;
- this.properties = other.properties();
- other.properties = props;
- return this;
- }
-
- public Matrix4f arcball(float radius, float centerX, float centerY, float centerZ, float angleX, float angleY, Matrix4f dest) {
- float m30 = m20() * -radius + this.m30();
- float m31 = m21() * -radius + this.m31();
- float m32 = m22() * -radius + this.m32();
- float m33 = m23() * -radius + this.m33();
- float sin = Math.sin(angleX);
- float cos = Math.cosFromSin(sin, angleX);
- float nm10 = m10() * cos + m20() * sin;
- float nm11 = m11() * cos + m21() * sin;
- float nm12 = m12() * cos + m22() * sin;
- float nm13 = m13() * cos + m23() * sin;
- float m20 = this.m20() * cos - m10() * sin;
- float m21 = this.m21() * cos - m11() * sin;
- float m22 = this.m22() * cos - m12() * sin;
- float m23 = this.m23() * cos - m13() * sin;
- sin = Math.sin(angleY);
- cos = Math.cosFromSin(sin, angleY);
- float nm00 = m00() * cos - m20 * sin;
- float nm01 = m01() * cos - m21 * sin;
- float nm02 = m02() * cos - m22 * sin;
- float nm03 = m03() * cos - m23 * sin;
- float nm20 = m00() * sin + m20 * cos;
- float nm21 = m01() * sin + m21 * cos;
- float nm22 = m02() * sin + m22 * cos;
- float nm23 = m03() * sin + m23 * cos;
- dest._m30(-nm00 * centerX - nm10 * centerY - nm20 * centerZ + m30)
- ._m31(-nm01 * centerX - nm11 * centerY - nm21 * centerZ + m31)
- ._m32(-nm02 * centerX - nm12 * centerY - nm22 * centerZ + m32)
- ._m33(-nm03 * centerX - nm13 * centerY - nm23 * centerZ + m33)
- ._m20(nm20)
- ._m21(nm21)
- ._m22(nm22)
- ._m23(nm23)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- return dest;
- }
-
- public Matrix4f arcball(float radius, Vector3fc center, float angleX, float angleY, Matrix4f dest) {
- return arcball(radius, center.x(), center.y(), center.z(), angleX, angleY, dest);
- }
-
- /**
- * Apply an arcball view transformation to this matrix with the given radius
and center (centerX, centerY, centerZ)
- * position of the arcball and the specified X and Y rotation angles.
- * translate(0, 0, -radius).rotateX(angleX).rotateY(angleY).translate(-centerX, -centerY, -centerZ)
- *
- * @param radius
- * the arcball radius
- * @param centerX
- * the x coordinate of the center position of the arcball
- * @param centerY
- * the y coordinate of the center position of the arcball
- * @param centerZ
- * the z coordinate of the center position of the arcball
- * @param angleX
- * the rotation angle around the X axis in radians
- * @param angleY
- * the rotation angle around the Y axis in radians
- * @return this
- */
- public Matrix4f arcball(float radius, float centerX, float centerY, float centerZ, float angleX, float angleY) {
- return arcball(radius, centerX, centerY, centerZ, angleX, angleY, this);
- }
-
- /**
- * Apply an arcball view transformation to this matrix with the given radius
and center
- * position of the arcball and the specified X and Y rotation angles.
- * translate(0, 0, -radius).rotateX(angleX).rotateY(angleY).translate(-center.x, -center.y, -center.z)
- *
- * @param radius
- * the arcball radius
- * @param center
- * the center position of the arcball
- * @param angleX
- * the rotation angle around the X axis in radians
- * @param angleY
- * the rotation angle around the Y axis in radians
- * @return this
- */
- public Matrix4f arcball(float radius, Vector3fc center, float angleX, float angleY) {
- return arcball(radius, center.x(), center.y(), center.z(), angleX, angleY, this);
- }
-
- /**
- * Compute the axis-aligned bounding box of the frustum described by this
matrix and store the minimum corner
- * coordinates in the given min
and the maximum corner coordinates in the given max
vector.
- * this
is assumed to be the {@link #invert() inverse} of the origial view-projection matrix
- * for which to compute the axis-aligned bounding box in world-space.
- * (-1, -1, -1)
, (1, 1, 1)
.
- *
- * @param min
- * will hold the minimum corner coordinates of the axis-aligned bounding box
- * @param max
- * will hold the maximum corner coordinates of the axis-aligned bounding box
- * @return this
- */
- public Matrix4f frustumAabb(Vector3f min, Vector3f max) {
- float minX = Float.POSITIVE_INFINITY;
- float minY = Float.POSITIVE_INFINITY;
- float minZ = Float.POSITIVE_INFINITY;
- float maxX = Float.NEGATIVE_INFINITY;
- float maxY = Float.NEGATIVE_INFINITY;
- float maxZ = Float.NEGATIVE_INFINITY;
- for (int t = 0; t < 8; t++) {
- float x = ((t & 1) << 1) - 1.0f;
- float y = (((t >>> 1) & 1) << 1) - 1.0f;
- float z = (((t >>> 2) & 1) << 1) - 1.0f;
- float invW = 1.0f / (m03() * x + m13() * y + m23() * z + m33());
- float nx = (m00() * x + m10() * y + m20() * z + m30()) * invW;
- float ny = (m01() * x + m11() * y + m21() * z + m31()) * invW;
- float nz = (m02() * x + m12() * y + m22() * z + m32()) * invW;
- minX = minX < nx ? minX : nx;
- minY = minY < ny ? minY : ny;
- minZ = minZ < nz ? minZ : nz;
- maxX = maxX > nx ? maxX : nx;
- maxY = maxY > ny ? maxY : ny;
- maxZ = maxZ > nz ? maxZ : nz;
- }
- min.x = minX;
- min.y = minY;
- min.z = minZ;
- max.x = maxX;
- max.y = maxY;
- max.z = maxZ;
- return this;
- }
-
- public Matrix4f projectedGridRange(Matrix4fc projector, float sLower, float sUpper, Matrix4f dest) {
- // Compute intersection with frustum edges and plane
- float minX = Float.POSITIVE_INFINITY, minY = Float.POSITIVE_INFINITY;
- float maxX = Float.NEGATIVE_INFINITY, maxY = Float.NEGATIVE_INFINITY;
- boolean intersection = false;
- for (int t = 0; t < 3 * 4; t++) {
- float c0X, c0Y, c0Z;
- float c1X, c1Y, c1Z;
- if (t < 4) {
- // all x edges
- c0X = -1; c1X = +1;
- c0Y = c1Y = ((t & 1) << 1) - 1.0f;
- c0Z = c1Z = (((t >>> 1) & 1) << 1) - 1.0f;
- } else if (t < 8) {
- // all y edges
- c0Y = -1; c1Y = +1;
- c0X = c1X = ((t & 1) << 1) - 1.0f;
- c0Z = c1Z = (((t >>> 1) & 1) << 1) - 1.0f;
- } else {
- // all z edges
- c0Z = -1; c1Z = +1;
- c0X = c1X = ((t & 1) << 1) - 1.0f;
- c0Y = c1Y = (((t >>> 1) & 1) << 1) - 1.0f;
- }
- // unproject corners
- float invW = 1.0f / (m03() * c0X + m13() * c0Y + m23() * c0Z + m33());
- float p0x = (m00() * c0X + m10() * c0Y + m20() * c0Z + m30()) * invW;
- float p0y = (m01() * c0X + m11() * c0Y + m21() * c0Z + m31()) * invW;
- float p0z = (m02() * c0X + m12() * c0Y + m22() * c0Z + m32()) * invW;
- invW = 1.0f / (m03() * c1X + m13() * c1Y + m23() * c1Z + m33());
- float p1x = (m00() * c1X + m10() * c1Y + m20() * c1Z + m30()) * invW;
- float p1y = (m01() * c1X + m11() * c1Y + m21() * c1Z + m31()) * invW;
- float p1z = (m02() * c1X + m12() * c1Y + m22() * c1Z + m32()) * invW;
- float dirX = p1x - p0x;
- float dirY = p1y - p0y;
- float dirZ = p1z - p0z;
- float invDenom = 1.0f / dirY;
- // test for intersection
- for (int s = 0; s < 2; s++) {
- float isectT = -(p0y + (s == 0 ? sLower : sUpper)) * invDenom;
- if (isectT >= 0.0f && isectT <= 1.0f) {
- intersection = true;
- // project with projector matrix
- float ix = p0x + isectT * dirX;
- float iz = p0z + isectT * dirZ;
- invW = 1.0f / (projector.m03() * ix + projector.m23() * iz + projector.m33());
- float px = (projector.m00() * ix + projector.m20() * iz + projector.m30()) * invW;
- float py = (projector.m01() * ix + projector.m21() * iz + projector.m31()) * invW;
- minX = minX < px ? minX : px;
- minY = minY < py ? minY : py;
- maxX = maxX > px ? maxX : px;
- maxY = maxY > py ? maxY : py;
- }
- }
- }
- if (!intersection)
- return null; // <- projected grid is not visible
- dest.set(maxX - minX, 0, 0, 0, 0, maxY - minY, 0, 0, 0, 0, 1, 0, minX, minY, 0, 1);
- dest._properties(PROPERTY_AFFINE);
- return dest;
- }
-
- /**
- * Change the near and far clip plane distances of this
perspective frustum transformation matrix
- * and store the result in dest
.
- * this
is a perspective projection frustum transformation, for example obtained
- * via {@link #perspective(float, float, float, float) perspective()} or {@link #frustum(float, float, float, float, float, float) frustum()}.
- *
- * @see #perspective(float, float, float, float)
- * @see #frustum(float, float, float, float, float, float)
- *
- * @param near
- * the new near clip plane distance
- * @param far
- * the new far clip plane distance
- * @param dest
- * will hold the resulting matrix
- * @return dest
- */
- public Matrix4f perspectiveFrustumSlice(float near, float far, Matrix4f dest) {
- float invOldNear = (m23() + m22()) / m32();
- float invNearFar = 1.0f / (near - far);
- dest._m00(m00() * invOldNear * near)
- ._m01(m01())
- ._m02(m02())
- ._m03(m03())
- ._m10(m10())
- ._m11(m11() * invOldNear * near)
- ._m12(m12())
- ._m13(m13())
- ._m20(m20())
- ._m21(m21())
- ._m22((far + near) * invNearFar)
- ._m23(m23())
- ._m30(m30())
- ._m31(m31())
- ._m32((far + far) * near * invNearFar)
- ._m33(m33())
- ._properties(properties & ~(PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_ORTHONORMAL));
- return dest;
- }
-
- /**
- * Build an ortographic projection transformation that fits the view-projection transformation represented by this
- * into the given affine view
transformation.
- * this
must be given as the {@link #invert() inverse} of a typical combined camera view-projection
- * transformation, whose projection can be either orthographic or perspective.
- * view
must be an {@link #isAffine() affine} transformation which in the application of Cascaded Shadow Maps is usually the light view transformation.
- * It be obtained via any affine transformation or for example via {@link #lookAt(float, float, float, float, float, float, float, float, float) lookAt()}.
- * this
- * @param dest
- * will hold the crop projection transformation
- * @return dest
- */
- public Matrix4f orthoCrop(Matrix4fc view, Matrix4f dest) {
- // determine min/max world z and min/max orthographically view-projected x/y
- float minX = Float.POSITIVE_INFINITY, maxX = Float.NEGATIVE_INFINITY;
- float minY = Float.POSITIVE_INFINITY, maxY = Float.NEGATIVE_INFINITY;
- float minZ = Float.POSITIVE_INFINITY, maxZ = Float.NEGATIVE_INFINITY;
- for (int t = 0; t < 8; t++) {
- float x = ((t & 1) << 1) - 1.0f;
- float y = (((t >>> 1) & 1) << 1) - 1.0f;
- float z = (((t >>> 2) & 1) << 1) - 1.0f;
- float invW = 1.0f / (m03() * x + m13() * y + m23() * z + m33());
- float wx = (m00() * x + m10() * y + m20() * z + m30()) * invW;
- float wy = (m01() * x + m11() * y + m21() * z + m31()) * invW;
- float wz = (m02() * x + m12() * y + m22() * z + m32()) * invW;
- invW = 1.0f / (view.m03() * wx + view.m13() * wy + view.m23() * wz + view.m33());
- float vx = view.m00() * wx + view.m10() * wy + view.m20() * wz + view.m30();
- float vy = view.m01() * wx + view.m11() * wy + view.m21() * wz + view.m31();
- float vz = (view.m02() * wx + view.m12() * wy + view.m22() * wz + view.m32()) * invW;
- minX = minX < vx ? minX : vx;
- maxX = maxX > vx ? maxX : vx;
- minY = minY < vy ? minY : vy;
- maxY = maxY > vy ? maxY : vy;
- minZ = minZ < vz ? minZ : vz;
- maxZ = maxZ > vz ? maxZ : vz;
- }
- // build crop projection matrix to fit 'this' frustum into view
- return dest.setOrtho(minX, maxX, minY, maxY, -maxZ, -minZ);
- }
-
- /**
- * Set this
matrix to a perspective transformation that maps the trapezoid spanned by the four corner coordinates
- * (p0x, p0y)
, (p1x, p1y)
, (p2x, p2y)
and (p3x, p3y)
to the unit square [(-1, -1)..(+1, +1)]
.
- * this
and other
using the given interpolation factor t
- * and store the result in this
.
- * t
is 0.0
then the result is this
. If the interpolation factor is 1.0
- * then the result is other
.
- *
- * @param other
- * the other matrix
- * @param t
- * the interpolation factor between 0.0 and 1.0
- * @return this
- */
- public Matrix4f lerp(Matrix4fc other, float t) {
- return lerp(other, t, this);
- }
-
- public Matrix4f lerp(Matrix4fc other, float t, Matrix4f dest) {
- dest._m00(Math.fma(other.m00() - m00(), t, m00()))
- ._m01(Math.fma(other.m01() - m01(), t, m01()))
- ._m02(Math.fma(other.m02() - m02(), t, m02()))
- ._m03(Math.fma(other.m03() - m03(), t, m03()))
- ._m10(Math.fma(other.m10() - m10(), t, m10()))
- ._m11(Math.fma(other.m11() - m11(), t, m11()))
- ._m12(Math.fma(other.m12() - m12(), t, m12()))
- ._m13(Math.fma(other.m13() - m13(), t, m13()))
- ._m20(Math.fma(other.m20() - m20(), t, m20()))
- ._m21(Math.fma(other.m21() - m21(), t, m21()))
- ._m22(Math.fma(other.m22() - m22(), t, m22()))
- ._m23(Math.fma(other.m23() - m23(), t, m23()))
- ._m30(Math.fma(other.m30() - m30(), t, m30()))
- ._m31(Math.fma(other.m31() - m31(), t, m31()))
- ._m32(Math.fma(other.m32() - m32(), t, m32()))
- ._m33(Math.fma(other.m33() - m33(), t, m33()))
- ._properties(properties & other.properties());
- return dest;
- }
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mulAffine(new Matrix4f().lookAt(new Vector3f(), new Vector3f(dir).negate(), up).invertAffine(), dest)
- *
- * @see #rotateTowards(float, float, float, float, float, float, Matrix4f)
- * @see #rotationTowards(Vector3fc, Vector3fc)
- *
- * @param dir
- * the direction to rotate towards
- * @param up
- * the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateTowards(Vector3fc dir, Vector3fc up, Matrix4f dest) {
- return rotateTowards(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z(), dest);
- }
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with dir
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mulAffine(new Matrix4f().lookAt(new Vector3f(), new Vector3f(dir).negate(), up).invertAffine())
- *
- * @see #rotateTowards(float, float, float, float, float, float)
- * @see #rotationTowards(Vector3fc, Vector3fc)
- *
- * @param dir
- * the direction to orient towards
- * @param up
- * the up vector
- * @return this
- */
- public Matrix4f rotateTowards(Vector3fc dir, Vector3fc up) {
- return rotateTowards(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z(), this);
- }
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with (dirX, dirY, dirZ)
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mulAffine(new Matrix4f().lookAt(0, 0, 0, -dirX, -dirY, -dirZ, upX, upY, upZ).invertAffine())
- *
- * @see #rotateTowards(Vector3fc, Vector3fc)
- * @see #rotationTowards(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to rotate towards
- * @param dirY
- * the y-coordinate of the direction to rotate towards
- * @param dirZ
- * the z-coordinate of the direction to rotate towards
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix4f rotateTowards(float dirX, float dirY, float dirZ, float upX, float upY, float upZ) {
- return rotateTowards(dirX, dirY, dirZ, upX, upY, upZ, this);
- }
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with (dirX, dirY, dirZ)
- * and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mulAffine(new Matrix4f().lookAt(0, 0, 0, -dirX, -dirY, -dirZ, upX, upY, upZ).invertAffine(), dest)
- *
- * @see #rotateTowards(Vector3fc, Vector3fc)
- * @see #rotationTowards(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to rotate towards
- * @param dirY
- * the y-coordinate of the direction to rotate towards
- * @param dirZ
- * the z-coordinate of the direction to rotate towards
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f rotateTowards(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix4f dest) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- float ndirX = dirX * invDirLength;
- float ndirY = dirY * invDirLength;
- float ndirZ = dirZ * invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * ndirZ - upZ * ndirY;
- leftY = upZ * ndirX - upX * ndirZ;
- leftZ = upX * ndirY - upY * ndirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = ndirY * leftZ - ndirZ * leftY;
- float upnY = ndirZ * leftX - ndirX * leftZ;
- float upnZ = ndirX * leftY - ndirY * leftX;
- float rm00 = leftX;
- float rm01 = leftY;
- float rm02 = leftZ;
- float rm10 = upnX;
- float rm11 = upnY;
- float rm12 = upnZ;
- float rm20 = ndirX;
- float rm21 = ndirY;
- float rm22 = ndirZ;
- dest._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33());
- float nm00 = m00() * rm00 + m10() * rm01 + m20() * rm02;
- float nm01 = m01() * rm00 + m11() * rm01 + m21() * rm02;
- float nm02 = m02() * rm00 + m12() * rm01 + m22() * rm02;
- float nm03 = m03() * rm00 + m13() * rm01 + m23() * rm02;
- float nm10 = m00() * rm10 + m10() * rm11 + m20() * rm12;
- float nm11 = m01() * rm10 + m11() * rm11 + m21() * rm12;
- float nm12 = m02() * rm10 + m12() * rm11 + m22() * rm12;
- float nm13 = m03() * rm10 + m13() * rm11 + m23() * rm12;
- dest._m20(m00() * rm20 + m10() * rm21 + m20() * rm22)
- ._m21(m01() * rm20 + m11() * rm21 + m21() * rm22)
- ._m22(m02() * rm20 + m12() * rm21 + m22() * rm22)
- ._m23(m03() * rm20 + m13() * rm21 + m23() * rm22)
- ._m00(nm00)
- ._m01(nm01)
- ._m02(nm02)
- ._m03(nm03)
- ._m10(nm10)
- ._m11(nm11)
- ._m12(nm12)
- ._m13(nm13)
- ._properties(properties & ~(PROPERTY_PERSPECTIVE | PROPERTY_IDENTITY | PROPERTY_TRANSLATION));
- return dest;
- }
-
- /**
- * Set this matrix to a model transformation for a right-handed coordinate system,
- * that aligns the local -z
axis with dir
.
- * setLookAt(new Vector3f(), new Vector3f(dir).negate(), up).invertAffine()
- *
- * @see #rotationTowards(Vector3fc, Vector3fc)
- * @see #rotateTowards(float, float, float, float, float, float)
- *
- * @param dir
- * the direction to orient the local -z axis towards
- * @param up
- * the up vector
- * @return this
- */
- public Matrix4f rotationTowards(Vector3fc dir, Vector3fc up) {
- return rotationTowards(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z());
- }
-
- /**
- * Set this matrix to a model transformation for a right-handed coordinate system,
- * that aligns the local -z
axis with (dirX, dirY, dirZ)
.
- * setLookAt(0, 0, 0, -dirX, -dirY, -dirZ, upX, upY, upZ).invertAffine()
- *
- * @see #rotateTowards(Vector3fc, Vector3fc)
- * @see #rotationTowards(float, float, float, float, float, float)
- *
- * @param dirX
- * the x-coordinate of the direction to rotate towards
- * @param dirY
- * the y-coordinate of the direction to rotate towards
- * @param dirZ
- * the z-coordinate of the direction to rotate towards
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix4f rotationTowards(float dirX, float dirY, float dirZ, float upX, float upY, float upZ) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- float ndirX = dirX * invDirLength;
- float ndirY = dirY * invDirLength;
- float ndirZ = dirZ * invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * ndirZ - upZ * ndirY;
- leftY = upZ * ndirX - upX * ndirZ;
- leftZ = upX * ndirY - upY * ndirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = ndirY * leftZ - ndirZ * leftY;
- float upnY = ndirZ * leftX - ndirX * leftZ;
- float upnZ = ndirX * leftY - ndirY * leftX;
- if ((properties & PROPERTY_IDENTITY) == 0)
- MemUtil.INSTANCE.identity(this);
- this._m00(leftX)
- ._m01(leftY)
- ._m02(leftZ)
- ._m10(upnX)
- ._m11(upnY)
- ._m12(upnZ)
- ._m20(ndirX)
- ._m21(ndirY)
- ._m22(ndirZ)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- /**
- * Set this matrix to a model transformation for a right-handed coordinate system,
- * that translates to the given pos
and aligns the local -z
- * axis with dir
.
- * translation(pos).rotateTowards(dir, up)
- *
- * @see #translation(Vector3fc)
- * @see #rotateTowards(Vector3fc, Vector3fc)
- *
- * @param pos
- * the position to translate to
- * @param dir
- * the direction to rotate towards
- * @param up
- * the up vector
- * @return this
- */
- public Matrix4f translationRotateTowards(Vector3fc pos, Vector3fc dir, Vector3fc up) {
- return translationRotateTowards(pos.x(), pos.y(), pos.z(), dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z());
- }
-
- /**
- * Set this matrix to a model transformation for a right-handed coordinate system,
- * that translates to the given (posX, posY, posZ)
and aligns the local -z
- * axis with (dirX, dirY, dirZ)
.
- * translation(posX, posY, posZ).rotateTowards(dirX, dirY, dirZ, upX, upY, upZ)
- *
- * @see #translation(float, float, float)
- * @see #rotateTowards(float, float, float, float, float, float)
- *
- * @param posX
- * the x-coordinate of the position to translate to
- * @param posY
- * the y-coordinate of the position to translate to
- * @param posZ
- * the z-coordinate of the position to translate to
- * @param dirX
- * the x-coordinate of the direction to rotate towards
- * @param dirY
- * the y-coordinate of the direction to rotate towards
- * @param dirZ
- * the z-coordinate of the direction to rotate towards
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @return this
- */
- public Matrix4f translationRotateTowards(float posX, float posY, float posZ, float dirX, float dirY, float dirZ, float upX, float upY, float upZ) {
- // Normalize direction
- float invDirLength = Math.invsqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
- float ndirX = dirX * invDirLength;
- float ndirY = dirY * invDirLength;
- float ndirZ = dirZ * invDirLength;
- // left = up x direction
- float leftX, leftY, leftZ;
- leftX = upY * ndirZ - upZ * ndirY;
- leftY = upZ * ndirX - upX * ndirZ;
- leftZ = upX * ndirY - upY * ndirX;
- // normalize left
- float invLeftLength = Math.invsqrt(leftX * leftX + leftY * leftY + leftZ * leftZ);
- leftX *= invLeftLength;
- leftY *= invLeftLength;
- leftZ *= invLeftLength;
- // up = direction x left
- float upnX = ndirY * leftZ - ndirZ * leftY;
- float upnY = ndirZ * leftX - ndirX * leftZ;
- float upnZ = ndirX * leftY - ndirY * leftX;
- this._m00(leftX)
- ._m01(leftY)
- ._m02(leftZ)
- ._m03(0.0f)
- ._m10(upnX)
- ._m11(upnY)
- ._m12(upnZ)
- ._m13(0.0f)
- ._m20(ndirX)
- ._m21(ndirY)
- ._m22(ndirZ)
- ._m23(0.0f)
- ._m30(posX)
- ._m31(posY)
- ._m32(posZ)
- ._m33(1.0f)
- ._properties(PROPERTY_AFFINE | PROPERTY_ORTHONORMAL);
- return this;
- }
-
- public Vector3f getEulerAnglesZYX(Vector3f dest) {
- dest.x = Math.atan2(m12(), m22());
- dest.y = Math.atan2(-m02(), Math.sqrt(1.0f - m02() * m02()));
- dest.z = Math.atan2(m01(), m00());
- return dest;
- }
-
- public Vector3f getEulerAnglesXYZ(Vector3f dest) {
- dest.x = Math.atan2(-m21(), m22());
- dest.y = Math.atan2(m20(), Math.sqrt(1.0f - m20() * m20()));
- dest.z = Math.atan2(-m10(), m00());
- return dest;
- }
-
- /**
- * Compute the extents of the coordinate system before this {@link #isAffine() affine} transformation was applied
- * and store the resulting corner coordinates in corner
and the span vectors in
- * xDir
, yDir
and zDir
.
- * [-1..+1]
in all dimensions,
- * this method returns one corner and the length and direction of the three base axis vectors in the coordinate
- * system before this transformation is applied, which transforms into the corner coordinates [-1, +1]
.
- * a
and
- * b
.
- * M
is this
matrix and O
the oblique transformation matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * oblique transformation will be applied first!
- *
- * x' = x + a*z
- * y' = y + a*z
- * z' = z
- *
- * or in matrix form:
- *
- * 1 0 a 0
- * 0 1 b 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @param a
- * the value for the z factor that applies to x
- * @param b
- * the value for the z factor that applies to y
- * @return this
- */
- public Matrix4f obliqueZ(float a, float b) {
- return this
- ._m20(m00() * a + m10() * b + m20())
- ._m21(m01() * a + m11() * b + m21())
- ._m22(m02() * a + m12() * b + m22())
- ._properties(this.properties & PROPERTY_AFFINE);
- }
-
- /**
- * Apply an oblique projection transformation to this matrix with the given values for a
and
- * b
and store the result in dest
.
- * M
is this
matrix and O
the oblique transformation matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * oblique transformation will be applied first!
- *
- * x' = x + a*z
- * y' = y + a*z
- * z' = z
- *
- * or in matrix form:
- *
- * 1 0 a 0
- * 0 1 b 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @param a
- * the value for the z factor that applies to x
- * @param b
- * the value for the z factor that applies to y
- * @param dest
- * will hold the result
- * @return dest
- */
- public Matrix4f obliqueZ(float a, float b, Matrix4f dest) {
- dest._m00(m00())
- ._m01(m01())
- ._m02(m02())
- ._m03(m03())
- ._m10(m10())
- ._m11(m11())
- ._m12(m12())
- ._m13(m13())
- ._m20(m00() * a + m10() * b + m20())
- ._m21(m01() * a + m11() * b + m21())
- ._m22(m02() * a + m12() * b + m22())
- ._m23(m23())
- ._m30(m30())
- ._m31(m31())
- ._m32(m32())
- ._m33(m33())
- ._properties(this.properties & PROPERTY_AFFINE);
- return dest;
- }
-
- /**
- * Create a view and projection matrix from a given eye
position, a given bottom left corner position p
of the near plane rectangle
- * and the extents of the near plane rectangle along its local x
and y
axes, and store the resulting matrices
- * in projDest
and viewDest
.
- * eye
- * projecting the scene onto the near plane defined by the rectangle.
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param projDest
- * will hold the resulting projection matrix
- * @param viewDest
- * will hold the resulting view matrix
- */
- public static void projViewFromRectangle(
- Vector3f eye, Vector3f p, Vector3f x, Vector3f y, float nearFarDist, boolean zeroToOne,
- Matrix4f projDest, Matrix4f viewDest) {
- float zx = y.y * x.z - y.z * x.y, zy = y.z * x.x - y.x * x.z, zz = y.x * x.y - y.y * x.x;
- float zd = zx * (p.x - eye.x) + zy * (p.y - eye.y) + zz * (p.z - eye.z);
- float zs = zd >= 0 ? 1 : -1; zx *= zs; zy *= zs; zz *= zs; zd *= zs;
- viewDest.setLookAt(eye.x, eye.y, eye.z, eye.x + zx, eye.y + zy, eye.z + zz, y.x, y.y, y.z);
- float px = viewDest.m00() * p.x + viewDest.m10() * p.y + viewDest.m20() * p.z + viewDest.m30();
- float py = viewDest.m01() * p.x + viewDest.m11() * p.y + viewDest.m21() * p.z + viewDest.m31();
- float tx = viewDest.m00() * x.x + viewDest.m10() * x.y + viewDest.m20() * x.z;
- float ty = viewDest.m01() * y.x + viewDest.m11() * y.y + viewDest.m21() * y.z;
- float len = Math.sqrt(zx * zx + zy * zy + zz * zz);
- float near = zd / len, far;
- if (Float.isInfinite(nearFarDist) && nearFarDist < 0.0f) {
- far = near;
- near = Float.POSITIVE_INFINITY;
- } else if (Float.isInfinite(nearFarDist) && nearFarDist > 0.0f) {
- far = Float.POSITIVE_INFINITY;
- } else if (nearFarDist < 0.0f) {
- far = near;
- near = near + nearFarDist;
- } else {
- far = near + nearFarDist;
- }
- projDest.setFrustum(px, px + tx, py, py + ty, near, far, zeroToOne);
- }
-
- /**
- * Apply a transformation to this matrix to ensure that the local Y axis (as obtained by {@link #positiveY(Vector3f)})
- * will be coplanar to the plane spanned by the local Z axis (as obtained by {@link #positiveZ(Vector3f)}) and the
- * given vector up
.
- * up
.
- * (upX, upY, upZ)
.
- * (upX, upY, upZ)
.
- * this
by the matrix
- *
- * 1 0 0 0
- * 0 0 1 0
- * 0 1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapXZY() {
- return mapXZY(this);
- }
- public Matrix4f mapXZY(Matrix4f dest) {
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(m00())._m01(m01())._m02(m02())._m03(m03())._m10(m20())._m11(m21())._m12(m22())._m13(m13())._m20(m10)._m21(m11)._m22(m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 0 -1 0
- * 0 1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapXZnY() {
- return mapXZnY(this);
- }
- public Matrix4f mapXZnY(Matrix4f dest) {
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(m00())._m01(m01())._m02(m02())._m03(m03())._m10(m20())._m11(m21())._m12(m22())._m13(m13())._m20(-m10)._m21(-m11)._m22(-m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 -1 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapXnYnZ() {
- return mapXnYnZ(this);
- }
- public Matrix4f mapXnYnZ(Matrix4f dest) {
- return dest._m00(m00())._m01(m01())._m02(m02())._m03(m03())._m10(-m10())._m11(-m11())._m12(-m12())._m13(m13())._m20(-m20())._m21(-m21())._m22(-m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 0 1 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapXnZY() {
- return mapXnZY(this);
- }
- public Matrix4f mapXnZY(Matrix4f dest) {
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(m00())._m01(m01())._m02(m02())._m03(m03())._m10(-m20())._m11(-m21())._m12(-m22())._m13(m13())._m20(m10)._m21(m11)._m22(m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 0 -1 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapXnZnY() {
- return mapXnZnY(this);
- }
- public Matrix4f mapXnZnY(Matrix4f dest) {
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(m00())._m01(m01())._m02(m02())._m03(m03())._m10(-m20())._m11(-m21())._m12(-m22())._m13(m13())._m20(-m10)._m21(-m11)._m22(-m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 1 0 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapYXZ() {
- return mapYXZ(this);
- }
- public Matrix4f mapYXZ(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m10())._m01(m11())._m02(m12())._m03(m03())._m10(m00)._m11(m01)._m12(m02)._m13(m13())._m20(m20())._m21(m21())._m22(m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 1 0 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapYXnZ() {
- return mapYXnZ(this);
- }
- public Matrix4f mapYXnZ(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m10())._m01(m11())._m02(m12())._m03(m03())._m10(m00)._m11(m01)._m12(m02)._m13(m13())._m20(-m20())._m21(-m21())._m22(-m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 1 0 0 0
- * 0 1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapYZX() {
- return mapYZX(this);
- }
- public Matrix4f mapYZX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m10())._m01(m11())._m02(m12())._m03(m03())._m10(m20())._m11(m21())._m12(m22())._m13(m13())._m20(m00)._m21(m01)._m22(m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 1 0 0 0
- * 0 1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapYZnX() {
- return mapYZnX(this);
- }
- public Matrix4f mapYZnX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m10())._m01(m11())._m02(m12())._m03(m03())._m10(m20())._m11(m21())._m12(m22())._m13(m13())._m20(-m00)._m21(-m01)._m22(-m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 1 0 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapYnXZ() {
- return mapYnXZ(this);
- }
- public Matrix4f mapYnXZ(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m10())._m01(m11())._m02(m12())._m03(m03())._m10(-m00)._m11(-m01)._m12(-m02)._m13(m13())._m20(m20())._m21(m21())._m22(m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 1 0 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapYnXnZ() {
- return mapYnXnZ(this);
- }
- public Matrix4f mapYnXnZ(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m10())._m01(m11())._m02(m12())._m03(m03())._m10(-m00)._m11(-m01)._m12(-m02)._m13(m13())._m20(-m20())._m21(-m21())._m22(-m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 1 0 0 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapYnZX() {
- return mapYnZX(this);
- }
- public Matrix4f mapYnZX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m10())._m01(m11())._m02(m12())._m03(m03())._m10(-m20())._m11(-m21())._m12(-m22())._m13(m13())._m20(m00)._m21(m01)._m22(m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 1 0 0 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapYnZnX() {
- return mapYnZnX(this);
- }
- public Matrix4f mapYnZnX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m10())._m01(m11())._m02(m12())._m03(m03())._m10(-m20())._m11(-m21())._m12(-m22())._m13(m13())._m20(-m00)._m21(-m01)._m22(-m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 0 0 1 0
- * 1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapZXY() {
- return mapZXY(this);
- }
- public Matrix4f mapZXY(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(m20())._m01(m21())._m02(m22())._m03(m03())._m10(m00)._m11(m01)._m12(m02)._m13(m13())._m20(m10)._m21(m11)._m22(m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 0 0 -1 0
- * 1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapZXnY() {
- return mapZXnY(this);
- }
- public Matrix4f mapZXnY(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(m20())._m01(m21())._m02(m22())._m03(m03())._m10(m00)._m11(m01)._m12(m02)._m13(m13())._m20(-m10)._m21(-m11)._m22(-m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 0 1 0 0
- * 1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapZYX() {
- return mapZYX(this);
- }
- public Matrix4f mapZYX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m20())._m01(m21())._m02(m22())._m03(m03())._m10(m10())._m11(m11())._m12(m12())._m13(m13())._m20(m00)._m21(m01)._m22(m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 0 1 0 0
- * 1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapZYnX() {
- return mapZYnX(this);
- }
- public Matrix4f mapZYnX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m20())._m01(m21())._m02(m22())._m03(m03())._m10(m10())._m11(m11())._m12(m12())._m13(m13())._m20(-m00)._m21(-m01)._m22(-m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 0 0 1 0
- * 1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapZnXY() {
- return mapZnXY(this);
- }
- public Matrix4f mapZnXY(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(m20())._m01(m21())._m02(m22())._m03(m03())._m10(-m00)._m11(-m01)._m12(-m02)._m13(m13())._m20(m10)._m21(m11)._m22(m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 0 0 -1 0
- * 1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapZnXnY() {
- return mapZnXnY(this);
- }
- public Matrix4f mapZnXnY(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(m20())._m01(m21())._m02(m22())._m03(m03())._m10(-m00)._m11(-m01)._m12(-m02)._m13(m13())._m20(-m10)._m21(-m11)._m22(-m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 0 -1 0 0
- * 1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapZnYX() {
- return mapZnYX(this);
- }
- public Matrix4f mapZnYX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m20())._m01(m21())._m02(m22())._m03(m03())._m10(-m10())._m11(-m11())._m12(-m12())._m13(m13())._m20(m00)._m21(m01)._m22(m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 0 -1 0 0
- * 1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapZnYnX() {
- return mapZnYnX(this);
- }
- public Matrix4f mapZnYnX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(m20())._m01(m21())._m02(m22())._m03(m03())._m10(-m10())._m11(-m11())._m12(-m12())._m13(m13())._m20(-m00)._m21(-m01)._m22(-m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 1 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnXYnZ() {
- return mapnXYnZ(this);
- }
- public Matrix4f mapnXYnZ(Matrix4f dest) {
- return dest._m00(-m00())._m01(-m01())._m02(-m02())._m03(m03())._m10(m10())._m11(m11())._m12(m12())._m13(m13())._m20(-m20())._m21(-m21())._m22(-m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 0 1 0
- * 0 1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnXZY() {
- return mapnXZY(this);
- }
- public Matrix4f mapnXZY(Matrix4f dest) {
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(-m00())._m01(-m01())._m02(-m02())._m03(m03())._m10(m20())._m11(m21())._m12(m22())._m13(m13())._m20(m10)._m21(m11)._m22(m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 0 -1 0
- * 0 1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnXZnY() {
- return mapnXZnY(this);
- }
- public Matrix4f mapnXZnY(Matrix4f dest) {
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(-m00())._m01(-m01())._m02(-m02())._m03(m03())._m10(m20())._m11(m21())._m12(m22())._m13(m13())._m20(-m10)._m21(-m11)._m22(-m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 -1 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnXnYZ() {
- return mapnXnYZ(this);
- }
- public Matrix4f mapnXnYZ(Matrix4f dest) {
- return dest._m00(-m00())._m01(-m01())._m02(-m02())._m03(m03())._m10(-m10())._m11(-m11())._m12(-m12())._m13(m13())._m20(m20())._m21(m21())._m22(m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 -1 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnXnYnZ() {
- return mapnXnYnZ(this);
- }
- public Matrix4f mapnXnYnZ(Matrix4f dest) {
- return dest._m00(-m00())._m01(-m01())._m02(-m02())._m03(m03())._m10(-m10())._m11(-m11())._m12(-m12())._m13(m13())._m20(-m20())._m21(-m21())._m22(-m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 0 1 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnXnZY() {
- return mapnXnZY(this);
- }
- public Matrix4f mapnXnZY(Matrix4f dest) {
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(-m00())._m01(-m01())._m02(-m02())._m03(m03())._m10(-m20())._m11(-m21())._m12(-m22())._m13(m13())._m20(m10)._m21(m11)._m22(m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 0 -1 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnXnZnY() {
- return mapnXnZnY(this);
- }
- public Matrix4f mapnXnZnY(Matrix4f dest) {
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(-m00())._m01(-m01())._m02(-m02())._m03(m03())._m10(-m20())._m11(-m21())._m12(-m22())._m13(m13())._m20(-m10)._m21(-m11)._m22(-m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * -1 0 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnYXZ() {
- return mapnYXZ(this);
- }
- public Matrix4f mapnYXZ(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m10())._m01(-m11())._m02(-m12())._m03(m03())._m10(m00)._m11(m01)._m12(m02)._m13(m13())._m20(m20())._m21(m21())._m22(m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * -1 0 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnYXnZ() {
- return mapnYXnZ(this);
- }
- public Matrix4f mapnYXnZ(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m10())._m01(-m11())._m02(-m12())._m03(m03())._m10(m00)._m11(m01)._m12(m02)._m13(m13())._m20(-m20())._m21(-m21())._m22(-m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * -1 0 0 0
- * 0 1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnYZX() {
- return mapnYZX(this);
- }
- public Matrix4f mapnYZX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m10())._m01(-m11())._m02(-m12())._m03(m03())._m10(m20())._m11(m21())._m12(m22())._m13(m13())._m20(m00)._m21(m01)._m22(m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * -1 0 0 0
- * 0 1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnYZnX() {
- return mapnYZnX(this);
- }
- public Matrix4f mapnYZnX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m10())._m01(-m11())._m02(-m12())._m03(m03())._m10(m20())._m11(m21())._m12(m22())._m13(m13())._m20(-m00)._m21(-m01)._m22(-m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * -1 0 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnYnXZ() {
- return mapnYnXZ(this);
- }
- public Matrix4f mapnYnXZ(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m10())._m01(-m11())._m02(-m12())._m03(m03())._m10(-m00)._m11(-m01)._m12(-m02)._m13(m13())._m20(m20())._m21(m21())._m22(m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * -1 0 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnYnXnZ() {
- return mapnYnXnZ(this);
- }
- public Matrix4f mapnYnXnZ(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m10())._m01(-m11())._m02(-m12())._m03(m03())._m10(-m00)._m11(-m01)._m12(-m02)._m13(m13())._m20(-m20())._m21(-m21())._m22(-m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * -1 0 0 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnYnZX() {
- return mapnYnZX(this);
- }
- public Matrix4f mapnYnZX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m10())._m01(-m11())._m02(-m12())._m03(m03())._m10(-m20())._m11(-m21())._m12(-m22())._m13(m13())._m20(m00)._m21(m01)._m22(m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * -1 0 0 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnYnZnX() {
- return mapnYnZnX(this);
- }
- public Matrix4f mapnYnZnX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m10())._m01(-m11())._m02(-m12())._m03(m03())._m10(-m20())._m11(-m21())._m12(-m22())._m13(m13())._m20(-m00)._m21(-m01)._m22(-m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 0 0 1 0
- * -1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnZXY() {
- return mapnZXY(this);
- }
- public Matrix4f mapnZXY(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(-m20())._m01(-m21())._m02(-m22())._m03(m03())._m10(m00)._m11(m01)._m12(m02)._m13(m13())._m20(m10)._m21(m11)._m22(m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 0 0 -1 0
- * -1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnZXnY() {
- return mapnZXnY(this);
- }
- public Matrix4f mapnZXnY(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(-m20())._m01(-m21())._m02(-m22())._m03(m03())._m10(m00)._m11(m01)._m12(m02)._m13(m13())._m20(-m10)._m21(-m11)._m22(-m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 0 1 0 0
- * -1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnZYX() {
- return mapnZYX(this);
- }
- public Matrix4f mapnZYX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m20())._m01(-m21())._m02(-m22())._m03(m03())._m10(m10())._m11(m11())._m12(m12())._m13(m13())._m20(m00)._m21(m01)._m22(m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 0 1 0 0
- * -1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnZYnX() {
- return mapnZYnX(this);
- }
- public Matrix4f mapnZYnX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m20())._m01(-m21())._m02(-m22())._m03(m03())._m10(m10())._m11(m11())._m12(m12())._m13(m13())._m20(-m00)._m21(-m01)._m22(-m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 0 0 1 0
- * -1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnZnXY() {
- return mapnZnXY(this);
- }
- public Matrix4f mapnZnXY(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(-m20())._m01(-m21())._m02(-m22())._m03(m03())._m10(-m00)._m11(-m01)._m12(-m02)._m13(m13())._m20(m10)._m21(m11)._m22(m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 0 0 -1 0
- * -1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnZnXnY() {
- return mapnZnXnY(this);
- }
- public Matrix4f mapnZnXnY(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- float m10 = this.m10(), m11 = this.m11(), m12 = this.m12();
- return dest._m00(-m20())._m01(-m21())._m02(-m22())._m03(m03())._m10(-m00)._m11(-m01)._m12(-m02)._m13(m13())._m20(-m10)._m21(-m11)._m22(-m12)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 0 -1 0 0
- * -1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnZnYX() {
- return mapnZnYX(this);
- }
- public Matrix4f mapnZnYX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m20())._m01(-m21())._m02(-m22())._m03(m03())._m10(-m10())._m11(-m11())._m12(-m12())._m13(m13())._m20(m00)._m21(m01)._m22(m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 0 -1 0 0
- * -1 0 0 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f mapnZnYnX() {
- return mapnZnYnX(this);
- }
- public Matrix4f mapnZnYnX(Matrix4f dest) {
- float m00 = this.m00(), m01 = this.m01(), m02 = this.m02();
- return dest._m00(-m20())._m01(-m21())._m02(-m22())._m03(m03())._m10(-m10())._m11(-m11())._m12(-m12())._m13(m13())._m20(-m00)._m21(-m01)._m22(-m02)._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
-
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 1 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f negateX() {
- return _m00(-m00())._m01(-m01())._m02(-m02())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- public Matrix4f negateX(Matrix4f dest) {
- return dest._m00(-m00())._m01(-m01())._m02(-m02())._m03(m03())._m10(m10())._m11(m11())._m12(m12())._m13(m13())._m20(m20())._m21(m21())._m22(m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 -1 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f negateY() {
- return _m10(-m10())._m11(-m11())._m12(-m12())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- public Matrix4f negateY(Matrix4f dest) {
- return dest._m00(m00())._m01(m01())._m02(m02())._m03(m03())._m10(-m10())._m11(-m11())._m12(-m12())._m13(m13())._m20(m20())._m21(m21())._m22(m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 1 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- *
- * @return this
- */
- public Matrix4f negateZ() {
- return _m20(-m20())._m21(-m21())._m22(-m22())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
- public Matrix4f negateZ(Matrix4f dest) {
- return dest._m00(m00())._m01(m01())._m02(m02())._m03(m03())._m10(m10())._m11(m11())._m12(m12())._m13(m13())._m20(-m20())._m21(-m21())._m22(-m22())._m23(m23())._m30(m30())._m31(m31())._m32(m32())._m33(m33())._properties(properties & (PROPERTY_AFFINE | PROPERTY_ORTHONORMAL));
- }
-
- public boolean isFinite() {
- return Math.isFinite(m00()) && Math.isFinite(m01()) && Math.isFinite(m02()) && Math.isFinite(m03()) &&
- Math.isFinite(m10()) && Math.isFinite(m11()) && Math.isFinite(m12()) && Math.isFinite(m13()) &&
- Math.isFinite(m20()) && Math.isFinite(m21()) && Math.isFinite(m22()) && Math.isFinite(m23()) &&
- Math.isFinite(m30()) && Math.isFinite(m31()) && Math.isFinite(m32()) && Math.isFinite(m33());
- }
-
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix4fStack.java b/src/main/java/com/jozufozu/flywheel/util/joml/Matrix4fStack.java
deleted file mode 100644
index 559a500ac..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Matrix4fStack.java
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 Kai Burjack
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-
-/**
- * A stack of many {@link Matrix4f} instances. This resembles the matrix stack known from legacy OpenGL.
- * this
- * {@link Matrix4f}
- */
- public Matrix4fStack(int stackSize) {
- if (stackSize < 1) {
- throw new IllegalArgumentException("stackSize must be >= 1"); //$NON-NLS-1$
- }
- mats = new Matrix4f[stackSize - 1];
- // Allocate all matrices up front to keep the promise of being "allocation-free"
- for (int i = 0; i < mats.length; i++) {
- mats[i] = new Matrix4f();
- }
- }
-
- /**
- * Do not invoke manually! Only meant for serialization.
- * x=-1
when using the identity matrix.
- */
- int PLANE_NX = 0;
- /**
- * Argument to the first parameter of {@link #frustumPlane(int, Vector4f)}
- * identifying the plane with equation x=1
when using the identity matrix.
- */
- int PLANE_PX = 1;
- /**
- * Argument to the first parameter of {@link #frustumPlane(int, Vector4f)}
- * identifying the plane with equation y=-1
when using the identity matrix.
- */
- int PLANE_NY = 2;
- /**
- * Argument to the first parameter of {@link #frustumPlane(int, Vector4f)}
- * identifying the plane with equation y=1
when using the identity matrix.
- */
- int PLANE_PY = 3;
- /**
- * Argument to the first parameter of {@link #frustumPlane(int, Vector4f)}
- * identifying the plane with equation z=-1
when using the identity matrix.
- */
- int PLANE_NZ = 4;
- /**
- * Argument to the first parameter of {@link #frustumPlane(int, Vector4f)}
- * identifying the plane with equation z=1
when using the identity matrix.
- */
- int PLANE_PZ = 5;
- /**
- * Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
- * identifying the corner (-1, -1, -1)
when using the identity matrix.
- */
- int CORNER_NXNYNZ = 0;
- /**
- * Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
- * identifying the corner (1, -1, -1)
when using the identity matrix.
- */
- int CORNER_PXNYNZ = 1;
- /**
- * Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
- * identifying the corner (1, 1, -1)
when using the identity matrix.
- */
- int CORNER_PXPYNZ = 2;
- /**
- * Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
- * identifying the corner (-1, 1, -1)
when using the identity matrix.
- */
- int CORNER_NXPYNZ = 3;
- /**
- * Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
- * identifying the corner (1, -1, 1)
when using the identity matrix.
- */
- int CORNER_PXNYPZ = 4;
- /**
- * Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
- * identifying the corner (-1, -1, 1)
when using the identity matrix.
- */
- int CORNER_NXNYPZ = 5;
- /**
- * Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
- * identifying the corner (-1, 1, 1)
when using the identity matrix.
- */
- int CORNER_NXPYPZ = 6;
- /**
- * Argument to the first parameter of {@link #frustumCorner(int, Vector3f)}
- * identifying the corner (1, 1, 1)
when using the identity matrix.
- */
- int CORNER_PXPYPZ = 7;
-
- /**
- * Bit returned by {@link #properties()} to indicate that the matrix represents a perspective transformation.
- */
- byte PROPERTY_PERSPECTIVE = 1<<0;
- /**
- * Bit returned by {@link #properties()} to indicate that the matrix represents an affine transformation.
- */
- byte PROPERTY_AFFINE = 1<<1;
- /**
- * Bit returned by {@link #properties()} to indicate that the matrix represents the identity transformation.
- */
- byte PROPERTY_IDENTITY = 1<<2;
- /**
- * Bit returned by {@link #properties()} to indicate that the matrix represents a pure translation transformation.
- */
- byte PROPERTY_TRANSLATION = 1<<3;
- /**
- * Bit returned by {@link #properties()} to indicate that the upper-left 3x3 submatrix represents an orthogonal
- * matrix (i.e. orthonormal basis). For practical reasons, this property also always implies
- * {@link #PROPERTY_AFFINE} in this implementation.
- */
- byte PROPERTY_ORTHONORMAL = 1<<4;
-
- /**
- * Return the assumed properties of this matrix. This is a bit-combination of
- * {@link #PROPERTY_IDENTITY}, {@link #PROPERTY_AFFINE},
- * {@link #PROPERTY_TRANSLATION} and {@link #PROPERTY_PERSPECTIVE}.
- *
- * @return the properties of the matrix
- */
- int properties();
-
- /**
- * Return the value of the matrix element at column 0 and row 0.
- *
- * @return the value of the matrix element
- */
- float m00();
-
- /**
- * Return the value of the matrix element at column 0 and row 1.
- *
- * @return the value of the matrix element
- */
- float m01();
-
- /**
- * Return the value of the matrix element at column 0 and row 2.
- *
- * @return the value of the matrix element
- */
- float m02();
-
- /**
- * Return the value of the matrix element at column 0 and row 3.
- *
- * @return the value of the matrix element
- */
- float m03();
-
- /**
- * Return the value of the matrix element at column 1 and row 0.
- *
- * @return the value of the matrix element
- */
- float m10();
-
- /**
- * Return the value of the matrix element at column 1 and row 1.
- *
- * @return the value of the matrix element
- */
- float m11();
-
- /**
- * Return the value of the matrix element at column 1 and row 2.
- *
- * @return the value of the matrix element
- */
- float m12();
-
- /**
- * Return the value of the matrix element at column 1 and row 3.
- *
- * @return the value of the matrix element
- */
- float m13();
-
- /**
- * Return the value of the matrix element at column 2 and row 0.
- *
- * @return the value of the matrix element
- */
- float m20();
-
- /**
- * Return the value of the matrix element at column 2 and row 1.
- *
- * @return the value of the matrix element
- */
- float m21();
-
- /**
- * Return the value of the matrix element at column 2 and row 2.
- *
- * @return the value of the matrix element
- */
- float m22();
-
- /**
- * Return the value of the matrix element at column 2 and row 3.
- *
- * @return the value of the matrix element
- */
- float m23();
-
- /**
- * Return the value of the matrix element at column 3 and row 0.
- *
- * @return the value of the matrix element
- */
- float m30();
-
- /**
- * Return the value of the matrix element at column 3 and row 1.
- *
- * @return the value of the matrix element
- */
- float m31();
-
- /**
- * Return the value of the matrix element at column 3 and row 2.
- *
- * @return the value of the matrix element
- */
- float m32();
-
- /**
- * Return the value of the matrix element at column 3 and row 3.
- *
- * @return the value of the matrix element
- */
- float m33();
-
- /**
- * Multiply this matrix by the supplied right
matrix and store the result in dest
.
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param right
- * the right operand of the matrix multiplication
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mul(Matrix4fc right, Matrix4f dest);
-
- /**
- * Multiply this matrix by the supplied right
matrix and store the result in dest
.
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- * this
or right
- * and will always perform a complete 4x4 matrix multiplication. This method should only be used whenever the
- * multiplied matrices do not have any properties for which there are optimized multiplication methods available.
- *
- * @param right
- * the right operand of the matrix multiplication
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mul0(Matrix4fc right, Matrix4f dest);
-
- /**
- * Multiply this matrix by the matrix with the supplied elements and store the result in dest
.
- * M
is this
matrix and R
the right
matrix whose
- * elements are supplied via the parameters, then the new matrix will be M * R
.
- * So when transforming a vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param r00
- * the m00 element of the right matrix
- * @param r01
- * the m01 element of the right matrix
- * @param r02
- * the m02 element of the right matrix
- * @param r03
- * the m03 element of the right matrix
- * @param r10
- * the m10 element of the right matrix
- * @param r11
- * the m11 element of the right matrix
- * @param r12
- * the m12 element of the right matrix
- * @param r13
- * the m13 element of the right matrix
- * @param r20
- * the m20 element of the right matrix
- * @param r21
- * the m21 element of the right matrix
- * @param r22
- * the m22 element of the right matrix
- * @param r23
- * the m23 element of the right matrix
- * @param r30
- * the m30 element of the right matrix
- * @param r31
- * the m31 element of the right matrix
- * @param r32
- * the m32 element of the right matrix
- * @param r33
- * the m33 element of the right matrix
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mul(
- float r00, float r01, float r02, float r03,
- float r10, float r11, float r12, float r13,
- float r20, float r21, float r22, float r23,
- float r30, float r31, float r32, float r33, Matrix4f dest);
-
- /**
- * Multiply this matrix by the 3x3 matrix with the supplied elements expanded to a 4x4 matrix with
- * all other matrix elements set to identity, and store the result in dest
.
- * M
is this
matrix and R
the right
matrix whose
- * elements are supplied via the parameters, then the new matrix will be M * R
.
- * So when transforming a vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param r00
- * the m00 element of the right matrix
- * @param r01
- * the m01 element of the right matrix
- * @param r02
- * the m02 element of the right matrix
- * @param r10
- * the m10 element of the right matrix
- * @param r11
- * the m11 element of the right matrix
- * @param r12
- * the m12 element of the right matrix
- * @param r20
- * the m20 element of the right matrix
- * @param r21
- * the m21 element of the right matrix
- * @param r22
- * the m22 element of the right matrix
- * @param dest
- * the destination matrix, which will hold the result
- * @return this
- */
- Matrix4f mul3x3(
- float r00, float r01, float r02,
- float r10, float r11, float r12,
- float r20, float r21, float r22, Matrix4f dest);
-
- /**
- * Pre-multiply this matrix by the supplied left
matrix and store the result in dest
.
- * M
is this
matrix and L
the left
matrix,
- * then the new matrix will be L * M
. So when transforming a
- * vector v
with the new matrix by using L * M * v
, the
- * transformation of this
matrix will be applied first!
- *
- * @param left
- * the left operand of the matrix multiplication
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mulLocal(Matrix4fc left, Matrix4f dest);
-
- /**
- * Pre-multiply this matrix by the supplied left
matrix, both of which are assumed to be {@link #isAffine() affine}, and store the result in dest
.
- * this
matrix and the given left
matrix both represent an {@link #isAffine() affine} transformation
- * (i.e. their last rows are equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrices only represent affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * this
or the last row of left
.
- * M
is this
matrix and L
the left
matrix,
- * then the new matrix will be L * M
. So when transforming a
- * vector v
with the new matrix by using L * M * v
, the
- * transformation of this
matrix will be applied first!
- *
- * @param left
- * the left operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mulLocalAffine(Matrix4fc left, Matrix4f dest);
-
- /**
- * Multiply this
symmetric perspective projection matrix by the supplied {@link #isAffine() affine} view
matrix and store the result in dest
.
- * P
is this
matrix and V
the view
matrix,
- * then the new matrix will be P * V
. So when transforming a
- * vector v
with the new matrix by using P * V * v
, the
- * transformation of the view
matrix will be applied first!
- *
- * @param view
- * the {@link #isAffine() affine} matrix to multiply this
symmetric perspective projection matrix by
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mulPerspectiveAffine(Matrix4fc view, Matrix4f dest);
-
- /**
- * Multiply this matrix by the supplied right
matrix, which is assumed to be {@link #isAffine() affine}, and store the result in dest
.
- * right
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param right
- * the right operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mulAffineR(Matrix4fc right, Matrix4f dest);
-
- /**
- * Multiply this matrix by the supplied right
matrix, both of which are assumed to be {@link #isAffine() affine}, and store the result in dest
.
- * this
matrix and the given right
matrix both represent an {@link #isAffine() affine} transformation
- * (i.e. their last rows are equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrices only represent affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * this
or the last row of right
.
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param right
- * the right operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mulAffine(Matrix4fc right, Matrix4f dest);
-
- /**
- * Multiply this matrix, which is assumed to only contain a translation, by the supplied right
matrix, which is assumed to be {@link #isAffine() affine}, and store the result in dest
.
- * this
matrix only contains a translation, and that the given right
matrix represents an {@link #isAffine() affine} transformation
- * (i.e. its last row is equal to (0, 0, 0, 1)
).
- * this
or the last row of right
.
- * M
is this
matrix and R
the right
matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * transformation of the right matrix will be applied first!
- *
- * @param right
- * the right operand of the matrix multiplication (the last row is assumed to be (0, 0, 0, 1)
)
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mulTranslationAffine(Matrix4fc right, Matrix4f dest);
-
- /**
- * Multiply this
orthographic projection matrix by the supplied {@link #isAffine() affine} view
matrix
- * and store the result in dest
.
- * M
is this
matrix and V
the view
matrix,
- * then the new matrix will be M * V
. So when transforming a
- * vector v
with the new matrix by using M * V * v
, the
- * transformation of the view
matrix will be applied first!
- *
- * @param view
- * the affine matrix which to multiply this
with
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f mulOrthoAffine(Matrix4fc view, Matrix4f dest);
-
- /**
- * Component-wise add the upper 4x3 submatrices of this
and other
- * by first multiplying each component of other
's 4x3 submatrix by otherFactor
,
- * adding that to this
and storing the final result in dest
.
- * dest
will be set to the ones of this
.
- * this
and other
will not be changed.
- *
- * @param other
- * the other matrix
- * @param otherFactor
- * the factor to multiply each of the other matrix's 4x3 components
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f fma4x3(Matrix4fc other, float otherFactor, Matrix4f dest);
-
- /**
- * Component-wise add this
and other
and store the result in dest
.
- *
- * @param other
- * the other addend
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f add(Matrix4fc other, Matrix4f dest);
-
- /**
- * Component-wise subtract subtrahend
from this
and store the result in dest
.
- *
- * @param subtrahend
- * the subtrahend
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f sub(Matrix4fc subtrahend, Matrix4f dest);
-
- /**
- * Component-wise multiply this
by other
and store the result in dest
.
- *
- * @param other
- * the other matrix
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mulComponentWise(Matrix4fc other, Matrix4f dest);
-
- /**
- * Component-wise add the upper 4x3 submatrices of this
and other
- * and store the result in dest
.
- * dest
will be set to the ones of this
.
- *
- * @param other
- * the other addend
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f add4x3(Matrix4fc other, Matrix4f dest);
-
- /**
- * Component-wise subtract the upper 4x3 submatrices of subtrahend
from this
- * and store the result in dest
.
- * dest
will be set to the ones of this
.
- *
- * @param subtrahend
- * the subtrahend
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f sub4x3(Matrix4fc subtrahend, Matrix4f dest);
-
- /**
- * Component-wise multiply the upper 4x3 submatrices of this
by other
- * and store the result in dest
.
- * dest
will be set to the ones of this
.
- *
- * @param other
- * the other matrix
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mul4x3ComponentWise(Matrix4fc other, Matrix4f dest);
-
- /**
- * Return the determinant of this matrix.
- * this
matrix represents an {@link #isAffine() affine} transformation, such as translation, rotation, scaling and shearing,
- * and thus its last row is equal to (0, 0, 0, 1)
, then {@link #determinantAffine()} can be used instead of this method.
- *
- * @see #determinantAffine()
- *
- * @return the determinant
- */
- float determinant();
-
- /**
- * Return the determinant of the upper left 3x3 submatrix of this matrix.
- *
- * @return the determinant
- */
- float determinant3x3();
-
- /**
- * Return the determinant of this matrix by assuming that it represents an {@link #isAffine() affine} transformation and thus
- * its last row is equal to (0, 0, 0, 1)
.
- *
- * @return the determinant
- */
- float determinantAffine();
-
- /**
- * Invert this matrix and write the result into dest
.
- * this
matrix represents an {@link #isAffine() affine} transformation, such as translation, rotation, scaling and shearing,
- * and thus its last row is equal to (0, 0, 0, 1)
, then {@link #invertAffine(Matrix4f)} can be used instead of this method.
- *
- * @see #invertAffine(Matrix4f)
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f invert(Matrix4f dest);
-
- /**
- * If this
is a perspective projection matrix obtained via one of the {@link #perspective(float, float, float, float, Matrix4f) perspective()} methods,
- * that is, if this
is a symmetrical perspective frustum transformation,
- * then this method builds the inverse of this
and stores it into the given dest
.
- * this
- * @return dest
- */
- Matrix4f invertPerspective(Matrix4f dest);
-
- /**
- * If this
is an arbitrary perspective projection matrix obtained via one of the {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()} methods,
- * then this method builds the inverse of this
and stores it into the given dest
.
- * this
- * @return dest
- */
- Matrix4f invertFrustum(Matrix4f dest);
-
- /**
- * Invert this
orthographic projection matrix and store the result into the given dest
.
- * this
- * @return dest
- */
- Matrix4f invertOrtho(Matrix4f dest);
-
- /**
- * If this
is a perspective projection matrix obtained via one of the {@link #perspective(float, float, float, float, Matrix4f) perspective()} methods,
- * that is, if this
is a symmetrical perspective frustum transformation
- * and the given view
matrix is {@link #isAffine() affine} and has unit scaling (for example by being obtained via {@link #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f) lookAt()}),
- * then this method builds the inverse of this * view
and stores it into the given dest
.
- * this
and view
mentioned above, this method is equivalent to the following code:
- *
- * dest.set(this).mul(view).invert();
- *
- *
- * @param view
- * the view transformation (must be {@link #isAffine() affine} and have unit scaling)
- * @param dest
- * will hold the inverse of this * view
- * @return dest
- */
- Matrix4f invertPerspectiveView(Matrix4fc view, Matrix4f dest);
-
- /**
- * Invert this matrix by assuming that it is an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
- * and write the result into dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f invertAffine(Matrix4f dest);
-
- /**
- * Transpose this matrix and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f transpose(Matrix4f dest);
-
- /**
- * Transpose only the upper left 3x3 submatrix of this matrix and store the result in dest
.
- * dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f transpose3x3(Matrix3f dest);
-
- /**
- * Get only the translation components (m30, m31, m32)
of this matrix and store them in the given vector xyz
.
- *
- * @param dest
- * will hold the translation components of this matrix
- * @return dest
- */
- Vector3f getTranslation(Vector3f dest);
-
- /**
- * Get the scaling factors of this
matrix for the three base axes.
- *
- * @param dest
- * will hold the scaling factors for x
, y
and z
- * @return dest
- */
- Vector3f getScale(Vector3f dest);
-
- /**
- * Get the current values of this
matrix and store them into
- * dest
.
- *
- * @param dest
- * the destination matrix
- * @return the passed in destination
- */
- Matrix4f get(Matrix4f dest);
-
- /**
- * Get the current values of the upper left 3x3 submatrix of this
matrix and store them into
- * dest
.
- *
- * @see Matrix3f#set(Matrix4fc)
- *
- * @param dest
- * the destination matrix
- * @return the passed in destination
- */
- Matrix3f get3x3(Matrix3f dest);
-
- /**
- * Get the rotational component of this
matrix and store the represented rotation
- * into the given {@link AxisAngle4f}.
- *
- * @see AxisAngle4f#set(Matrix4fc)
- *
- * @param dest
- * the destination {@link AxisAngle4f}
- * @return the passed in destination
- */
- AxisAngle4f getRotation(AxisAngle4f dest);
-
- /**
- * Get the current values of this
matrix and store the represented rotation
- * into the given {@link Quaternionf}.
- * this
matrix and store the represented rotation
- * into the given {@link Quaternionf}.
- * this
matrix in row-major order into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- * this
matrix in row-major order into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- * this
matrix in row-major order into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- * this
matrix in row-major order into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- * dest
.
- *
- * @see Vector4f#mul(Matrix4fc, Vector4f)
- *
- * @param v
- * the vector to transform
- * @param dest
- * will contain the result
- * @return dest
- */
- Vector4f transform(Vector4fc v, Vector4f dest);
-
- /**
- * Transform/multiply the vector (x, y, z, w)
by this matrix and store the result in dest
.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param w
- * the w coordinate of the vector to transform
- * @param dest
- * will contain the result
- * @return dest
- */
- Vector4f transform(float x, float y, float z, float w, Vector4f dest);
-
- /**
- * Transform/multiply the given vector by the transpose of this matrix and store the result in that vector.
- *
- * @see Vector4f#mulTranspose(Matrix4fc)
- *
- * @param v
- * the vector to transform and to hold the final result
- * @return v
- */
- Vector4f transformTranspose(Vector4f v);
-
- /**
- * Transform/multiply the given vector by the transpose of this matrix and store the result in dest
.
- *
- * @see Vector4f#mulTranspose(Matrix4fc, Vector4f)
- *
- * @param v
- * the vector to transform
- * @param dest
- * will contain the result
- * @return dest
- */
- Vector4f transformTranspose(Vector4fc v, Vector4f dest);
-
- /**
- * Transform/multiply the vector (x, y, z, w)
by the transpose of this matrix and store the result in dest
.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param w
- * the w coordinate of the vector to transform
- * @param dest
- * will contain the result
- * @return dest
- */
- Vector4f transformTranspose(float x, float y, float z, float w, Vector4f dest);
-
- /**
- * Transform/multiply the given vector by this matrix, perform perspective divide and store the result in that vector.
- *
- * @see Vector4f#mulProject(Matrix4fc)
- *
- * @param v
- * the vector to transform and to hold the final result
- * @return v
- */
- Vector4f transformProject(Vector4f v);
-
- /**
- * Transform/multiply the given vector by this matrix, perform perspective divide and store the result in dest
.
- *
- * @see Vector4f#mulProject(Matrix4fc, Vector4f)
- *
- * @param v
- * the vector to transform
- * @param dest
- * will contain the result
- * @return dest
- */
- Vector4f transformProject(Vector4fc v, Vector4f dest);
-
- /**
- * Transform/multiply the vector (x, y, z, w)
by this matrix, perform perspective divide and store the result in dest
.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param w
- * the w coordinate of the vector to transform
- * @param dest
- * will contain the result
- * @return dest
- */
- Vector4f transformProject(float x, float y, float z, float w, Vector4f dest);
-
- /**
- * Transform/multiply the given vector by this matrix, perform perspective divide and store the result in that vector.
- * w=1.0
as the fourth vector component.
- *
- * @see Vector3f#mulProject(Matrix4fc)
- *
- * @param v
- * the vector to transform and to hold the final result
- * @return v
- */
- Vector3f transformProject(Vector3f v);
-
- /**
- * Transform/multiply the given vector by this matrix, perform perspective divide and store the result in dest
.
- * w=1.0
as the fourth vector component.
- *
- * @see Vector3f#mulProject(Matrix4fc, Vector3f)
- *
- * @param v
- * the vector to transform
- * @param dest
- * will contain the result
- * @return dest
- */
- Vector3f transformProject(Vector3fc v, Vector3f dest);
-
- /**
- * Transform/multiply the given vector by this matrix, perform perspective divide and store the result in dest
.
- *
- * @see Vector4f#mulProject(Matrix4fc, Vector4f)
- *
- * @param v
- * the vector to transform
- * @param dest
- * will contain the (x, y, z)
components of the result
- * @return dest
- */
- Vector3f transformProject(Vector4fc v, Vector3f dest);
-
- /**
- * Transform/multiply the vector (x, y, z)
by this matrix, perform perspective divide and store the result in dest
.
- * w=1.0
as the fourth vector component.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will contain the result
- * @return dest
- */
- Vector3f transformProject(float x, float y, float z, Vector3f dest);
-
- /**
- * Transform/multiply the vector (x, y, z, w)
by this matrix, perform perspective divide and store
- * (x, y, z)
of the result in dest
.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param w
- * the w coordinate of the vector to transform
- * @param dest
- * will contain the (x, y, z)
components of the result
- * @return dest
- */
- Vector3f transformProject(float x, float y, float z, float w, Vector3f dest);
-
- /**
- * Transform/multiply the given 3D-vector, as if it was a 4D-vector with w=1, by
- * this matrix and store the result in that vector.
- * w
component of the transformed vector.
- * For perspective projection use {@link #transform(Vector4f)} or {@link #transformProject(Vector3f)}
- * when perspective divide should be applied, too.
- * dest
.
- * w
component of the transformed vector.
- * For perspective projection use {@link #transform(Vector4fc, Vector4f)} or
- * {@link #transformProject(Vector3fc, Vector3f)} when perspective divide should be applied, too.
- * (x, y, z)
, as if it was a 4D-vector with w=1, by
- * this matrix and store the result in dest
.
- * w
component of the transformed vector.
- * For perspective projection use {@link #transform(float, float, float, float, Vector4f)} or
- * {@link #transformProject(float, float, float, Vector3f)} when perspective divide should be applied, too.
- *
- * @see #transform(float, float, float, float, Vector4f)
- * @see #transformProject(float, float, float, Vector3f)
- *
- * @param x
- * the x coordinate of the position
- * @param y
- * the y coordinate of the position
- * @param z
- * the z coordinate of the position
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformPosition(float x, float y, float z, Vector3f dest);
-
- /**
- * Transform/multiply the given 3D-vector, as if it was a 4D-vector with w=0, by
- * this matrix and store the result in that vector.
- * 0.0
, so it
- * will represent a direction in 3D-space rather than a position. This method will therefore
- * not take the translation part of the matrix into account.
- * dest
.
- * 0.0
, so it
- * will represent a direction in 3D-space rather than a position. This method will therefore
- * not take the translation part of the matrix into account.
- * (x, y, z)
, as if it was a 4D-vector with w=0, by
- * this matrix and store the result in dest
.
- * 0.0
, so it
- * will represent a direction in 3D-space rather than a position. This method will therefore
- * not take the translation part of the matrix into account.
- *
- * @param x
- * the x coordinate of the direction to transform
- * @param y
- * the y coordinate of the direction to transform
- * @param z
- * the z coordinate of the direction to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformDirection(float x, float y, float z, Vector3f dest);
-
- /**
- * Transform/multiply the given 4D-vector by assuming that this
matrix represents an {@link #isAffine() affine} transformation
- * (i.e. its last row is equal to (0, 0, 0, 1)
).
- * this
matrix represents an {@link #isAffine() affine} transformation
- * (i.e. its last row is equal to (0, 0, 0, 1)
) and store the result in dest
.
- * (x, y, z, w)
by assuming that this
matrix represents an {@link #isAffine() affine} transformation
- * (i.e. its last row is equal to (0, 0, 0, 1)
) and store the result in dest
.
- *
- * @param x
- * the x coordinate of the direction to transform
- * @param y
- * the y coordinate of the direction to transform
- * @param z
- * the z coordinate of the direction to transform
- * @param w
- * the w coordinate of the direction to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformAffine(float x, float y, float z, float w, Vector4f dest);
-
- /**
- * Apply scaling to this
matrix by scaling the base axes by the given xyz.x
,
- * xyz.y
and xyz.z
factors, respectively and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
- * , the scaling will be applied first!
- *
- * @param xyz
- * the factors of the x, y and z component, respectively
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f scale(Vector3fc xyz, Matrix4f dest);
-
- /**
- * Apply scaling to this matrix by uniformly scaling all base axes by the given xyz
factor
- * and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- * x
and the Y axis by y
- * and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f scaleXY(float x, float y, Matrix4f dest);
-
- /**
- * Apply scaling to this
matrix by scaling the base axes by the given x,
- * y and z factors and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
- * , the scaling will be applied first!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @param z
- * the factor of the z component
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f scale(float x, float y, float z, Matrix4f dest);
-
- /**
- * Apply scaling to this
matrix by scaling the base axes by the given sx,
- * sy and sz factors while using (ox, oy, oz)
as the scaling origin,
- * and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
- * , the scaling will be applied first!
- * translate(ox, oy, oz, dest).scale(sx, sy, sz).translate(-ox, -oy, -oz)
- *
- * @param sx
- * the scaling factor of the x component
- * @param sy
- * the scaling factor of the y component
- * @param sz
- * the scaling factor of the z component
- * @param ox
- * the x coordinate of the scaling origin
- * @param oy
- * the y coordinate of the scaling origin
- * @param oz
- * the z coordinate of the scaling origin
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f scaleAround(float sx, float sy, float sz, float ox, float oy, float oz, Matrix4f dest);
-
- /**
- * Apply scaling to this matrix by scaling all three base axes by the given factor
- * while using (ox, oy, oz)
as the scaling origin,
- * and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * scaling will be applied first!
- * translate(ox, oy, oz, dest).scale(factor).translate(-ox, -oy, -oz)
- *
- * @param factor
- * the scaling factor for all three axes
- * @param ox
- * the x coordinate of the scaling origin
- * @param oy
- * the y coordinate of the scaling origin
- * @param oz
- * the z coordinate of the scaling origin
- * @param dest
- * will hold the result
- * @return this
- */
- Matrix4f scaleAround(float factor, float ox, float oy, float oz, Matrix4f dest);
-
- /**
- * Pre-multiply scaling to this
matrix by scaling all base axes by the given xyz
factor,
- * and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
- * , the scaling will be applied last!
- *
- * @param xyz
- * the factor to scale all three base axes by
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f scaleLocal(float xyz, Matrix4f dest);
-
- /**
- * Pre-multiply scaling to this
matrix by scaling the base axes by the given x,
- * y and z factors and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
- * , the scaling will be applied last!
- *
- * @param x
- * the factor of the x component
- * @param y
- * the factor of the y component
- * @param z
- * the factor of the z component
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f scaleLocal(float x, float y, float z, Matrix4f dest);
-
- /**
- * Pre-multiply scaling to this
matrix by scaling the base axes by the given sx,
- * sy and sz factors while using the given (ox, oy, oz)
as the scaling origin,
- * and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
- * , the scaling will be applied last!
- * new Matrix4f().translate(ox, oy, oz).scale(sx, sy, sz).translate(-ox, -oy, -oz).mul(this, dest)
- *
- * @param sx
- * the scaling factor of the x component
- * @param sy
- * the scaling factor of the y component
- * @param sz
- * the scaling factor of the z component
- * @param ox
- * the x coordinate of the scaling origin
- * @param oy
- * the y coordinate of the scaling origin
- * @param oz
- * the z coordinate of the scaling origin
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f scaleAroundLocal(float sx, float sy, float sz, float ox, float oy, float oz, Matrix4f dest);
-
- /**
- * Pre-multiply scaling to this matrix by scaling all three base axes by the given factor
- * while using (ox, oy, oz)
as the scaling origin,
- * and store the result in dest
.
- * M
is this
matrix and S
the scaling matrix,
- * then the new matrix will be S * M
. So when transforming a
- * vector v
with the new matrix by using S * M * v
, the
- * scaling will be applied last!
- * new Matrix4f().translate(ox, oy, oz).scale(factor).translate(-ox, -oy, -oz).mul(this, dest)
- *
- * @param factor
- * the scaling factor for all three axes
- * @param ox
- * the x coordinate of the scaling origin
- * @param oy
- * the y coordinate of the scaling origin
- * @param oz
- * the z coordinate of the scaling origin
- * @param dest
- * will hold the result
- * @return this
- */
- Matrix4f scaleAroundLocal(float factor, float ox, float oy, float oz, Matrix4f dest);
-
- /**
- * Apply rotation about the X axis to this matrix by rotating the given amount of radians
- * and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * +X
towards (dirX, dirY)
and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (dirX, dirY)
must be a unit vector.
- *
- * @param dirX
- * the x component of the normalized direction
- * @param dirY
- * the y component of the normalized direction
- * @param dest
- * will hold the result
- * @return this
- */
- Matrix4f rotateTowardsXY(float dirX, float dirY, Matrix4f dest);
-
- /**
- * Apply rotation of angleX
radians about the X axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateX(angleX, dest).rotateY(angleY).rotateZ(angleZ)
- *
- * @param angleX
- * the angle to rotate about X
- * @param angleY
- * the angle to rotate about Y
- * @param angleZ
- * the angle to rotate about Z
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateXYZ(float angleX, float angleY, float angleZ, Matrix4f dest);
-
- /**
- * Apply rotation of angleX
radians about the X axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
- * this
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- *
- * @param angleX
- * the angle to rotate about X
- * @param angleY
- * the angle to rotate about Y
- * @param angleZ
- * the angle to rotate about Z
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateAffineXYZ(float angleX, float angleY, float angleZ, Matrix4f dest);
-
- /**
- * Apply rotation of angleZ
radians about the Z axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleX
radians about the X axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateZ(angleZ, dest).rotateY(angleY).rotateX(angleX)
- *
- * @param angleZ
- * the angle to rotate about Z
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateZYX(float angleZ, float angleY, float angleX, Matrix4f dest);
-
- /**
- * Apply rotation of angleZ
radians about the Z axis, followed by a rotation of angleY
radians about the Y axis and
- * followed by a rotation of angleX
radians about the X axis and store the result in dest
.
- * this
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- *
- * @param angleZ
- * the angle to rotate about Z
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateAffineZYX(float angleZ, float angleY, float angleX, Matrix4f dest);
-
- /**
- * Apply rotation of angleY
radians about the Y axis, followed by a rotation of angleX
radians about the X axis and
- * followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * rotateY(angleY, dest).rotateX(angleX).rotateZ(angleZ)
- *
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param angleZ
- * the angle to rotate about Z
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateYXZ(float angleY, float angleX, float angleZ, Matrix4f dest);
-
- /**
- * Apply rotation of angleY
radians about the Y axis, followed by a rotation of angleX
radians about the X axis and
- * followed by a rotation of angleZ
radians about the Z axis and store the result in dest
.
- * this
matrix represents an {@link #isAffine() affine} transformation (i.e. its last row is equal to (0, 0, 0, 1)
)
- * and can be used to speed up matrix multiplication if the matrix only represents affine transformations, such as translation, rotation, scaling and shearing (in any combination).
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- *
- * @param angleY
- * the angle to rotate about Y
- * @param angleX
- * the angle to rotate about X
- * @param angleZ
- * the angle to rotate about Z
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateAffineYXZ(float angleY, float angleX, float angleZ, Matrix4f dest);
-
- /**
- * Apply rotation to this matrix by rotating the given amount of radians
- * about the specified (x, y, z)
axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (x, y, z)
axis and store the result in dest
.
- * this
to only contain a translation.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (x, y, z)
axis and store the result in dest
.
- * this
to be {@link #isAffine() affine}.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * rotation will be applied first!
- * (x, y, z)
axis and store the result in dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and R
the rotation matrix,
- * then the new matrix will be R * M
. So when transforming a
- * vector v
with the new matrix by using R * M * v
, the
- * rotation will be applied last!
- * dest
.
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be M * T
. So when
- * transforming a vector v
with the new matrix by using
- * M * T * v
, the translation will be applied first!
- *
- * @param offset
- * the number of units in x, y and z by which to translate
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f translate(Vector3fc offset, Matrix4f dest);
-
- /**
- * Apply a translation to this matrix by translating by the given number of
- * units in x, y and z and store the result in dest
.
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be M * T
. So when
- * transforming a vector v
with the new matrix by using
- * M * T * v
, the translation will be applied first!
- *
- * @param x
- * the offset to translate in x
- * @param y
- * the offset to translate in y
- * @param z
- * the offset to translate in z
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f translate(float x, float y, float z, Matrix4f dest);
-
- /**
- * Pre-multiply a translation to this matrix by translating by the given number of
- * units in x, y and z and store the result in dest
.
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be T * M
. So when
- * transforming a vector v
with the new matrix by using
- * T * M * v
, the translation will be applied last!
- *
- * @param offset
- * the number of units in x, y and z by which to translate
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f translateLocal(Vector3fc offset, Matrix4f dest);
-
- /**
- * Pre-multiply a translation to this matrix by translating by the given number of
- * units in x, y and z and store the result in dest
.
- * M
is this
matrix and T
the translation
- * matrix, then the new matrix will be T * M
. So when
- * transforming a vector v
with the new matrix by using
- * T * M * v
, the translation will be applied last!
- *
- * @param x
- * the offset to translate in x
- * @param y
- * the offset to translate in y
- * @param z
- * the offset to translate in z
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f translateLocal(float x, float y, float z, Matrix4f dest);
-
- /**
- * Apply an orthographic projection transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * Reference: http://www.songho.ca
- *
- * @param left
- * the distance from the center to the left frustum edge
- * @param right
- * the distance from the center to the right frustum edge
- * @param bottom
- * the distance from the center to the bottom frustum edge
- * @param top
- * the distance from the center to the top frustum edge
- * @param zNear
- * near clipping plane distance
- * @param zFar
- * far clipping plane distance
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f ortho(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply an orthographic projection transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * dest
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f orthoLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply an orthographic projection transformation for a left-handed coordiante system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * dest
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- Matrix4f orthoSymmetric(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply a symmetric orthographic projection transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * dest
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- Matrix4f orthoSymmetricLH(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply a symmetric orthographic projection transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * left=-width/2
, right=+width/2
, bottom=-height/2
and top=+height/2
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * dest
.
- * zNear=-1
and zFar=+1
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * dest
.
- * zNear=-1
and zFar=+1
.
- * M
is this
matrix and O
the orthographic projection matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * orthographic projection transformation will be applied first!
- * -z
point along dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * eye = (0, 0, 0)
and center = dir
.
- *
- * @see #lookAlong(float, float, float, float, float, float, Matrix4f)
- * @see #lookAt(Vector3fc, Vector3fc, Vector3fc, Matrix4f)
- *
- * @param dir
- * the direction in space to look along
- * @param up
- * the direction of 'up'
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f lookAlong(Vector3fc dir, Vector3fc up, Matrix4f dest);
-
- /**
- * Apply a rotation transformation to this matrix to make -z
point along dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookalong rotation matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
, the
- * lookalong rotation transformation will be applied first!
- * eye = (0, 0, 0)
and center = dir
.
- *
- * @see #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f)
- *
- * @param dirX
- * the x-coordinate of the direction to look along
- * @param dirY
- * the y-coordinate of the direction to look along
- * @param dirZ
- * the z-coordinate of the direction to look along
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f lookAlong(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix4f dest);
-
- /**
- * Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
- * that aligns -z
with center - eye
and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- *
- * @see #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f)
- *
- * @param eye
- * the position of the camera
- * @param center
- * the point in space to look at
- * @param up
- * the direction of 'up'
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f lookAt(Vector3fc eye, Vector3fc center, Vector3fc up, Matrix4f dest);
-
- /**
- * Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
- * that aligns -z
with center - eye
and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- *
- * @see #lookAt(Vector3fc, Vector3fc, Vector3fc, Matrix4f)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f lookAt(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ, Matrix4f dest);
-
- /**
- * Apply a "lookat" transformation to this matrix for a right-handed coordinate system,
- * that aligns -z
with center - eye
and store the result in dest
.
- * this
to be a perspective transformation, obtained via
- * {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()} or {@link #perspective(float, float, float, float, Matrix4f) perspective()} or
- * one of their overloads.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f lookAtPerspective(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ, Matrix4f dest);
-
- /**
- * Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
- * that aligns +z
with center - eye
and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- *
- * @see #lookAtLH(float, float, float, float, float, float, float, float, float, Matrix4f)
- *
- * @param eye
- * the position of the camera
- * @param center
- * the point in space to look at
- * @param up
- * the direction of 'up'
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f lookAtLH(Vector3fc eye, Vector3fc center, Vector3fc up, Matrix4f dest);
-
- /**
- * Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
- * that aligns +z
with center - eye
and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- *
- * @see #lookAtLH(Vector3fc, Vector3fc, Vector3fc, Matrix4f)
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f lookAtLH(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ, Matrix4f dest);
-
- /**
- * Apply a "lookat" transformation to this matrix for a left-handed coordinate system,
- * that aligns +z
with center - eye
and store the result in dest
.
- * this
to be a perspective transformation, obtained via
- * {@link #frustumLH(float, float, float, float, float, float, Matrix4f) frustumLH()} or {@link #perspectiveLH(float, float, float, float, Matrix4f) perspectiveLH()} or
- * one of their overloads.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- *
- * @param eyeX
- * the x-coordinate of the eye/camera location
- * @param eyeY
- * the y-coordinate of the eye/camera location
- * @param eyeZ
- * the z-coordinate of the eye/camera location
- * @param centerX
- * the x-coordinate of the point to look at
- * @param centerY
- * the y-coordinate of the point to look at
- * @param centerZ
- * the z-coordinate of the point to look at
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f lookAtPerspectiveLH(float eyeX, float eyeY, float eyeZ, float centerX, float centerY, float centerZ, float upX, float upY, float upZ, Matrix4f dest);
-
- /**
- * This method is equivalent to calling: translate(w-1-2*x, h-1-2*y, 0, dest).scale(w, h, 1)
- * M
is this
matrix and T
the created transformation matrix,
- * then the new matrix will be M * T
. So when transforming a
- * vector v
with the new matrix by using M * T * v
, the
- * created transformation will be applied first!
- *
- * @param x
- * the tile's x coordinate/index (should be in [0..w)
)
- * @param y
- * the tile's y coordinate/index (should be in [0..h)
)
- * @param w
- * the number of tiles along the x axis
- * @param h
- * the number of tiles along the y axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f tile(int x, int y, int w, int h, Matrix4f dest);
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f perspective(float fovy, float aspect, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param width
- * the width of the near frustum plane
- * @param height
- * the height of the near frustum plane
- * @param zNear
- * near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- Matrix4f perspectiveRect(float width, float height, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param width
- * the width of the near frustum plane
- * @param height
- * the height of the near frustum plane
- * @param zNear
- * near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f perspectiveRect(float width, float height, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * offAngleX
and offAngleY
are the horizontal and vertical angles between
- * the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
- * is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
- * is parallel to the XZ-plane.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param offAngleX
- * the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param offAngleY
- * the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @return dest
- */
- Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * offAngleX
and offAngleY
are the horizontal and vertical angles between
- * the line of sight and the line given by the center of the near and far frustum planes. So, when offAngleY
- * is just fovy/2
then the projection frustum is rotated towards +Y and the bottom frustum plane
- * is parallel to the XZ-plane.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param offAngleX
- * the horizontal angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param offAngleY
- * the vertical angle between the line of sight and the line crossing the center of the near and far frustum planes
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f perspectiveOffCenter(float fovy, float offAngleX, float offAngleY, float aspect, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f perspectiveOffCenterFov(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f perspectiveOffCenterFov(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f perspectiveOffCenterFovLH(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply an asymmetric off-center perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * angleLeft
and angleRight
are the horizontal angles between
- * the left and right frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * The angles angleDown
and angleUp
are the vertical angles between
- * the bottom and top frustum planes, respectively, and a line perpendicular to the near and far frustum planes.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param angleLeft
- * the horizontal angle between left frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleRight
- * the horizontal angle between right frustum plane and a line perpendicular to the near/far frustum planes
- * @param angleDown
- * the vertical angle between bottom frustum plane and a line perpendicular to the near/far frustum planes.
- * For a symmetric frustum, this value is negative.
- * @param angleUp
- * the vertical angle between top frustum plane and a line perpendicular to the near/far frustum planes
- * @param zNear
- * near clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f perspectiveOffCenterFovLH(float angleLeft, float angleRight, float angleDown, float angleUp, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f perspectiveLH(float fovy, float aspect, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply a symmetric perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and P
the perspective projection matrix,
- * then the new matrix will be M * P
. So when transforming a
- * vector v
with the new matrix by using M * P * v
,
- * the perspective projection will be applied first!
- *
- * @param fovy
- * the vertical field of view in radians (must be greater than zero and less than {@link Math#PI PI})
- * @param aspect
- * the aspect ratio (i.e. width / height; must be greater than zero)
- * @param zNear
- * near clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the near clipping plane will be at positive infinity.
- * In that case, zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f perspectiveLH(float fovy, float aspect, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a right-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f frustum(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a right-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f frustum(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a left-handed coordinate system
- * using the given NDC z range to this matrix and store the result in dest
.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zZeroToOne
- * whether to use Vulkan's and Direct3D's NDC z range of [0..+1]
when true
- * or whether to use OpenGL's NDC z range of [-1..+1]
when false
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f frustumLH(float left, float right, float bottom, float top, float zNear, float zFar, boolean zZeroToOne, Matrix4f dest);
-
- /**
- * Apply an arbitrary perspective projection frustum transformation for a left-handed coordinate system
- * using OpenGL's NDC z range of [-1..+1]
to this matrix and store the result in dest
.
- * M
is this
matrix and F
the frustum matrix,
- * then the new matrix will be M * F
. So when transforming a
- * vector v
with the new matrix by using M * F * v
,
- * the frustum transformation will be applied first!
- * zFar
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param zFar
- * far clipping plane distance. This value must be greater than zero.
- * If the special value {@link Float#POSITIVE_INFINITY} is used, the far clipping plane will be at positive infinity.
- * In that case, zNear
may not also be {@link Float#POSITIVE_INFINITY}.
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f frustumLH(float left, float right, float bottom, float top, float zNear, float zFar, Matrix4f dest);
-
- /**
- * Apply the rotation - and possibly scaling - transformation of the given {@link Quaternionfc} to this matrix and store
- * the result in dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * dest
.
- * this
to be {@link #isAffine() affine}.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * dest
.
- * this
to only contain a translation.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * (ox, oy, oz)
as the rotation origin, and store the result in dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * this
is an {@link #isAffine() affine} matrix.
- * translate(ox, oy, oz, dest).rotate(quat).translate(-ox, -oy, -oz)
- * (ox, oy, oz)
as the rotation origin,
- * and store the result in dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be M * Q
. So when transforming a
- * vector v
with the new matrix by using M * Q * v
,
- * the quaternion rotation will be applied first!
- * translate(ox, oy, oz, dest).rotate(quat).translate(-ox, -oy, -oz)
- * dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be Q * M
. So when transforming a
- * vector v
with the new matrix by using Q * M * v
,
- * the quaternion rotation will be applied last!
- * (ox, oy, oz)
- * as the rotation origin, and store the result in dest
.
- * M
is this
matrix and Q
the rotation matrix obtained from the given quaternion,
- * then the new matrix will be Q * M
. So when transforming a
- * vector v
with the new matrix by using Q * M * v
,
- * the quaternion rotation will be applied last!
- * translateLocal(-ox, -oy, -oz, dest).rotateLocal(quat).translateLocal(ox, oy, oz)
- * dest
.
- * M
is this
matrix and A
the rotation matrix obtained from the given {@link AxisAngle4f},
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the {@link AxisAngle4f} rotation will be applied first!
- * dest
.
- * axis
vector needs to be a unit vector.
- * M
is this
matrix and A
the rotation matrix obtained from the given axis-angle,
- * then the new matrix will be M * A
. So when transforming a
- * vector v
with the new matrix by using M * A * v
,
- * the axis-angle rotation will be applied first!
- * (winX, winY, winZ)
by this
matrix using the specified viewport.
- * [-1..1]
- * and then transforms those NDC coordinates by the inverse of this
matrix.
- * winZ
is assumed to be [0..1]
, which is also the OpenGL default.
- * this
matrix.
- * In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
- * once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInv(float, float, float, int[], Vector4f) unprojectInv()} can be invoked on it.
- *
- * @see #unprojectInv(float, float, float, int[], Vector4f)
- * @see #invert(Matrix4f)
- *
- * @param winX
- * the x-coordinate in window coordinates (pixels)
- * @param winY
- * the y-coordinate in window coordinates (pixels)
- * @param winZ
- * the z-coordinate, which is the depth value in [0..1]
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param dest
- * will hold the unprojected position
- * @return dest
- */
- Vector4f unproject(float winX, float winY, float winZ, int[] viewport, Vector4f dest);
-
- /**
- * Unproject the given window coordinates (winX, winY, winZ)
by this
matrix using the specified viewport.
- * [-1..1]
- * and then transforms those NDC coordinates by the inverse of this
matrix.
- * winZ
is assumed to be [0..1]
, which is also the OpenGL default.
- * this
matrix.
- * In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
- * once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInv(float, float, float, int[], Vector3f) unprojectInv()} can be invoked on it.
- *
- * @see #unprojectInv(float, float, float, int[], Vector3f)
- * @see #invert(Matrix4f)
- *
- * @param winX
- * the x-coordinate in window coordinates (pixels)
- * @param winY
- * the y-coordinate in window coordinates (pixels)
- * @param winZ
- * the z-coordinate, which is the depth value in [0..1]
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param dest
- * will hold the unprojected position
- * @return dest
- */
- Vector3f unproject(float winX, float winY, float winZ, int[] viewport, Vector3f dest);
-
- /**
- * Unproject the given window coordinates winCoords
by this
matrix using the specified viewport.
- * [-1..1]
- * and then transforms those NDC coordinates by the inverse of this
matrix.
- * winCoords.z
is assumed to be [0..1]
, which is also the OpenGL default.
- * this
matrix.
- * In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
- * once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInv(float, float, float, int[], Vector4f) unprojectInv()} can be invoked on it.
- *
- * @see #unprojectInv(float, float, float, int[], Vector4f)
- * @see #unproject(float, float, float, int[], Vector4f)
- * @see #invert(Matrix4f)
- *
- * @param winCoords
- * the window coordinates to unproject
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param dest
- * will hold the unprojected position
- * @return dest
- */
- Vector4f unproject(Vector3fc winCoords, int[] viewport, Vector4f dest);
-
- /**
- * Unproject the given window coordinates winCoords
by this
matrix using the specified viewport.
- * [-1..1]
- * and then transforms those NDC coordinates by the inverse of this
matrix.
- * winCoords.z
is assumed to be [0..1]
, which is also the OpenGL default.
- * this
matrix.
- * In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
- * once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInv(float, float, float, int[], Vector3f) unprojectInv()} can be invoked on it.
- *
- * @see #unprojectInv(float, float, float, int[], Vector3f)
- * @see #unproject(float, float, float, int[], Vector3f)
- * @see #invert(Matrix4f)
- *
- * @param winCoords
- * the window coordinates to unproject
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param dest
- * will hold the unprojected position
- * @return dest
- */
- Vector3f unproject(Vector3fc winCoords, int[] viewport, Vector3f dest);
-
- /**
- * Unproject the given 2D window coordinates (winX, winY)
by this
matrix using the specified viewport
- * and compute the origin and the direction of the resulting ray which starts at NDC z = -1.0
and goes through NDC z = +1.0
.
- * [-1..1]
- * and then transforms those NDC coordinates by the inverse of this
matrix.
- * this
matrix.
- * In order to avoid computing the matrix inverse with every invocation, the inverse of this
matrix can be built
- * once outside using {@link #invert(Matrix4f)} and then the method {@link #unprojectInvRay(float, float, int[], Vector3f, Vector3f) unprojectInvRay()} can be invoked on it.
- *
- * @see #unprojectInvRay(float, float, int[], Vector3f, Vector3f)
- * @see #invert(Matrix4f)
- *
- * @param winX
- * the x-coordinate in window coordinates (pixels)
- * @param winY
- * the y-coordinate in window coordinates (pixels)
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param originDest
- * will hold the ray origin
- * @param dirDest
- * will hold the (unnormalized) ray direction
- * @return this
- */
- Matrix4f unprojectRay(float winX, float winY, int[] viewport, Vector3f originDest, Vector3f dirDest);
-
- /**
- * Unproject the given window coordinates winCoords
by this
matrix using the specified viewport.
- * this
is already the inverse matrix of the original projection matrix.
- * It exists to avoid recomputing the matrix inverse with every invocation.
- * winCoords.z
is assumed to be [0..1]
, which is also the OpenGL default.
- * [x, y, width, height]
- * @param dest
- * will hold the unprojected position
- * @return dest
- */
- Vector4f unprojectInv(Vector3fc winCoords, int[] viewport, Vector4f dest);
-
- /**
- * Unproject the given window coordinates (winX, winY, winZ)
by this
matrix using the specified viewport.
- * this
is already the inverse matrix of the original projection matrix.
- * It exists to avoid recomputing the matrix inverse with every invocation.
- * winZ
is assumed to be [0..1]
, which is also the OpenGL default.
- *
- * @see #unproject(float, float, float, int[], Vector4f)
- *
- * @param winX
- * the x-coordinate in window coordinates (pixels)
- * @param winY
- * the y-coordinate in window coordinates (pixels)
- * @param winZ
- * the z-coordinate, which is the depth value in [0..1]
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param dest
- * will hold the unprojected position
- * @return dest
- */
- Vector4f unprojectInv(float winX, float winY, float winZ, int[] viewport, Vector4f dest);
-
- /**
- * Unproject the given 2D window coordinates (winX, winY)
by this
matrix using the specified viewport
- * and compute the origin and the direction of the resulting ray which starts at NDC z = -1.0
and goes through NDC z = +1.0
.
- * this
is already the inverse matrix of the original projection matrix.
- * It exists to avoid recomputing the matrix inverse with every invocation.
- *
- * @see #unprojectRay(float, float, int[], Vector3f, Vector3f)
- *
- * @param winX
- * the x-coordinate in window coordinates (pixels)
- * @param winY
- * the y-coordinate in window coordinates (pixels)
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param originDest
- * will hold the ray origin
- * @param dirDest
- * will hold the (unnormalized) ray direction
- * @return this
- */
- Matrix4f unprojectInvRay(float winX, float winY, int[] viewport, Vector3f originDest, Vector3f dirDest);
-
- /**
- * Unproject the given window coordinates winCoords
by this
matrix using the specified viewport.
- * this
is already the inverse matrix of the original projection matrix.
- * It exists to avoid recomputing the matrix inverse with every invocation.
- * winCoords.z
is assumed to be [0..1]
, which is also the OpenGL default.
- *
- * @see #unproject(Vector3fc, int[], Vector3f)
- *
- * @param winCoords
- * the window coordinates to unproject
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param dest
- * will hold the unprojected position
- * @return dest
- */
- Vector3f unprojectInv(Vector3fc winCoords, int[] viewport, Vector3f dest);
-
- /**
- * Unproject the given window coordinates (winX, winY, winZ)
by this
matrix using the specified viewport.
- * this
is already the inverse matrix of the original projection matrix.
- * It exists to avoid recomputing the matrix inverse with every invocation.
- * winZ
is assumed to be [0..1]
, which is also the OpenGL default.
- *
- * @see #unproject(float, float, float, int[], Vector3f)
- *
- * @param winX
- * the x-coordinate in window coordinates (pixels)
- * @param winY
- * the y-coordinate in window coordinates (pixels)
- * @param winZ
- * the z-coordinate, which is the depth value in [0..1]
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param dest
- * will hold the unprojected position
- * @return dest
- */
- Vector3f unprojectInv(float winX, float winY, float winZ, int[] viewport, Vector3f dest);
-
- /**
- * Project the given (x, y, z)
position via this
matrix using the specified viewport
- * and store the resulting window coordinates in winCoordsDest
.
- * this
matrix including perspective division to
- * obtain normalized device coordinates, and then translates these into window coordinates by using the
- * given viewport
settings [x, y, width, height]
.
- * winCoordsDest.z
will be [0..1]
, which is also the OpenGL default.
- *
- * @param x
- * the x-coordinate of the position to project
- * @param y
- * the y-coordinate of the position to project
- * @param z
- * the z-coordinate of the position to project
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param winCoordsDest
- * will hold the projected window coordinates
- * @return winCoordsDest
- */
- Vector4f project(float x, float y, float z, int[] viewport, Vector4f winCoordsDest);
-
- /**
- * Project the given (x, y, z)
position via this
matrix using the specified viewport
- * and store the resulting window coordinates in winCoordsDest
.
- * this
matrix including perspective division to
- * obtain normalized device coordinates, and then translates these into window coordinates by using the
- * given viewport
settings [x, y, width, height]
.
- * winCoordsDest.z
will be [0..1]
, which is also the OpenGL default.
- *
- * @param x
- * the x-coordinate of the position to project
- * @param y
- * the y-coordinate of the position to project
- * @param z
- * the z-coordinate of the position to project
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param winCoordsDest
- * will hold the projected window coordinates
- * @return winCoordsDest
- */
- Vector3f project(float x, float y, float z, int[] viewport, Vector3f winCoordsDest);
-
- /**
- * Project the given position
via this
matrix using the specified viewport
- * and store the resulting window coordinates in winCoordsDest
.
- * this
matrix including perspective division to
- * obtain normalized device coordinates, and then translates these into window coordinates by using the
- * given viewport
settings [x, y, width, height]
.
- * winCoordsDest.z
will be [0..1]
, which is also the OpenGL default.
- *
- * @see #project(float, float, float, int[], Vector4f)
- *
- * @param position
- * the position to project into window coordinates
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param winCoordsDest
- * will hold the projected window coordinates
- * @return winCoordsDest
- */
- Vector4f project(Vector3fc position, int[] viewport, Vector4f winCoordsDest);
-
- /**
- * Project the given position
via this
matrix using the specified viewport
- * and store the resulting window coordinates in winCoordsDest
.
- * this
matrix including perspective division to
- * obtain normalized device coordinates, and then translates these into window coordinates by using the
- * given viewport
settings [x, y, width, height]
.
- * winCoordsDest.z
will be [0..1]
, which is also the OpenGL default.
- *
- * @see #project(float, float, float, int[], Vector4f)
- *
- * @param position
- * the position to project into window coordinates
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param winCoordsDest
- * will hold the projected window coordinates
- * @return winCoordsDest
- */
- Vector3f project(Vector3fc position, int[] viewport, Vector3f winCoordsDest);
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects about the given plane
- * specified via the equation x*a + y*b + z*c + d = 0
and store the result in dest
.
- * (a, b, c)
must be a unit vector.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- * dest
.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param nx
- * the x-coordinate of the plane normal
- * @param ny
- * the y-coordinate of the plane normal
- * @param nz
- * the z-coordinate of the plane normal
- * @param px
- * the x-coordinate of a point on the plane
- * @param py
- * the y-coordinate of a point on the plane
- * @param pz
- * the z-coordinate of a point on the plane
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f reflect(float nx, float ny, float nz, float px, float py, float pz, Matrix4f dest);
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects about a plane
- * specified via the plane orientation and a point on the plane, and store the result in dest
.
- * (0, 0, 1)
. So, if the given {@link Quaternionfc} is
- * the identity (does not apply any additional rotation), the reflection plane will be z=0
, offset by the given point
.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param orientation
- * the plane orientation relative to an implied normal vector of (0, 0, 1)
- * @param point
- * a point on the plane
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f reflect(Quaternionfc orientation, Vector3fc point, Matrix4f dest);
-
- /**
- * Apply a mirror/reflection transformation to this matrix that reflects about the given plane
- * specified via the plane normal and a point on the plane, and store the result in dest
.
- * M
is this
matrix and R
the reflection matrix,
- * then the new matrix will be M * R
. So when transforming a
- * vector v
with the new matrix by using M * R * v
, the
- * reflection will be applied first!
- *
- * @param normal
- * the plane normal
- * @param point
- * a point on the plane
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f reflect(Vector3fc normal, Vector3fc point, Matrix4f dest);
-
- /**
- * Get the row at the given row
index, starting with 0
.
- *
- * @param row
- * the row index in [0..3]
- * @param dest
- * will hold the row components
- * @return the passed in destination
- * @throws IndexOutOfBoundsException if row
is not in [0..3]
- */
- Vector4f getRow(int row, Vector4f dest) throws IndexOutOfBoundsException;
-
- /**
- * Get the first three components of the row at the given row
index, starting with 0
.
- *
- * @param row
- * the row index in [0..3]
- * @param dest
- * will hold the first three row components
- * @return the passed in destination
- * @throws IndexOutOfBoundsException if row
is not in [0..3]
- */
- Vector3f getRow(int row, Vector3f dest) throws IndexOutOfBoundsException;
-
- /**
- * Get the column at the given column
index, starting with 0
.
- *
- * @param column
- * the column index in [0..3]
- * @param dest
- * will hold the column components
- * @return the passed in destination
- * @throws IndexOutOfBoundsException if column
is not in [0..3]
- */
- Vector4f getColumn(int column, Vector4f dest) throws IndexOutOfBoundsException;
-
- /**
- * Get the first three components of the column at the given column
index, starting with 0
.
- *
- * @param column
- * the column index in [0..3]
- * @param dest
- * will hold the first three column components
- * @return the passed in destination
- * @throws IndexOutOfBoundsException if column
is not in [0..3]
- */
- Vector3f getColumn(int column, Vector3f dest) throws IndexOutOfBoundsException;
-
- /**
- * Get the matrix element value at the given column and row.
- *
- * @param column
- * the colum index in [0..3]
- * @param row
- * the row index in [0..3]
- * @return the element value
- */
- float get(int column, int row);
-
- /**
- * Get the matrix element value at the given row and column.
- *
- * @param row
- * the row index in [0..3]
- * @param column
- * the colum index in [0..3]
- * @return the element value
- */
- float getRowColumn(int row, int column);
-
- /**
- * Compute a normal matrix from the upper left 3x3 submatrix of this
- * and store it into the upper left 3x3 submatrix of dest
.
- * All other values of dest
will be set to identity.
- * m
is the transpose of the inverse of m
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f normal(Matrix4f dest);
-
- /**
- * Compute a normal matrix from the upper left 3x3 submatrix of this
- * and store it into dest
.
- * m
is the transpose of the inverse of m
.
- *
- * @see Matrix3f#set(Matrix4fc)
- * @see #get3x3(Matrix3f)
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix3f normal(Matrix3f dest);
-
- /**
- * Compute the cofactor matrix of the upper left 3x3 submatrix of this
- * and store it into dest
.
- * this
- * and store it into dest
.
- * All other values of dest
will be set to identity.
- * dest
.
- * dest
.
- * this
matrix, which
- * can be a projection matrix or a combined modelview-projection matrix, and store the result
- * in the given planeEquation
.
- * this
- * transformation was applied to it in order to yield homogeneous clipping space.
- * a*x + b*y + c*z + d = 0
, where the given {@link Vector4f} components will
- * hold the (a, b, c, d)
values of the equation.
- * (a, b, c)
, is directed "inwards" of the frustum.
- * Any plane/point test using a*x + b*y + c*z + d
therefore will yield a result greater than zero
- * if the point is within the frustum (i.e. at the positive side of the frustum plane).
- * (a, b, c)
will be a unit vector
- * @return planeEquation
- */
- Vector4f frustumPlane(int plane, Vector4f planeEquation);
-
- /**
- * Compute the corner coordinates of the frustum defined by this
matrix, which
- * can be a projection matrix or a combined modelview-projection matrix, and store the result
- * in the given point
.
- * this
- * transformation was applied to it in order to yield homogeneous clipping space.
- * this
matrix,
- * which can be a projection matrix or a combined modelview-projection matrix, and store the result
- * in the given origin
.
- * this
- * transformation was applied to it in order to yield homogeneous clipping space.
- * invert(new Matrix4f()).transformProject(0, 0, -1, 0, origin)
- * and in the case of an already available inverse of this
matrix, the method {@link #perspectiveInvOrigin(Vector3f)}
- * on the inverse of the matrix should be used instead.
- * this
- * perspective projection transformation
- * @return origin
- */
- Vector3f perspectiveOrigin(Vector3f origin);
-
- /**
- * Compute the eye/origin of the inverse of the perspective frustum transformation defined by this
matrix,
- * which can be the inverse of a projection matrix or the inverse of a combined modelview-projection matrix, and store the result
- * in the given dest
.
- * 0.0
.
- * this
perspective projection matrix.
- * this
is a perspective projection matrix, for example obtained via {@link #perspective(float, float, float, float, Matrix4f)}.
- *
- * @return the near clip plane distance
- */
- float perspectiveNear();
-
- /**
- * Extract the far clip plane distance from this
perspective projection matrix.
- * this
is a perspective projection matrix, for example obtained via {@link #perspective(float, float, float, float, Matrix4f)}.
- *
- * @return the far clip plane distance
- */
- float perspectiveFar();
-
- /**
- * Obtain the direction of a ray starting at the center of the coordinate system and going
- * through the near frustum plane.
- * dir
vector in the local frame of
- * any coordinate system that existed before this
- * transformation was applied to it in order to yield homogeneous clipping space.
- * x
and y
are used to interpolate the generated ray direction
- * from the bottom-left to the top-right frustum corners.
- * (0, 0)
, (1, 0)
, (0, 1)
and (1, 1)
- * and then bilinearly interpolating between them; or to use the {@link FrustumRayBuilder}.
- * [0..1]
- * @param y
- * the interpolation factor along the bottom-to-top frustum planes, within [0..1]
- * @param dir
- * will hold the normalized ray direction in the local frame of the coordinate system before
- * transforming to homogeneous clipping space using this
matrix
- * @return dir
- */
- Vector3f frustumRayDir(float x, float y, Vector3f dir);
-
- /**
- * Obtain the direction of +Z
before the transformation represented by this
matrix is applied.
- * +Z
by this
matrix.
- *
- * Matrix4f inv = new Matrix4f(this).invert();
- * inv.transformDirection(dir.set(0, 0, 1)).normalize();
- *
- * If this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveZ(Vector3f)} instead.
- * +Z
- * @return dir
- */
- Vector3f positiveZ(Vector3f dir);
-
- /**
- * Obtain the direction of +Z
before the transformation represented by this
orthogonal matrix is applied.
- * This method only produces correct results if this
is an orthogonal matrix.
- * +Z
by this
matrix.
- *
- * Matrix4f inv = new Matrix4f(this).transpose();
- * inv.transformDirection(dir.set(0, 0, 1));
- *
- * +Z
- * @return dir
- */
- Vector3f normalizedPositiveZ(Vector3f dir);
-
- /**
- * Obtain the direction of +X
before the transformation represented by this
matrix is applied.
- * +X
by this
matrix.
- *
- * Matrix4f inv = new Matrix4f(this).invert();
- * inv.transformDirection(dir.set(1, 0, 0)).normalize();
- *
- * If this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveX(Vector3f)} instead.
- * +X
- * @return dir
- */
- Vector3f positiveX(Vector3f dir);
-
- /**
- * Obtain the direction of +X
before the transformation represented by this
orthogonal matrix is applied.
- * This method only produces correct results if this
is an orthogonal matrix.
- * +X
by this
matrix.
- *
- * Matrix4f inv = new Matrix4f(this).transpose();
- * inv.transformDirection(dir.set(1, 0, 0));
- *
- * +X
- * @return dir
- */
- Vector3f normalizedPositiveX(Vector3f dir);
-
- /**
- * Obtain the direction of +Y
before the transformation represented by this
matrix is applied.
- * +Y
by this
matrix.
- *
- * Matrix4f inv = new Matrix4f(this).invert();
- * inv.transformDirection(dir.set(0, 1, 0)).normalize();
- *
- * If this
is already an orthogonal matrix, then consider using {@link #normalizedPositiveY(Vector3f)} instead.
- * +Y
- * @return dir
- */
- Vector3f positiveY(Vector3f dir);
-
- /**
- * Obtain the direction of +Y
before the transformation represented by this
orthogonal matrix is applied.
- * This method only produces correct results if this
is an orthogonal matrix.
- * +Y
by this
matrix.
- *
- * Matrix4f inv = new Matrix4f(this).transpose();
- * inv.transformDirection(dir.set(0, 1, 0));
- *
- * +Y
- * @return dir
- */
- Vector3f normalizedPositiveY(Vector3f dir);
-
- /**
- * Obtain the position that gets transformed to the origin by this
{@link #isAffine() affine} matrix.
- * This can be used to get the position of the "camera" from a given view transformation matrix.
- *
- * Matrix4f inv = new Matrix4f(this).invertAffine();
- * inv.transformPosition(origin.set(0, 0, 0));
- *
- *
- * @param origin
- * will hold the position transformed to the origin
- * @return origin
- */
- Vector3f originAffine(Vector3f origin);
-
- /**
- * Obtain the position that gets transformed to the origin by this
matrix.
- * This can be used to get the position of the "camera" from a given view/projection transformation matrix.
- *
- * Matrix4f inv = new Matrix4f(this).invert();
- * inv.transformPosition(origin.set(0, 0, 0));
- *
- *
- * @param origin
- * will hold the position transformed to the origin
- * @return origin
- */
- Vector3f origin(Vector3f origin);
-
- /**
- * Apply a projection transformation to this matrix that projects onto the plane specified via the general plane equation
- * x*a + y*b + z*c + d = 0
as if casting a shadow from a given light position/direction light
- * and store the result in dest
.
- * light.w
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
- * M
is this
matrix and S
the shadow matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * shadow projection will be applied first!
- * x*a + y*b + z*c + d = 0
as if casting a shadow from a given light position/direction (lightX, lightY, lightZ, lightW)
- * and store the result in dest
.
- * lightW
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
- * M
is this
matrix and S
the shadow matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * shadow projection will be applied first!
- * y = 0
as if casting a shadow from a given light position/direction light
- * and store the result in dest
.
- * planeTransformation
.
- * light.w
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
- * M
is this
matrix and S
the shadow matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * shadow projection will be applied first!
- *
- * @param light
- * the light's vector
- * @param planeTransform
- * the transformation to transform the implied plane y = 0
before applying the projection
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f shadow(Vector4f light, Matrix4fc planeTransform, Matrix4f dest);
-
- /**
- * Apply a projection transformation to this matrix that projects onto the plane with the general plane equation
- * y = 0
as if casting a shadow from a given light position/direction (lightX, lightY, lightZ, lightW)
- * and store the result in dest
.
- * planeTransformation
.
- * lightW
is 0.0
the light is being treated as a directional light; if it is 1.0
it is a point light.
- * M
is this
matrix and S
the shadow matrix,
- * then the new matrix will be M * S
. So when transforming a
- * vector v
with the new matrix by using M * S * v
, the
- * shadow projection will be applied first!
- *
- * @param lightX
- * the x-component of the light vector
- * @param lightY
- * the y-component of the light vector
- * @param lightZ
- * the z-component of the light vector
- * @param lightW
- * the w-component of the light vector
- * @param planeTransform
- * the transformation to transform the implied plane y = 0
before applying the projection
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f shadow(float lightX, float lightY, float lightZ, float lightW, Matrix4fc planeTransform, Matrix4f dest);
-
- /**
- * Apply a picking transformation to this matrix using the given window coordinates (x, y)
as the pick center
- * and the given (width, height)
as the size of the picking region in window coordinates, and store the result
- * in dest
.
- *
- * @param x
- * the x coordinate of the picking region center in window coordinates
- * @param y
- * the y coordinate of the picking region center in window coordinates
- * @param width
- * the width of the picking region in window coordinates
- * @param height
- * the height of the picking region in window coordinates
- * @param viewport
- * the viewport described by [x, y, width, height]
- * @param dest
- * the destination matrix, which will hold the result
- * @return dest
- */
- Matrix4f pick(float x, float y, float width, float height, int[] viewport, Matrix4f dest);
-
- /**
- * Determine whether this matrix describes an affine transformation. This is the case iff its last row is equal to (0, 0, 0, 1)
.
- *
- * @return true
iff this matrix is affine; false
otherwise
- */
- boolean isAffine();
-
- /**
- * Apply an arcball view transformation to this matrix with the given radius
and center (centerX, centerY, centerZ)
- * position of the arcball and the specified X and Y rotation angles, and store the result in dest
.
- * translate(0, 0, -radius, dest).rotateX(angleX).rotateY(angleY).translate(-centerX, -centerY, -centerZ)
- *
- * @param radius
- * the arcball radius
- * @param centerX
- * the x coordinate of the center position of the arcball
- * @param centerY
- * the y coordinate of the center position of the arcball
- * @param centerZ
- * the z coordinate of the center position of the arcball
- * @param angleX
- * the rotation angle around the X axis in radians
- * @param angleY
- * the rotation angle around the Y axis in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f arcball(float radius, float centerX, float centerY, float centerZ, float angleX, float angleY, Matrix4f dest);
-
- /**
- * Apply an arcball view transformation to this matrix with the given radius
and center
- * position of the arcball and the specified X and Y rotation angles, and store the result in dest
.
- * translate(0, 0, -radius).rotateX(angleX).rotateY(angleY).translate(-center.x, -center.y, -center.z)
- *
- * @param radius
- * the arcball radius
- * @param center
- * the center position of the arcball
- * @param angleX
- * the rotation angle around the X axis in radians
- * @param angleY
- * the rotation angle around the Y axis in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f arcball(float radius, Vector3fc center, float angleX, float angleY, Matrix4f dest);
-
- /**
- * Compute the axis-aligned bounding box of the frustum described by this
matrix and store the minimum corner
- * coordinates in the given min
and the maximum corner coordinates in the given max
vector.
- * this
is assumed to be the {@link #invert(Matrix4f) inverse} of the origial view-projection matrix
- * for which to compute the axis-aligned bounding box in world-space.
- * (-1, -1, -1)
, (1, 1, 1)
.
- *
- * @param min
- * will hold the minimum corner coordinates of the axis-aligned bounding box
- * @param max
- * will hold the maximum corner coordinates of the axis-aligned bounding box
- * @return this
- */
- Matrix4f frustumAabb(Vector3f min, Vector3f max);
-
- /**
- * Compute the range matrix for the Projected Grid transformation as described in chapter "2.4.2 Creating the range conversion matrix"
- * of the paper Real-time water rendering - Introducing the projected grid concept
- * based on the inverse of the view-projection matrix which is assumed to be this
, and store that range matrix into dest
.
- * null
.
- * y = 0
plane for the projection.
- *
- * @param projector
- * the projector view-projection transformation
- * @param sLower
- * the lower (smallest) Y-coordinate which any transformed vertex might have while still being visible on the projected grid
- * @param sUpper
- * the upper (highest) Y-coordinate which any transformed vertex might have while still being visible on the projected grid
- * @param dest
- * will hold the resulting range matrix
- * @return the computed range matrix; or null
if the projected grid will not be visible
- */
- Matrix4f projectedGridRange(Matrix4fc projector, float sLower, float sUpper, Matrix4f dest);
-
- /**
- * Change the near and far clip plane distances of this
perspective frustum transformation matrix
- * and store the result in dest
.
- * this
is a perspective projection frustum transformation, for example obtained
- * via {@link #perspective(float, float, float, float, Matrix4f) perspective()} or {@link #frustum(float, float, float, float, float, float, Matrix4f) frustum()}.
- *
- * @see #perspective(float, float, float, float, Matrix4f)
- * @see #frustum(float, float, float, float, float, float, Matrix4f)
- *
- * @param near
- * the new near clip plane distance
- * @param far
- * the new far clip plane distance
- * @param dest
- * will hold the resulting matrix
- * @return dest
- */
- Matrix4f perspectiveFrustumSlice(float near, float far, Matrix4f dest);
-
- /**
- * Build an ortographic projection transformation that fits the view-projection transformation represented by this
- * into the given affine view
transformation.
- * this
must be given as the {@link #invert(Matrix4f) inverse} of a typical combined camera view-projection
- * transformation, whose projection can be either orthographic or perspective.
- * view
must be an {@link #isAffine() affine} transformation which in the application of Cascaded Shadow Maps is usually the light view transformation.
- * It be obtained via any affine transformation or for example via {@link #lookAt(float, float, float, float, float, float, float, float, float, Matrix4f) lookAt()}.
- * this
- * @param dest
- * will hold the crop projection transformation
- * @return dest
- */
- Matrix4f orthoCrop(Matrix4fc view, Matrix4f dest);
-
- /**
- * Transform the axis-aligned box given as the minimum corner (minX, minY, minZ)
and maximum corner (maxX, maxY, maxZ)
- * by this
{@link #isAffine() affine} matrix and compute the axis-aligned box of the result whose minimum corner is stored in outMin
- * and maximum corner stored in outMax
.
- * min
and maximum corner max
- * by this
{@link #isAffine() affine} matrix and compute the axis-aligned box of the result whose minimum corner is stored in outMin
- * and maximum corner stored in outMax
.
- *
- * @param min
- * the minimum corner of the axis-aligned box
- * @param max
- * the maximum corner of the axis-aligned box
- * @param outMin
- * will hold the minimum corner of the resulting axis-aligned box
- * @param outMax
- * will hold the maximum corner of the resulting axis-aligned box
- * @return this
- */
- Matrix4f transformAab(Vector3fc min, Vector3fc max, Vector3f outMin, Vector3f outMax);
-
- /**
- * Linearly interpolate this
and other
using the given interpolation factor t
- * and store the result in dest
.
- * t
is 0.0
then the result is this
. If the interpolation factor is 1.0
- * then the result is other
.
- *
- * @param other
- * the other matrix
- * @param t
- * the interpolation factor between 0.0 and 1.0
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f lerp(Matrix4fc other, float t, Matrix4f dest);
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with dir
- * and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mulAffine(new Matrix4f().lookAt(new Vector3f(), new Vector3f(dir).negate(), up).invertAffine(), dest)
- *
- * @see #rotateTowards(float, float, float, float, float, float, Matrix4f)
- *
- * @param dir
- * the direction to rotate towards
- * @param up
- * the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateTowards(Vector3fc dir, Vector3fc up, Matrix4f dest);
-
- /**
- * Apply a model transformation to this matrix for a right-handed coordinate system,
- * that aligns the local +Z
axis with (dirX, dirY, dirZ)
- * and store the result in dest
.
- * M
is this
matrix and L
the lookat matrix,
- * then the new matrix will be M * L
. So when transforming a
- * vector v
with the new matrix by using M * L * v
,
- * the lookat transformation will be applied first!
- * mulAffine(new Matrix4f().lookAt(0, 0, 0, -dirX, -dirY, -dirZ, upX, upY, upZ).invertAffine(), dest)
- *
- * @see #rotateTowards(Vector3fc, Vector3fc, Matrix4f)
- *
- * @param dirX
- * the x-coordinate of the direction to rotate towards
- * @param dirY
- * the y-coordinate of the direction to rotate towards
- * @param dirZ
- * the z-coordinate of the direction to rotate towards
- * @param upX
- * the x-coordinate of the up vector
- * @param upY
- * the y-coordinate of the up vector
- * @param upZ
- * the z-coordinate of the up vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f rotateTowards(float dirX, float dirY, float dirZ, float upX, float upY, float upZ, Matrix4f dest);
-
- /**
- * Extract the Euler angles from the rotation represented by the upper left 3x3 submatrix of this
- * and store the extracted Euler angles in dest
.
- * this
only represents a rotation without scaling.
- * X * Y * Z
to obtain the identical matrix.
- * This means that calling {@link Matrix4fc#rotateXYZ(float, float, float, Matrix4f)} using the obtained Euler angles will yield
- * the same rotation as the original matrix from which the Euler angles were obtained, so in the below code the matrix
- * m2
should be identical to m
(disregarding possible floating-point inaccuracies).
- *
- * Matrix4f m = ...; // <- matrix only representing rotation
- * Matrix4f n = new Matrix4f();
- * n.rotateXYZ(m.getEulerAnglesXYZ(new Vector3f()));
- *
- * this
- * and store the extracted Euler angles in dest
.
- * this
only represents a rotation without scaling.
- * Z * Y * X
to obtain the identical matrix.
- * This means that calling {@link Matrix4fc#rotateZYX(float, float, float, Matrix4f)} using the obtained Euler angles will yield
- * the same rotation as the original matrix from which the Euler angles were obtained, so in the below code the matrix
- * m2
should be identical to m
(disregarding possible floating-point inaccuracies).
- *
- * Matrix4f m = ...; // <- matrix only representing rotation
- * Matrix4f n = new Matrix4f();
- * n.rotateZYX(m.getEulerAnglesZYX(new Vector3f()));
- *
- * (x, y, z)
is within the frustum defined by this
matrix.
- * this
matrix to be a transformation from any arbitrary coordinate system/space M
- * into standard OpenGL clip space and tests whether the given point with the coordinates (x, y, z)
given
- * in space M
is within the clip space.
- * true
if the given point is inside the frustum; false
otherwise
- */
- boolean testPoint(float x, float y, float z);
-
- /**
- * Test whether the given sphere is partly or completely within or outside of the frustum defined by this
matrix.
- * this
matrix to be a transformation from any arbitrary coordinate system/space M
- * into standard OpenGL clip space and tests whether the given sphere with the coordinates (x, y, z)
given
- * in space M
is within the clip space.
- * true
for spheres that are actually not visible.
- * See iquilezles.org for an examination of this problem.
- * true
if the given sphere is partly or completely inside the frustum; false
otherwise
- */
- boolean testSphere(float x, float y, float z, float r);
-
- /**
- * Test whether the given axis-aligned box is partly or completely within or outside of the frustum defined by this
matrix.
- * The box is specified via its min and max corner coordinates.
- * this
matrix to be a transformation from any arbitrary coordinate system/space M
- * into standard OpenGL clip space and tests whether the given axis-aligned box with its minimum corner coordinates (minX, minY, minZ)
- * and maximum corner coordinates (maxX, maxY, maxZ)
given in space M
is within the clip space.
- * -1
for boxes that are actually not visible/do not intersect the frustum.
- * See iquilezles.org for an examination of this problem.
- *
- * Reference:
- * Fast Extraction of Viewing Frustum Planes from the World-View-Projection Matrix
- *
- * @param minX
- * the x-coordinate of the minimum corner
- * @param minY
- * the y-coordinate of the minimum corner
- * @param minZ
- * the z-coordinate of the minimum corner
- * @param maxX
- * the x-coordinate of the maximum corner
- * @param maxY
- * the y-coordinate of the maximum corner
- * @param maxZ
- * the z-coordinate of the maximum corner
- * @return true
if the axis-aligned box is completely or partly inside of the frustum; false
otherwise
- */
- boolean testAab(float minX, float minY, float minZ, float maxX, float maxY, float maxZ);
-
- /**
- * Apply an oblique projection transformation to this matrix with the given values for a
and
- * b
and store the result in dest
.
- * M
is this
matrix and O
the oblique transformation matrix,
- * then the new matrix will be M * O
. So when transforming a
- * vector v
with the new matrix by using M * O * v
, the
- * oblique transformation will be applied first!
- *
- * x' = x + a*z
- * y' = y + a*z
- * z' = z
- *
- * or in matrix form:
- *
- * 1 0 a 0
- * 0 1 b 0
- * 0 0 1 0
- * 0 0 0 1
- *
- *
- * @param a
- * the value for the z factor that applies to x
- * @param b
- * the value for the z factor that applies to y
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f obliqueZ(float a, float b, Matrix4f dest);
-
- /**
- * Apply a transformation to this matrix to ensure that the local Y axis (as obtained by {@link #positiveY(Vector3f)})
- * will be coplanar to the plane spanned by the local Z axis (as obtained by {@link #positiveZ(Vector3f)}) and the
- * given vector up
, and store the result in dest
.
- * up
.
- * (upX, upY, upZ)
, and store the result in dest
.
- * (upX, upY, upZ)
.
- * this
by the matrix
- *
- * 1 0 0 0
- * 0 0 1 0
- * 0 1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapXZY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 0 -1 0
- * 0 1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapXZnY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 -1 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapXnYnZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 0 1 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapXnZY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 0 -1 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapXnZnY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 1 0 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapYXZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 1 0 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapYXnZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 1 0 0 0
- * 0 1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapYZX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 1 0 0 0
- * 0 1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapYZnX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 1 0 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapYnXZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 1 0 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapYnXnZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 1 0 0 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapYnZX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 1 0 0 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapYnZnX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 0 0 1 0
- * 1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapZXY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 0 0 -1 0
- * 1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapZXnY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 0 1 0 0
- * 1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapZYX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 0 1 0 0
- * 1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapZYnX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 0 0 1 0
- * 1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapZnXY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 0 0 -1 0
- * 1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapZnXnY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 0 -1 0 0
- * 1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapZnYX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 0 -1 0 0
- * 1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapZnYnX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 1 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnXYnZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 0 1 0
- * 0 1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnXZY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 0 -1 0
- * 0 1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnXZnY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 -1 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnXnYZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 -1 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnXnYnZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 0 1 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnXnZY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 0 -1 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnXnZnY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * -1 0 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnYXZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * -1 0 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnYXnZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * -1 0 0 0
- * 0 1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnYZX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * -1 0 0 0
- * 0 1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnYZnX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * -1 0 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnYnXZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * -1 0 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnYnXnZ(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * -1 0 0 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnYnZX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * -1 0 0 0
- * 0 -1 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnYnZnX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 0 0 1 0
- * -1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnZXY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 1 0 0
- * 0 0 -1 0
- * -1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnZXnY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 0 1 0 0
- * -1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnZYX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 0 1 0 0
- * -1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnZYnX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 0 0 1 0
- * -1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnZnXY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 -1 0 0
- * 0 0 -1 0
- * -1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnZnXnY(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 1 0
- * 0 -1 0 0
- * -1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnZnYX(Matrix4f dest);
- /**
- * Multiply this
by the matrix
- *
- * 0 0 -1 0
- * 0 -1 0 0
- * -1 0 0 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f mapnZnYnX(Matrix4f dest);
-
- /**
- * Multiply this
by the matrix
- *
- * -1 0 0 0
- * 0 1 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f negateX(Matrix4f dest);
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 -1 0 0
- * 0 0 1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f negateY(Matrix4f dest);
-
- /**
- * Multiply this
by the matrix
- *
- * 1 0 0 0
- * 0 1 0 0
- * 0 0 -1 0
- * 0 0 0 1
- *
- * and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Matrix4f negateZ(Matrix4f dest);
-
- /**
- * Compare the matrix elements of this
matrix with the given matrix using the given delta
- * and return whether all of them are equal within a maximum difference of delta
.
- * true
whether all of the matrix elements are equal; false
otherwise
- */
- boolean equals(Matrix4fc m, float delta);
-
- /**
- * Determine whether all matrix elements are finite floating-point values, that
- * is, they are not {@link Float#isNaN() NaN} and not
- * {@link Float#isInfinite() infinity}.
- *
- * @return {@code true} if all components are finite floating-point values;
- * {@code false} otherwise
- */
- boolean isFinite();
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/MemUtil.java b/src/main/java/com/jozufozu/flywheel/util/joml/MemUtil.java
deleted file mode 100644
index 3f88b030f..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/MemUtil.java
+++ /dev/null
@@ -1,2034 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2016-2021 Kai Burjack
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.lang.reflect.Field;
-import java.nio.*;
-
-/**
- * Helper class to do efficient memory operations on all JOML objects, NIO buffers and primitive arrays.
- * This class is used internally throughout JOML, is undocumented and is subject to change.
- * Use with extreme caution!
- *
- * @author The LWJGL authors
- * @author Kai Burjack
- */
-abstract class MemUtil {
- public static final MemUtil INSTANCE = createInstance();
- private static MemUtil createInstance() {
- MemUtil accessor;
- try {
- if (Options.NO_UNSAFE && Options.FORCE_UNSAFE)
- throw new ConfigurationException("Cannot enable both -Djoml.nounsafe and -Djoml.forceUnsafe", null);
- else if (Options.NO_UNSAFE)
- accessor = new MemUtilNIO();
- else
- accessor = new MemUtilUnsafe();
- } catch (Throwable e) {
- if (Options.FORCE_UNSAFE)
- throw new ConfigurationException("Unsafe is not supported but its use was forced via -Djoml.forceUnsafe", e);
- accessor = new MemUtilNIO();
- }
- return accessor;
- }
-
- public abstract void put(Matrix4f m, int offset, FloatBuffer dest);
- public abstract void put(Matrix4f m, int offset, ByteBuffer dest);
- public abstract void put4x3(Matrix4f m, int offset, FloatBuffer dest);
- public abstract void put4x3(Matrix4f m, int offset, ByteBuffer dest);
- public abstract void put3x4(Matrix4f m, int offset, FloatBuffer dest);
- public abstract void put3x4(Matrix4f m, int offset, ByteBuffer dest);
- public abstract void put3x4(Matrix3f m, int offset, FloatBuffer dest);
- public abstract void put3x4(Matrix3f m, int offset, ByteBuffer dest);
- public abstract void putTransposed(Matrix4f m, int offset, FloatBuffer dest);
- public abstract void putTransposed(Matrix4f m, int offset, ByteBuffer dest);
- public abstract void put4x3Transposed(Matrix4f m, int offset, FloatBuffer dest);
- public abstract void put4x3Transposed(Matrix4f m, int offset, ByteBuffer dest);
- public abstract void putTransposed(Matrix3f m, int offset, FloatBuffer dest);
- public abstract void putTransposed(Matrix3f m, int offset, ByteBuffer dest);
- public abstract void put(Matrix3f m, int offset, FloatBuffer dest);
- public abstract void put(Matrix3f m, int offset, ByteBuffer dest);
- public abstract void put(Vector4f src, int offset, FloatBuffer dest);
- public abstract void put(Vector4f src, int offset, ByteBuffer dest);
- public abstract void put(Vector3f src, int offset, FloatBuffer dest);
- public abstract void put(Vector3f src, int offset, ByteBuffer dest);
- public abstract void get(Matrix4f m, int offset, FloatBuffer src);
- public abstract void get(Matrix4f m, int offset, ByteBuffer src);
- public abstract void getTransposed(Matrix4f m, int offset, FloatBuffer src);
- public abstract void getTransposed(Matrix4f m, int offset, ByteBuffer src);
- public abstract void get(Matrix3f m, int offset, FloatBuffer src);
- public abstract void get(Matrix3f m, int offset, ByteBuffer src);
- public abstract void get(Vector4f dst, int offset, FloatBuffer src);
- public abstract void get(Vector4f dst, int offset, ByteBuffer src);
- public abstract void get(Vector3f dst, int offset, FloatBuffer src);
- public abstract void get(Vector3f dst, int offset, ByteBuffer src);
- public abstract void putMatrix3f(Quaternionf q, int position, ByteBuffer dest);
- public abstract void putMatrix3f(Quaternionf q, int position, FloatBuffer dest);
- public abstract void putMatrix4f(Quaternionf q, int position, ByteBuffer dest);
- public abstract void putMatrix4f(Quaternionf q, int position, FloatBuffer dest);
- public abstract void putMatrix4x3f(Quaternionf q, int position, ByteBuffer dest);
- public abstract void putMatrix4x3f(Quaternionf q, int position, FloatBuffer dest);
-
- public abstract float get(Matrix4f m, int column, int row);
- public abstract Matrix4f set(Matrix4f m, int column, int row, float v);
- public abstract float get(Matrix3f m, int column, int row);
- public abstract Matrix3f set(Matrix3f m, int column, int row, float v);
- public abstract Vector4f getColumn(Matrix4f m, int column, Vector4f dest);
- public abstract Matrix4f setColumn(Vector4f v, int column, Matrix4f dest);
- public abstract Matrix4f setColumn(Vector4fc v, int column, Matrix4f dest);
- public abstract void copy(Matrix4f src, Matrix4f dest);
- public abstract void copy(Matrix3f src, Matrix3f dest);
- public abstract void copy(Matrix3f src, Matrix4f dest);
- public abstract void copy(Matrix4f src, Matrix3f dest);
- public abstract void copy3x3(Matrix4f src, Matrix4f dest);
- public abstract void copy3x3(Matrix3f src, Matrix4f dest);
- public abstract void copy4x3(Matrix4f src, Matrix4f dest);
- public abstract void copy(float[] arr, int off, Matrix4f dest);
- public abstract void copyTransposed(float[] arr, int off, Matrix4f dest);
- public abstract void copy(float[] arr, int off, Matrix3f dest);
- public abstract void copy(Matrix4f src, float[] dest, int off);
- public abstract void copy(Matrix3f src, float[] dest, int off);
-
- public abstract void identity(Matrix4f dest);
-
- public abstract void identity(Matrix3f dest);
-
- public abstract void swap(Matrix4f m1, Matrix4f m2);
-
- public abstract void swap(Matrix3f m1, Matrix3f m2);
-
- public abstract void zero(Matrix4f dest);
-
- public abstract void zero(Matrix3f dest);
-
- public static class MemUtilNIO extends MemUtil {
- public void put0(Matrix4f m, FloatBuffer dest) {
- dest.put(0, m.m00())
- .put(1, m.m01())
- .put(2, m.m02())
- .put(3, m.m03())
- .put(4, m.m10())
- .put(5, m.m11())
- .put(6, m.m12())
- .put(7, m.m13())
- .put(8, m.m20())
- .put(9, m.m21())
- .put(10, m.m22())
- .put(11, m.m23())
- .put(12, m.m30())
- .put(13, m.m31())
- .put(14, m.m32())
- .put(15, m.m33());
- }
- public void putN(Matrix4f m, int offset, FloatBuffer dest) {
- dest.put(offset, m.m00())
- .put(offset+1, m.m01())
- .put(offset+2, m.m02())
- .put(offset+3, m.m03())
- .put(offset+4, m.m10())
- .put(offset+5, m.m11())
- .put(offset+6, m.m12())
- .put(offset+7, m.m13())
- .put(offset+8, m.m20())
- .put(offset+9, m.m21())
- .put(offset+10, m.m22())
- .put(offset+11, m.m23())
- .put(offset+12, m.m30())
- .put(offset+13, m.m31())
- .put(offset+14, m.m32())
- .put(offset+15, m.m33());
- }
- public void put(Matrix4f m, int offset, FloatBuffer dest) {
- if (offset == 0)
- put0(m, dest);
- else
- putN(m, offset, dest);
- }
-
- public void put0(Matrix4f m, ByteBuffer dest) {
- dest.putFloat(0, m.m00())
- .putFloat(4, m.m01())
- .putFloat(8, m.m02())
- .putFloat(12, m.m03())
- .putFloat(16, m.m10())
- .putFloat(20, m.m11())
- .putFloat(24, m.m12())
- .putFloat(28, m.m13())
- .putFloat(32, m.m20())
- .putFloat(36, m.m21())
- .putFloat(40, m.m22())
- .putFloat(44, m.m23())
- .putFloat(48, m.m30())
- .putFloat(52, m.m31())
- .putFloat(56, m.m32())
- .putFloat(60, m.m33());
- }
- private void putN(Matrix4f m, int offset, ByteBuffer dest) {
- dest.putFloat(offset, m.m00())
- .putFloat(offset+4, m.m01())
- .putFloat(offset+8, m.m02())
- .putFloat(offset+12, m.m03())
- .putFloat(offset+16, m.m10())
- .putFloat(offset+20, m.m11())
- .putFloat(offset+24, m.m12())
- .putFloat(offset+28, m.m13())
- .putFloat(offset+32, m.m20())
- .putFloat(offset+36, m.m21())
- .putFloat(offset+40, m.m22())
- .putFloat(offset+44, m.m23())
- .putFloat(offset+48, m.m30())
- .putFloat(offset+52, m.m31())
- .putFloat(offset+56, m.m32())
- .putFloat(offset+60, m.m33());
- }
- public void put(Matrix4f m, int offset, ByteBuffer dest) {
- if (offset == 0)
- put0(m, dest);
- else
- putN(m, offset, dest);
- }
-
- public void put4x3_0(Matrix4f m, FloatBuffer dest) {
- dest.put(0, m.m00())
- .put(1, m.m01())
- .put(2, m.m02())
- .put(3, m.m10())
- .put(4, m.m11())
- .put(5, m.m12())
- .put(6, m.m20())
- .put(7, m.m21())
- .put(8, m.m22())
- .put(9, m.m30())
- .put(10, m.m31())
- .put(11, m.m32());
- }
- public void put4x3_N(Matrix4f m, int offset, FloatBuffer dest) {
- dest.put(offset, m.m00())
- .put(offset+1, m.m01())
- .put(offset+2, m.m02())
- .put(offset+3, m.m10())
- .put(offset+4, m.m11())
- .put(offset+5, m.m12())
- .put(offset+6, m.m20())
- .put(offset+7, m.m21())
- .put(offset+8, m.m22())
- .put(offset+9, m.m30())
- .put(offset+10, m.m31())
- .put(offset+11, m.m32());
- }
- public void put4x3(Matrix4f m, int offset, FloatBuffer dest) {
- if (offset == 0)
- put4x3_0(m, dest);
- else
- put4x3_N(m, offset, dest);
- }
-
- public void put4x3_0(Matrix4f m, ByteBuffer dest) {
- dest.putFloat(0, m.m00())
- .putFloat(4, m.m01())
- .putFloat(8, m.m02())
- .putFloat(12, m.m10())
- .putFloat(16, m.m11())
- .putFloat(20, m.m12())
- .putFloat(24, m.m20())
- .putFloat(28, m.m21())
- .putFloat(32, m.m22())
- .putFloat(36, m.m30())
- .putFloat(40, m.m31())
- .putFloat(44, m.m32());
- }
- private void put4x3_N(Matrix4f m, int offset, ByteBuffer dest) {
- dest.putFloat(offset, m.m00())
- .putFloat(offset+4, m.m01())
- .putFloat(offset+8, m.m02())
- .putFloat(offset+12, m.m10())
- .putFloat(offset+16, m.m11())
- .putFloat(offset+20, m.m12())
- .putFloat(offset+24, m.m20())
- .putFloat(offset+28, m.m21())
- .putFloat(offset+32, m.m22())
- .putFloat(offset+36, m.m30())
- .putFloat(offset+40, m.m31())
- .putFloat(offset+44, m.m32());
- }
- public void put4x3(Matrix4f m, int offset, ByteBuffer dest) {
- if (offset == 0)
- put4x3_0(m, dest);
- else
- put4x3_N(m, offset, dest);
- }
-
- public void put3x4_0(Matrix4f m, ByteBuffer dest) {
- dest.putFloat(0, m.m00())
- .putFloat(4, m.m01())
- .putFloat(8, m.m02())
- .putFloat(12, m.m03())
- .putFloat(16, m.m10())
- .putFloat(20, m.m11())
- .putFloat(24, m.m12())
- .putFloat(28, m.m13())
- .putFloat(32, m.m20())
- .putFloat(36, m.m21())
- .putFloat(40, m.m22())
- .putFloat(44, m.m23());
- }
- private void put3x4_N(Matrix4f m, int offset, ByteBuffer dest) {
- dest.putFloat(offset, m.m00())
- .putFloat(offset+4, m.m01())
- .putFloat(offset+8, m.m02())
- .putFloat(offset+12, m.m03())
- .putFloat(offset+16, m.m10())
- .putFloat(offset+20, m.m11())
- .putFloat(offset+24, m.m12())
- .putFloat(offset+28, m.m13())
- .putFloat(offset+32, m.m20())
- .putFloat(offset+36, m.m21())
- .putFloat(offset+40, m.m22())
- .putFloat(offset+44, m.m23());
- }
- public void put3x4(Matrix4f m, int offset, ByteBuffer dest) {
- if (offset == 0)
- put3x4_0(m, dest);
- else
- put3x4_N(m, offset, dest);
- }
-
- public void put3x4_0(Matrix4f m, FloatBuffer dest) {
- dest.put(0, m.m00())
- .put(1, m.m01())
- .put(2, m.m02())
- .put(3, m.m03())
- .put(4, m.m10())
- .put(5, m.m11())
- .put(6, m.m12())
- .put(7, m.m13())
- .put(8, m.m20())
- .put(9, m.m21())
- .put(10, m.m22())
- .put(11, m.m23());
- }
- public void put3x4_N(Matrix4f m, int offset, FloatBuffer dest) {
- dest.put(offset, m.m00())
- .put(offset+1, m.m01())
- .put(offset+2, m.m02())
- .put(offset+3, m.m03())
- .put(offset+4, m.m10())
- .put(offset+5, m.m11())
- .put(offset+6, m.m12())
- .put(offset+7, m.m13())
- .put(offset+8, m.m20())
- .put(offset+9, m.m21())
- .put(offset+10, m.m22())
- .put(offset+11, m.m23());
- }
- public void put3x4(Matrix4f m, int offset, FloatBuffer dest) {
- if (offset == 0)
- put3x4_0(m, dest);
- else
- put3x4_N(m, offset, dest);
- }
-
- private void putTransposedN(Matrix4f m, int offset, FloatBuffer dest) {
- dest.put(offset, m.m00())
- .put(offset+1, m.m10())
- .put(offset+2, m.m20())
- .put(offset+3, m.m30())
- .put(offset+4, m.m01())
- .put(offset+5, m.m11())
- .put(offset+6, m.m21())
- .put(offset+7, m.m31())
- .put(offset+8, m.m02())
- .put(offset+9, m.m12())
- .put(offset+10, m.m22())
- .put(offset+11, m.m32())
- .put(offset+12, m.m03())
- .put(offset+13, m.m13())
- .put(offset+14, m.m23())
- .put(offset+15, m.m33());
- }
- private void putTransposed0(Matrix4f m, FloatBuffer dest) {
- dest.put(0, m.m00())
- .put(1, m.m10())
- .put(2, m.m20())
- .put(3, m.m30())
- .put(4, m.m01())
- .put(5, m.m11())
- .put(6, m.m21())
- .put(7, m.m31())
- .put(8, m.m02())
- .put(9, m.m12())
- .put(10, m.m22())
- .put(11, m.m32())
- .put(12, m.m03())
- .put(13, m.m13())
- .put(14, m.m23())
- .put(15, m.m33());
- }
- public void putTransposed(Matrix4f m, int offset, FloatBuffer dest) {
- if (offset == 0)
- putTransposed0(m, dest);
- else
- putTransposedN(m, offset, dest);
- }
-
- private void putTransposedN(Matrix4f m, int offset, ByteBuffer dest) {
- dest.putFloat(offset, m.m00())
- .putFloat(offset+4, m.m10())
- .putFloat(offset+8, m.m20())
- .putFloat(offset+12, m.m30())
- .putFloat(offset+16, m.m01())
- .putFloat(offset+20, m.m11())
- .putFloat(offset+24, m.m21())
- .putFloat(offset+28, m.m31())
- .putFloat(offset+32, m.m02())
- .putFloat(offset+36, m.m12())
- .putFloat(offset+40, m.m22())
- .putFloat(offset+44, m.m32())
- .putFloat(offset+48, m.m03())
- .putFloat(offset+52, m.m13())
- .putFloat(offset+56, m.m23())
- .putFloat(offset+60, m.m33());
- }
- private void putTransposed0(Matrix4f m, ByteBuffer dest) {
- dest.putFloat(0, m.m00())
- .putFloat(4, m.m10())
- .putFloat(8, m.m20())
- .putFloat(12, m.m30())
- .putFloat(16, m.m01())
- .putFloat(20, m.m11())
- .putFloat(24, m.m21())
- .putFloat(28, m.m31())
- .putFloat(32, m.m02())
- .putFloat(36, m.m12())
- .putFloat(40, m.m22())
- .putFloat(44, m.m32())
- .putFloat(48, m.m03())
- .putFloat(52, m.m13())
- .putFloat(56, m.m23())
- .putFloat(60, m.m33());
- }
- public void putTransposed(Matrix4f m, int offset, ByteBuffer dest) {
- if (offset == 0)
- putTransposed0(m, dest);
- else
- putTransposedN(m, offset, dest);
- }
-
- public void put4x3Transposed(Matrix4f m, int offset, FloatBuffer dest) {
- dest.put(offset, m.m00())
- .put(offset+1, m.m10())
- .put(offset+2, m.m20())
- .put(offset+3, m.m30())
- .put(offset+4, m.m01())
- .put(offset+5, m.m11())
- .put(offset+6, m.m21())
- .put(offset+7, m.m31())
- .put(offset+8, m.m02())
- .put(offset+9, m.m12())
- .put(offset+10, m.m22())
- .put(offset+11, m.m32());
- }
-
- public void put4x3Transposed(Matrix4f m, int offset, ByteBuffer dest) {
- dest.putFloat(offset, m.m00())
- .putFloat(offset+4, m.m10())
- .putFloat(offset+8, m.m20())
- .putFloat(offset+12, m.m30())
- .putFloat(offset+16, m.m01())
- .putFloat(offset+20, m.m11())
- .putFloat(offset+24, m.m21())
- .putFloat(offset+28, m.m31())
- .putFloat(offset+32, m.m02())
- .putFloat(offset+36, m.m12())
- .putFloat(offset+40, m.m22())
- .putFloat(offset+44, m.m32());
- }
-
- public void putTransposed(Matrix3f m, int offset, FloatBuffer dest) {
- dest.put(offset, m.m00())
- .put(offset+1, m.m10())
- .put(offset+2, m.m20())
- .put(offset+3, m.m01())
- .put(offset+4, m.m11())
- .put(offset+5, m.m21())
- .put(offset+6, m.m02())
- .put(offset+7, m.m12())
- .put(offset+8, m.m22());
- }
-
- public void putTransposed(Matrix3f m, int offset, ByteBuffer dest) {
- dest.putFloat(offset, m.m00())
- .putFloat(offset+4, m.m10())
- .putFloat(offset+8, m.m20())
- .putFloat(offset+12, m.m01())
- .putFloat(offset+16, m.m11())
- .putFloat(offset+20, m.m21())
- .putFloat(offset+24, m.m02())
- .putFloat(offset+28, m.m12())
- .putFloat(offset+32, m.m22());
- }
-
- public void put0(Matrix3f m, FloatBuffer dest) {
- dest.put(0, m.m00())
- .put(1, m.m01())
- .put(2, m.m02())
- .put(3, m.m10())
- .put(4, m.m11())
- .put(5, m.m12())
- .put(6, m.m20())
- .put(7, m.m21())
- .put(8, m.m22());
- }
- public void putN(Matrix3f m, int offset, FloatBuffer dest) {
- dest.put(offset, m.m00())
- .put(offset+1, m.m01())
- .put(offset+2, m.m02())
- .put(offset+3, m.m10())
- .put(offset+4, m.m11())
- .put(offset+5, m.m12())
- .put(offset+6, m.m20())
- .put(offset+7, m.m21())
- .put(offset+8, m.m22());
- }
- public void put(Matrix3f m, int offset, FloatBuffer dest) {
- if (offset == 0)
- put0(m, dest);
- else
- putN(m, offset, dest);
- }
-
- public void put0(Matrix3f m, ByteBuffer dest) {
- dest.putFloat(0, m.m00())
- .putFloat(4, m.m01())
- .putFloat(8, m.m02())
- .putFloat(12, m.m10())
- .putFloat(16, m.m11())
- .putFloat(20, m.m12())
- .putFloat(24, m.m20())
- .putFloat(28, m.m21())
- .putFloat(32, m.m22());
- }
- public void putN(Matrix3f m, int offset, ByteBuffer dest) {
- dest.putFloat(offset, m.m00())
- .putFloat(offset+4, m.m01())
- .putFloat(offset+8, m.m02())
- .putFloat(offset+12, m.m10())
- .putFloat(offset+16, m.m11())
- .putFloat(offset+20, m.m12())
- .putFloat(offset+24, m.m20())
- .putFloat(offset+28, m.m21())
- .putFloat(offset+32, m.m22());
- }
- public void put(Matrix3f m, int offset, ByteBuffer dest) {
- if (offset == 0)
- put0(m, dest);
- else
- putN(m, offset, dest);
- }
-
- public void put3x4_0(Matrix3f m, ByteBuffer dest) {
- dest.putFloat(0, m.m00())
- .putFloat(4, m.m01())
- .putFloat(8, m.m02())
- .putFloat(12, 0.0f)
- .putFloat(16, m.m10())
- .putFloat(20, m.m11())
- .putFloat(24, m.m12())
- .putFloat(28, 0.0f)
- .putFloat(32, m.m20())
- .putFloat(36, m.m21())
- .putFloat(40, m.m22())
- .putFloat(44, 0.0f);
- }
- private void put3x4_N(Matrix3f m, int offset, ByteBuffer dest) {
- dest.putFloat(offset, m.m00())
- .putFloat(offset+4, m.m01())
- .putFloat(offset+8, m.m02())
- .putFloat(offset+12, 0.0f)
- .putFloat(offset+16, m.m10())
- .putFloat(offset+20, m.m11())
- .putFloat(offset+24, m.m12())
- .putFloat(offset+28, 0.0f)
- .putFloat(offset+32, m.m20())
- .putFloat(offset+36, m.m21())
- .putFloat(offset+40, m.m22())
- .putFloat(offset+44, 0.0f);
- }
- public void put3x4(Matrix3f m, int offset, ByteBuffer dest) {
- if (offset == 0)
- put3x4_0(m, dest);
- else
- put3x4_N(m, offset, dest);
- }
-
- public void put3x4_0(Matrix3f m, FloatBuffer dest) {
- dest.put(0, m.m00())
- .put(1, m.m01())
- .put(2, m.m02())
- .put(3, 0.0f)
- .put(4, m.m10())
- .put(5, m.m11())
- .put(6, m.m12())
- .put(7, 0.0f)
- .put(8, m.m20())
- .put(9, m.m21())
- .put(10, m.m22())
- .put(11, 0.0f);
- }
- public void put3x4_N(Matrix3f m, int offset, FloatBuffer dest) {
- dest.put(offset, m.m00())
- .put(offset+1, m.m01())
- .put(offset+2, m.m02())
- .put(offset+3, 0.0f)
- .put(offset+4, m.m10())
- .put(offset+5, m.m11())
- .put(offset+6, m.m12())
- .put(offset+7, 0.0f)
- .put(offset+8, m.m20())
- .put(offset+9, m.m21())
- .put(offset+10, m.m22())
- .put(offset+11, 0.0f);
- }
- public void put3x4(Matrix3f m, int offset, FloatBuffer dest) {
- if (offset == 0)
- put3x4_0(m, dest);
- else
- put3x4_N(m, offset, dest);
- }
-
- public void put(Vector4f src, int offset, FloatBuffer dest) {
- dest.put(offset, src.x)
- .put(offset+1, src.y)
- .put(offset+2, src.z)
- .put(offset+3, src.w);
- }
-
- public void put(Vector4f src, int offset, ByteBuffer dest) {
- dest.putFloat(offset, src.x)
- .putFloat(offset+4, src.y)
- .putFloat(offset+8, src.z)
- .putFloat(offset+12, src.w);
- }
-
- public void put(Vector3f src, int offset, FloatBuffer dest) {
- dest.put(offset, src.x)
- .put(offset+1, src.y)
- .put(offset+2, src.z);
- }
-
- public void put(Vector3f src, int offset, ByteBuffer dest) {
- dest.putFloat(offset, src.x)
- .putFloat(offset+4, src.y)
- .putFloat(offset+8, src.z);
- }
-
- public void get(Matrix4f m, int offset, FloatBuffer src) {
- m._m00(src.get(offset))
- ._m01(src.get(offset+1))
- ._m02(src.get(offset+2))
- ._m03(src.get(offset+3))
- ._m10(src.get(offset+4))
- ._m11(src.get(offset+5))
- ._m12(src.get(offset+6))
- ._m13(src.get(offset+7))
- ._m20(src.get(offset+8))
- ._m21(src.get(offset+9))
- ._m22(src.get(offset+10))
- ._m23(src.get(offset+11))
- ._m30(src.get(offset+12))
- ._m31(src.get(offset+13))
- ._m32(src.get(offset+14))
- ._m33(src.get(offset+15));
- }
-
- public void get(Matrix4f m, int offset, ByteBuffer src) {
- m._m00(src.getFloat(offset))
- ._m01(src.getFloat(offset+4))
- ._m02(src.getFloat(offset+8))
- ._m03(src.getFloat(offset+12))
- ._m10(src.getFloat(offset+16))
- ._m11(src.getFloat(offset+20))
- ._m12(src.getFloat(offset+24))
- ._m13(src.getFloat(offset+28))
- ._m20(src.getFloat(offset+32))
- ._m21(src.getFloat(offset+36))
- ._m22(src.getFloat(offset+40))
- ._m23(src.getFloat(offset+44))
- ._m30(src.getFloat(offset+48))
- ._m31(src.getFloat(offset+52))
- ._m32(src.getFloat(offset+56))
- ._m33(src.getFloat(offset+60));
- }
-
- public void getTransposed(Matrix4f m, int offset, FloatBuffer src) {
- m._m00(src.get(offset))
- ._m10(src.get(offset+1))
- ._m20(src.get(offset+2))
- ._m30(src.get(offset+3))
- ._m01(src.get(offset+4))
- ._m11(src.get(offset+5))
- ._m21(src.get(offset+6))
- ._m31(src.get(offset+7))
- ._m02(src.get(offset+8))
- ._m12(src.get(offset+9))
- ._m22(src.get(offset+10))
- ._m32(src.get(offset+11))
- ._m03(src.get(offset+12))
- ._m13(src.get(offset+13))
- ._m23(src.get(offset+14))
- ._m33(src.get(offset+15));
- }
-
- public void getTransposed(Matrix4f m, int offset, ByteBuffer src) {
- m._m00(src.getFloat(offset))
- ._m10(src.getFloat(offset+4))
- ._m20(src.getFloat(offset+8))
- ._m30(src.getFloat(offset+12))
- ._m01(src.getFloat(offset+16))
- ._m11(src.getFloat(offset+20))
- ._m21(src.getFloat(offset+24))
- ._m31(src.getFloat(offset+28))
- ._m02(src.getFloat(offset+32))
- ._m12(src.getFloat(offset+36))
- ._m22(src.getFloat(offset+40))
- ._m32(src.getFloat(offset+44))
- ._m03(src.getFloat(offset+48))
- ._m13(src.getFloat(offset+52))
- ._m23(src.getFloat(offset+56))
- ._m33(src.getFloat(offset+60));
- }
-
- public void get(Matrix3f m, int offset, FloatBuffer src) {
- m._m00(src.get(offset))
- ._m01(src.get(offset+1))
- ._m02(src.get(offset+2))
- ._m10(src.get(offset+3))
- ._m11(src.get(offset+4))
- ._m12(src.get(offset+5))
- ._m20(src.get(offset+6))
- ._m21(src.get(offset+7))
- ._m22(src.get(offset+8));
- }
-
- public void get(Matrix3f m, int offset, ByteBuffer src) {
- m._m00(src.getFloat(offset))
- ._m01(src.getFloat(offset+4))
- ._m02(src.getFloat(offset+8))
- ._m10(src.getFloat(offset+12))
- ._m11(src.getFloat(offset+16))
- ._m12(src.getFloat(offset+20))
- ._m20(src.getFloat(offset+24))
- ._m21(src.getFloat(offset+28))
- ._m22(src.getFloat(offset+32));
- }
-
-
- public void get(Vector4f dst, int offset, FloatBuffer src) {
- dst.x = src.get(offset);
- dst.y = src.get(offset+1);
- dst.z = src.get(offset+2);
- dst.w = src.get(offset+3);
- }
-
- public void get(Vector4f dst, int offset, ByteBuffer src) {
- dst.x = src.getFloat(offset);
- dst.y = src.getFloat(offset+4);
- dst.z = src.getFloat(offset+8);
- dst.w = src.getFloat(offset+12);
- }
-
- public void get(Vector3f dst, int offset, FloatBuffer src) {
- dst.x = src.get(offset);
- dst.y = src.get(offset+1);
- dst.z = src.get(offset+2);
- }
-
- public void get(Vector3f dst, int offset, ByteBuffer src) {
- dst.x = src.getFloat(offset);
- dst.y = src.getFloat(offset+4);
- dst.z = src.getFloat(offset+8);
- }
-
- public float get(Matrix4f m, int column, int row) {
- switch (column) {
- case 0:
- switch (row) {
- case 0:
- return m.m00();
- case 1:
- return m.m01();
- case 2:
- return m.m02();
- case 3:
- return m.m03();
- default:
- break;
- }
- break;
- case 1:
- switch (row) {
- case 0:
- return m.m10();
- case 1:
- return m.m11();
- case 2:
- return m.m12();
- case 3:
- return m.m13();
- default:
- break;
- }
- break;
- case 2:
- switch (row) {
- case 0:
- return m.m20();
- case 1:
- return m.m21();
- case 2:
- return m.m22();
- case 3:
- return m.m23();
- default:
- break;
- }
- break;
- case 3:
- switch (row) {
- case 0:
- return m.m30();
- case 1:
- return m.m31();
- case 2:
- return m.m32();
- case 3:
- return m.m33();
- default:
- break;
- }
- break;
- default:
- break;
- }
- throw new IllegalArgumentException();
- }
-
- public Matrix4f set(Matrix4f m, int column, int row, float value) {
- switch (column) {
- case 0:
- switch (row) {
- case 0:
- return m.m00(value);
- case 1:
- return m.m01(value);
- case 2:
- return m.m02(value);
- case 3:
- return m.m03(value);
- default:
- break;
- }
- break;
- case 1:
- switch (row) {
- case 0:
- return m.m10(value);
- case 1:
- return m.m11(value);
- case 2:
- return m.m12(value);
- case 3:
- return m.m13(value);
- default:
- break;
- }
- break;
- case 2:
- switch (row) {
- case 0:
- return m.m20(value);
- case 1:
- return m.m21(value);
- case 2:
- return m.m22(value);
- case 3:
- return m.m23(value);
- default:
- break;
- }
- break;
- case 3:
- switch (row) {
- case 0:
- return m.m30(value);
- case 1:
- return m.m31(value);
- case 2:
- return m.m32(value);
- case 3:
- return m.m33(value);
- default:
- break;
- }
- break;
- default:
- break;
- }
- throw new IllegalArgumentException();
- }
-
- public float get(Matrix3f m, int column, int row) {
- switch (column) {
- case 0:
- switch (row) {
- case 0:
- return m.m00;
- case 1:
- return m.m01;
- case 2:
- return m.m02;
- default:
- break;
- }
- break;
- case 1:
- switch (row) {
- case 0:
- return m.m10;
- case 1:
- return m.m11;
- case 2:
- return m.m12;
- default:
- break;
- }
- break;
- case 2:
- switch (row) {
- case 0:
- return m.m20;
- case 1:
- return m.m21;
- case 2:
- return m.m22;
- default:
- break;
- }
- break;
- default:
- break;
- }
- throw new IllegalArgumentException();
- }
-
- public Matrix3f set(Matrix3f m, int column, int row, float value) {
- switch (column) {
- case 0:
- switch (row) {
- case 0:
- return m.m00(value);
- case 1:
- return m.m01(value);
- case 2:
- return m.m02(value);
- default:
- break;
- }
- break;
- case 1:
- switch (row) {
- case 0:
- return m.m10(value);
- case 1:
- return m.m11(value);
- case 2:
- return m.m12(value);
- default:
- break;
- }
- break;
- case 2:
- switch (row) {
- case 0:
- return m.m20(value);
- case 1:
- return m.m21(value);
- case 2:
- return m.m22(value);
- default:
- break;
- }
- break;
- default:
- break;
- }
- throw new IllegalArgumentException();
- }
-
- public Vector4f getColumn(Matrix4f m, int column, Vector4f dest) {
- switch (column) {
- case 0:
- return dest.set(m.m00(), m.m01(), m.m02(), m.m03());
- case 1:
- return dest.set(m.m10(), m.m11(), m.m12(), m.m13());
- case 2:
- return dest.set(m.m20(), m.m21(), m.m22(), m.m23());
- case 3:
- return dest.set(m.m30(), m.m31(), m.m32(), m.m33());
- default:
- throw new IndexOutOfBoundsException();
- }
- }
-
- public Matrix4f setColumn(Vector4f v, int column, Matrix4f dest) {
- switch (column) {
- case 0:
- return dest._m00(v.x)._m01(v.y)._m02(v.z)._m03(v.w);
- case 1:
- return dest._m10(v.x)._m11(v.y)._m12(v.z)._m13(v.w);
- case 2:
- return dest._m20(v.x)._m21(v.y)._m22(v.z)._m23(v.w);
- case 3:
- return dest._m30(v.x)._m31(v.y)._m32(v.z)._m33(v.w);
- default:
- throw new IndexOutOfBoundsException();
- }
- }
-
- public Matrix4f setColumn(Vector4fc v, int column, Matrix4f dest) {
- switch (column) {
- case 0:
- return dest._m00(v.x())._m01(v.y())._m02(v.z())._m03(v.w());
- case 1:
- return dest._m10(v.x())._m11(v.y())._m12(v.z())._m13(v.w());
- case 2:
- return dest._m20(v.x())._m21(v.y())._m22(v.z())._m23(v.w());
- case 3:
- return dest._m30(v.x())._m31(v.y())._m32(v.z())._m33(v.w());
- default:
- throw new IndexOutOfBoundsException();
- }
- }
-
- public void copy(Matrix4f src, Matrix4f dest) {
- dest._m00(src.m00()).
- _m01(src.m01()).
- _m02(src.m02()).
- _m03(src.m03()).
- _m10(src.m10()).
- _m11(src.m11()).
- _m12(src.m12()).
- _m13(src.m13()).
- _m20(src.m20()).
- _m21(src.m21()).
- _m22(src.m22()).
- _m23(src.m23()).
- _m30(src.m30()).
- _m31(src.m31()).
- _m32(src.m32()).
- _m33(src.m33());
- }
-
- public void copy(Matrix3f src, Matrix4f dest) {
- dest._m00(src.m00())
- ._m01(src.m01())
- ._m02(src.m02())
- ._m03(0.0f)
- ._m10(src.m10())
- ._m11(src.m11())
- ._m12(src.m12())
- ._m13(0.0f)
- ._m20(src.m20())
- ._m21(src.m21())
- ._m22(src.m22())
- ._m23(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(1.0f);
- }
-
- public void copy(Matrix4f src, Matrix3f dest) {
- dest._m00(src.m00())
- ._m01(src.m01())
- ._m02(src.m02())
- ._m10(src.m10())
- ._m11(src.m11())
- ._m12(src.m12())
- ._m20(src.m20())
- ._m21(src.m21())
- ._m22(src.m22());
- }
-
- public void copy3x3(Matrix4f src, Matrix4f dest) {
- dest._m00(src.m00())
- ._m01(src.m01())
- ._m02(src.m02())
- ._m10(src.m10())
- ._m11(src.m11())
- ._m12(src.m12())
- ._m20(src.m20())
- ._m21(src.m21())
- ._m22(src.m22());
- }
-
- public void copy3x3(Matrix3f src, Matrix4f dest) {
- dest._m00(src.m00())
- ._m01(src.m01())
- ._m02(src.m02())
- ._m10(src.m10())
- ._m11(src.m11())
- ._m12(src.m12())
- ._m20(src.m20())
- ._m21(src.m21())
- ._m22(src.m22());
- }
-
- public void copy4x3(Matrix4f src, Matrix4f dest) {
- dest._m00(src.m00())
- ._m01(src.m01())
- ._m02(src.m02())
- ._m10(src.m10())
- ._m11(src.m11())
- ._m12(src.m12())
- ._m20(src.m20())
- ._m21(src.m21())
- ._m22(src.m22())
- ._m30(src.m30())
- ._m31(src.m31())
- ._m32(src.m32());
- }
-
- public void copy(Matrix3f src, Matrix3f dest) {
- dest._m00(src.m00())
- ._m01(src.m01())
- ._m02(src.m02())
- ._m10(src.m10())
- ._m11(src.m11())
- ._m12(src.m12())
- ._m20(src.m20())
- ._m21(src.m21())
- ._m22(src.m22());
- }
-
- public void copy(float[] arr, int off, Matrix4f dest) {
- dest._m00(arr[off+0])
- ._m01(arr[off+1])
- ._m02(arr[off+2])
- ._m03(arr[off+3])
- ._m10(arr[off+4])
- ._m11(arr[off+5])
- ._m12(arr[off+6])
- ._m13(arr[off+7])
- ._m20(arr[off+8])
- ._m21(arr[off+9])
- ._m22(arr[off+10])
- ._m23(arr[off+11])
- ._m30(arr[off+12])
- ._m31(arr[off+13])
- ._m32(arr[off+14])
- ._m33(arr[off+15]);
- }
-
- public void copyTransposed(float[] arr, int off, Matrix4f dest) {
- dest._m00(arr[off+0])
- ._m10(arr[off+1])
- ._m20(arr[off+2])
- ._m30(arr[off+3])
- ._m01(arr[off+4])
- ._m11(arr[off+5])
- ._m21(arr[off+6])
- ._m31(arr[off+7])
- ._m02(arr[off+8])
- ._m12(arr[off+9])
- ._m22(arr[off+10])
- ._m32(arr[off+11])
- ._m03(arr[off+12])
- ._m13(arr[off+13])
- ._m23(arr[off+14])
- ._m33(arr[off+15]);
- }
-
- public void copy(float[] arr, int off, Matrix3f dest) {
- dest._m00(arr[off+0])
- ._m01(arr[off+1])
- ._m02(arr[off+2])
- ._m10(arr[off+3])
- ._m11(arr[off+4])
- ._m12(arr[off+5])
- ._m20(arr[off+6])
- ._m21(arr[off+7])
- ._m22(arr[off+8]);
- }
-
- public void copy(Matrix4f src, float[] dest, int off) {
- dest[off+0] = src.m00();
- dest[off+1] = src.m01();
- dest[off+2] = src.m02();
- dest[off+3] = src.m03();
- dest[off+4] = src.m10();
- dest[off+5] = src.m11();
- dest[off+6] = src.m12();
- dest[off+7] = src.m13();
- dest[off+8] = src.m20();
- dest[off+9] = src.m21();
- dest[off+10] = src.m22();
- dest[off+11] = src.m23();
- dest[off+12] = src.m30();
- dest[off+13] = src.m31();
- dest[off+14] = src.m32();
- dest[off+15] = src.m33();
- }
-
- public void copy(Matrix3f src, float[] dest, int off) {
- dest[off+0] = src.m00();
- dest[off+1] = src.m01();
- dest[off+2] = src.m02();
- dest[off+3] = src.m10();
- dest[off+4] = src.m11();
- dest[off+5] = src.m12();
- dest[off+6] = src.m20();
- dest[off+7] = src.m21();
- dest[off+8] = src.m22();
- }
-
- public void identity(Matrix4f dest) {
- dest._m00(1.0f)
- ._m01(0.0f)
- ._m02(0.0f)
- ._m03(0.0f)
- ._m10(0.0f)
- ._m11(1.0f)
- ._m12(0.0f)
- ._m13(0.0f)
- ._m20(0.0f)
- ._m21(0.0f)
- ._m22(1.0f)
- ._m23(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(1.0f);
- }
-
- public void identity(Matrix3f dest) {
- dest._m00(1.0f)
- ._m01(0.0f)
- ._m02(0.0f)
- ._m10(0.0f)
- ._m11(1.0f)
- ._m12(0.0f)
- ._m20(0.0f)
- ._m21(0.0f)
- ._m22(1.0f);
- }
-
- public void swap(Matrix4f m1, Matrix4f m2) {
- float tmp;
- tmp = m1.m00(); m1._m00(m2.m00()); m2._m00(tmp);
- tmp = m1.m01(); m1._m01(m2.m01()); m2._m01(tmp);
- tmp = m1.m02(); m1._m02(m2.m02()); m2._m02(tmp);
- tmp = m1.m03(); m1._m03(m2.m03()); m2._m03(tmp);
- tmp = m1.m10(); m1._m10(m2.m10()); m2._m10(tmp);
- tmp = m1.m11(); m1._m11(m2.m11()); m2._m11(tmp);
- tmp = m1.m12(); m1._m12(m2.m12()); m2._m12(tmp);
- tmp = m1.m13(); m1._m13(m2.m13()); m2._m13(tmp);
- tmp = m1.m20(); m1._m20(m2.m20()); m2._m20(tmp);
- tmp = m1.m21(); m1._m21(m2.m21()); m2._m21(tmp);
- tmp = m1.m22(); m1._m22(m2.m22()); m2._m22(tmp);
- tmp = m1.m23(); m1._m23(m2.m23()); m2._m23(tmp);
- tmp = m1.m30(); m1._m30(m2.m30()); m2._m30(tmp);
- tmp = m1.m31(); m1._m31(m2.m31()); m2._m31(tmp);
- tmp = m1.m32(); m1._m32(m2.m32()); m2._m32(tmp);
- tmp = m1.m33(); m1._m33(m2.m33()); m2._m33(tmp);
- }
-
- public void swap(Matrix3f m1, Matrix3f m2) {
- float tmp;
- tmp = m1.m00(); m1._m00(m2.m00()); m2._m00(tmp);
- tmp = m1.m01(); m1._m01(m2.m01()); m2._m01(tmp);
- tmp = m1.m02(); m1._m02(m2.m02()); m2._m02(tmp);
- tmp = m1.m10(); m1._m10(m2.m10()); m2._m10(tmp);
- tmp = m1.m11(); m1._m11(m2.m11()); m2._m11(tmp);
- tmp = m1.m12(); m1._m12(m2.m12()); m2._m12(tmp);
- tmp = m1.m20(); m1._m20(m2.m20()); m2._m20(tmp);
- tmp = m1.m21(); m1._m21(m2.m21()); m2._m21(tmp);
- tmp = m1.m22(); m1._m22(m2.m22()); m2._m22(tmp);
- }
-
- public void zero(Matrix4f dest) {
- dest._m00(0.0f)
- ._m01(0.0f)
- ._m02(0.0f)
- ._m03(0.0f)
- ._m10(0.0f)
- ._m11(0.0f)
- ._m12(0.0f)
- ._m13(0.0f)
- ._m20(0.0f)
- ._m21(0.0f)
- ._m22(0.0f)
- ._m23(0.0f)
- ._m30(0.0f)
- ._m31(0.0f)
- ._m32(0.0f)
- ._m33(0.0f);
- }
-
- public void zero(Matrix3f dest) {
- dest._m00(0.0f)
- ._m01(0.0f)
- ._m02(0.0f)
- ._m10(0.0f)
- ._m11(0.0f)
- ._m12(0.0f)
- ._m20(0.0f)
- ._m21(0.0f)
- ._m22(0.0f);
- }
-
- public void putMatrix3f(Quaternionf q, int position, ByteBuffer dest) {
- float w2 = q.w * q.w;
- float x2 = q.x * q.x;
- float y2 = q.y * q.y;
- float z2 = q.z * q.z;
- float zw = q.z * q.w;
- float xy = q.x * q.y;
- float xz = q.x * q.z;
- float yw = q.y * q.w;
- float yz = q.y * q.z;
- float xw = q.x * q.w;
- dest.putFloat(position, w2 + x2 - z2 - y2)
- .putFloat(position + 4, xy + zw + zw + xy)
- .putFloat(position + 8, xz - yw + xz - yw)
- .putFloat(position + 12, -zw + xy - zw + xy)
- .putFloat(position + 16, y2 - z2 + w2 - x2)
- .putFloat(position + 20, yz + yz + xw + xw)
- .putFloat(position + 24, yw + xz + xz + yw)
- .putFloat(position + 28, yz + yz - xw - xw)
- .putFloat(position + 32, z2 - y2 - x2 + w2);
- }
-
- public void putMatrix3f(Quaternionf q, int position, FloatBuffer dest) {
- float w2 = q.w * q.w;
- float x2 = q.x * q.x;
- float y2 = q.y * q.y;
- float z2 = q.z * q.z;
- float zw = q.z * q.w;
- float xy = q.x * q.y;
- float xz = q.x * q.z;
- float yw = q.y * q.w;
- float yz = q.y * q.z;
- float xw = q.x * q.w;
- dest.put(position, w2 + x2 - z2 - y2)
- .put(position + 1, xy + zw + zw + xy)
- .put(position + 2, xz - yw + xz - yw)
- .put(position + 3, -zw + xy - zw + xy)
- .put(position + 4, y2 - z2 + w2 - x2)
- .put(position + 5, yz + yz + xw + xw)
- .put(position + 6, yw + xz + xz + yw)
- .put(position + 7, yz + yz - xw - xw)
- .put(position + 8, z2 - y2 - x2 + w2);
- }
-
- public void putMatrix4f(Quaternionf q, int position, ByteBuffer dest) {
- float w2 = q.w * q.w;
- float x2 = q.x * q.x;
- float y2 = q.y * q.y;
- float z2 = q.z * q.z;
- float zw = q.z * q.w;
- float xy = q.x * q.y;
- float xz = q.x * q.z;
- float yw = q.y * q.w;
- float yz = q.y * q.z;
- float xw = q.x * q.w;
- dest.putFloat(position, w2 + x2 - z2 - y2)
- .putFloat(position + 4, xy + zw + zw + xy)
- .putFloat(position + 8, xz - yw + xz - yw)
- .putFloat(position + 12, 0.0f)
- .putFloat(position + 16, -zw + xy - zw + xy)
- .putFloat(position + 20, y2 - z2 + w2 - x2)
- .putFloat(position + 24, yz + yz + xw + xw)
- .putFloat(position + 28, 0.0f)
- .putFloat(position + 32, yw + xz + xz + yw)
- .putFloat(position + 36, yz + yz - xw - xw)
- .putFloat(position + 40, z2 - y2 - x2 + w2)
- .putFloat(position + 44, 0.0f)
- .putLong(position + 48, 0L)
- .putLong(position + 56, 0x3F80000000000000L);
- }
-
- public void putMatrix4f(Quaternionf q, int position, FloatBuffer dest) {
- float w2 = q.w * q.w;
- float x2 = q.x * q.x;
- float y2 = q.y * q.y;
- float z2 = q.z * q.z;
- float zw = q.z * q.w;
- float xy = q.x * q.y;
- float xz = q.x * q.z;
- float yw = q.y * q.w;
- float yz = q.y * q.z;
- float xw = q.x * q.w;
- dest.put(position, w2 + x2 - z2 - y2)
- .put(position + 1, xy + zw + zw + xy)
- .put(position + 2, xz - yw + xz - yw)
- .put(position + 3, 0.0f)
- .put(position + 4, -zw + xy - zw + xy)
- .put(position + 5, y2 - z2 + w2 - x2)
- .put(position + 6, yz + yz + xw + xw)
- .put(position + 7, 0.0f)
- .put(position + 8, yw + xz + xz + yw)
- .put(position + 9, yz + yz - xw - xw)
- .put(position + 10, z2 - y2 - x2 + w2)
- .put(position + 11, 0.0f)
- .put(position + 12, 0.0f)
- .put(position + 13, 0.0f)
- .put(position + 14, 0.0f)
- .put(position + 15, 1.0f);
- }
-
- public void putMatrix4x3f(Quaternionf q, int position, ByteBuffer dest) {
- float w2 = q.w * q.w;
- float x2 = q.x * q.x;
- float y2 = q.y * q.y;
- float z2 = q.z * q.z;
- float zw = q.z * q.w;
- float xy = q.x * q.y;
- float xz = q.x * q.z;
- float yw = q.y * q.w;
- float yz = q.y * q.z;
- float xw = q.x * q.w;
- dest.putFloat(position, w2 + x2 - z2 - y2)
- .putFloat(position + 4, xy + zw + zw + xy)
- .putFloat(position + 8, xz - yw + xz - yw)
- .putFloat(position + 12, -zw + xy - zw + xy)
- .putFloat(position + 16, y2 - z2 + w2 - x2)
- .putFloat(position + 20, yz + yz + xw + xw)
- .putFloat(position + 24, yw + xz + xz + yw)
- .putFloat(position + 28, yz + yz - xw - xw)
- .putFloat(position + 32, z2 - y2 - x2 + w2)
- .putLong(position + 36, 0L)
- .putFloat(position + 44, 0.0f);
- }
-
- public void putMatrix4x3f(Quaternionf q, int position, FloatBuffer dest) {
- float w2 = q.w * q.w;
- float x2 = q.x * q.x;
- float y2 = q.y * q.y;
- float z2 = q.z * q.z;
- float zw = q.z * q.w;
- float xy = q.x * q.y;
- float xz = q.x * q.z;
- float yw = q.y * q.w;
- float yz = q.y * q.z;
- float xw = q.x * q.w;
- dest.put(position, w2 + x2 - z2 - y2)
- .put(position + 1, xy + zw + zw + xy)
- .put(position + 2, xz - yw + xz - yw)
- .put(position + 3, -zw + xy - zw + xy)
- .put(position + 4, y2 - z2 + w2 - x2)
- .put(position + 5, yz + yz + xw + xw)
- .put(position + 6, yw + xz + xz + yw)
- .put(position + 7, yz + yz - xw - xw)
- .put(position + 8, z2 - y2 - x2 + w2)
- .put(position + 9, 0.0f)
- .put(position + 10, 0.0f)
- .put(position + 11, 0.0f);
- }
- }
-
- public static class MemUtilUnsafe extends MemUtilNIO {
- public static final sun.misc.Unsafe UNSAFE;
-
- public static final long ADDRESS;
- public static final long Matrix3f_m00;
- public static final long Matrix4f_m00;
- public static final long Vector4f_x;
- public static final long Vector3f_x;
- public static final long Quaternionf_x;
- public static final long floatArrayOffset;
-
- static {
- UNSAFE = getUnsafeInstance();
- try {
- ADDRESS = findBufferAddress();
- Matrix4f_m00 = checkMatrix4f();
- Matrix3f_m00 = checkMatrix3f();
- Vector4f_x = checkVector4f();
- Vector3f_x = checkVector3f();
- Quaternionf_x = checkQuaternionf();
- floatArrayOffset = UNSAFE.arrayBaseOffset(float[].class);
- // Check if we can use object field offset/address put/get methods
- sun.misc.Unsafe.class.getDeclaredMethod("getLong", new Class[] {Object.class, long.class});
- sun.misc.Unsafe.class.getDeclaredMethod("putLong", new Class[] {Object.class, long.class, long.class});
- } catch (NoSuchFieldException e) {
- throw new UnsupportedOperationException(e);
- } catch (NoSuchMethodException e) {
- throw new UnsupportedOperationException(e);
- }
- }
-
- private static long findBufferAddress() {
- try {
- return UNSAFE.objectFieldOffset(getDeclaredField(Buffer.class, "address")); //$NON-NLS-1$
- } catch (Exception e) {
- throw new UnsupportedOperationException(e);
- }
- }
-
- private static long checkMatrix4f() throws NoSuchFieldException, SecurityException {
- Field f = Matrix4f.class.getDeclaredField("m00");
- long Matrix4f_m00 = UNSAFE.objectFieldOffset(f);
- // Validate expected field offsets
- for (int i = 1; i < 16; i++) {
- int c = i >>> 2;
- int r = i & 3;
- f = Matrix4f.class.getDeclaredField("m" + c + r);
- long offset = UNSAFE.objectFieldOffset(f);
- if (offset != Matrix4f_m00 + (i << 2))
- throw new UnsupportedOperationException("Unexpected Matrix4f element offset");
- }
- return Matrix4f_m00;
- }
-
- private static long checkMatrix3f() throws NoSuchFieldException, SecurityException {
- Field f = Matrix3f.class.getDeclaredField("m00");
- long Matrix3f_m00 = UNSAFE.objectFieldOffset(f);
- // Validate expected field offsets
- for (int i = 1; i < 9; i++) {
- int c = i / 3;
- int r = i % 3;
- f = Matrix3f.class.getDeclaredField("m" + c + r);
- long offset = UNSAFE.objectFieldOffset(f);
- if (offset != Matrix3f_m00 + (i << 2))
- throw new UnsupportedOperationException("Unexpected Matrix3f element offset");
- }
- return Matrix3f_m00;
- }
-
- private static long checkVector4f() throws NoSuchFieldException, SecurityException {
- Field f = Vector4f.class.getDeclaredField("x");
- long Vector4f_x = UNSAFE.objectFieldOffset(f);
- // Validate expected field offsets
- String[] names = {"y", "z", "w"};
- for (int i = 1; i < 4; i++) {
- f = Vector4f.class.getDeclaredField(names[i-1]);
- long offset = UNSAFE.objectFieldOffset(f);
- if (offset != Vector4f_x + (i << 2))
- throw new UnsupportedOperationException("Unexpected Vector4f element offset");
- }
- return Vector4f_x;
- }
-
- private static long checkVector3f() throws NoSuchFieldException, SecurityException {
- Field f = Vector3f.class.getDeclaredField("x");
- long Vector3f_x = UNSAFE.objectFieldOffset(f);
- // Validate expected field offsets
- String[] names = {"y", "z"};
- for (int i = 1; i < 3; i++) {
- f = Vector3f.class.getDeclaredField(names[i-1]);
- long offset = UNSAFE.objectFieldOffset(f);
- if (offset != Vector3f_x + (i << 2))
- throw new UnsupportedOperationException("Unexpected Vector3f element offset");
- }
- return Vector3f_x;
- }
-
- private static long checkQuaternionf() throws NoSuchFieldException, SecurityException {
- Field f = Quaternionf.class.getDeclaredField("x");
- long Quaternionf_x = UNSAFE.objectFieldOffset(f);
- // Validate expected field offsets
- String[] names = {"y", "z", "w"};
- for (int i = 1; i < 4; i++) {
- f = Quaternionf.class.getDeclaredField(names[i-1]);
- long offset = UNSAFE.objectFieldOffset(f);
- if (offset != Quaternionf_x + (i << 2))
- throw new UnsupportedOperationException("Unexpected Quaternionf element offset");
- }
- return Quaternionf_x;
- }
-
- private static java.lang.reflect.Field getDeclaredField(Class root, String fieldName) throws NoSuchFieldException {
- Class type = root;
- do {
- try {
- java.lang.reflect.Field field = type.getDeclaredField(fieldName);
- return field;
- } catch (NoSuchFieldException e) {
- type = type.getSuperclass();
- } catch (SecurityException e) {
- type = type.getSuperclass();
- }
- } while (type != null);
- throw new NoSuchFieldException(fieldName + " does not exist in " + root.getName() + " or any of its superclasses."); //$NON-NLS-1$ //$NON-NLS-2$
- }
-
- public static sun.misc.Unsafe getUnsafeInstance() throws SecurityException {
- java.lang.reflect.Field[] fields = sun.misc.Unsafe.class.getDeclaredFields();
- for (int i = 0; i < fields.length; i++) {
- java.lang.reflect.Field field = fields[i];
- if (!field.getType().equals(sun.misc.Unsafe.class))
- continue;
- int modifiers = field.getModifiers();
- if (!(java.lang.reflect.Modifier.isStatic(modifiers) && java.lang.reflect.Modifier.isFinal(modifiers)))
- continue;
- field.setAccessible(true);
- try {
- return (sun.misc.Unsafe) field.get(null);
- } catch (IllegalAccessException e) {
- /* Ignore */
- }
- break;
- }
- throw new UnsupportedOperationException();
- }
-
- public static void put(Matrix4f m, long destAddr) {
- for (int i = 0; i < 8; i++) {
- UNSAFE.putLong(null, destAddr + (i << 3), UNSAFE.getLong(m, Matrix4f_m00 + (i << 3)));
- }
- }
-
- public static void put4x3(Matrix4f m, long destAddr) {
- sun.misc.Unsafe u = UNSAFE;
- for (int i = 0; i < 4; i++) {
- u.putLong(null, destAddr + 12 * i, u.getLong(m, Matrix4f_m00 + (i << 4)));
- }
- u.putFloat(null, destAddr + 8, m.m02());
- u.putFloat(null, destAddr + 20, m.m12());
- u.putFloat(null, destAddr + 32, m.m22());
- u.putFloat(null, destAddr + 44, m.m32());
- }
-
- public static void put3x4(Matrix4f m, long destAddr) {
- for (int i = 0; i < 6; i++) {
- UNSAFE.putLong(null, destAddr + (i << 3), UNSAFE.getLong(m, Matrix4f_m00 + (i << 3)));
- }
- }
-
- public static void putTransposed(Matrix4f m, long destAddr) {
- sun.misc.Unsafe u = UNSAFE;
- u.putFloat(null, destAddr, m.m00());
- u.putFloat(null, destAddr + 4, m.m10());
- u.putFloat(null, destAddr + 8, m.m20());
- u.putFloat(null, destAddr + 12, m.m30());
- u.putFloat(null, destAddr + 16, m.m01());
- u.putFloat(null, destAddr + 20, m.m11());
- u.putFloat(null, destAddr + 24, m.m21());
- u.putFloat(null, destAddr + 28, m.m31());
- u.putFloat(null, destAddr + 32, m.m02());
- u.putFloat(null, destAddr + 36, m.m12());
- u.putFloat(null, destAddr + 40, m.m22());
- u.putFloat(null, destAddr + 44, m.m32());
- u.putFloat(null, destAddr + 48, m.m03());
- u.putFloat(null, destAddr + 52, m.m13());
- u.putFloat(null, destAddr + 56, m.m23());
- u.putFloat(null, destAddr + 60, m.m33());
- }
-
- public static void put4x3Transposed(Matrix4f m, long destAddr) {
- sun.misc.Unsafe u = UNSAFE;
- u.putFloat(null, destAddr, m.m00());
- u.putFloat(null, destAddr + 4, m.m10());
- u.putFloat(null, destAddr + 8, m.m20());
- u.putFloat(null, destAddr + 12, m.m30());
- u.putFloat(null, destAddr + 16, m.m01());
- u.putFloat(null, destAddr + 20, m.m11());
- u.putFloat(null, destAddr + 24, m.m21());
- u.putFloat(null, destAddr + 28, m.m31());
- u.putFloat(null, destAddr + 32, m.m02());
- u.putFloat(null, destAddr + 36, m.m12());
- u.putFloat(null, destAddr + 40, m.m22());
- u.putFloat(null, destAddr + 44, m.m32());
- }
-
- public static void putTransposed(Matrix3f m, long destAddr) {
- sun.misc.Unsafe u = UNSAFE;
- u.putFloat(null, destAddr, m.m00());
- u.putFloat(null, destAddr + 4, m.m10());
- u.putFloat(null, destAddr + 8, m.m20());
- u.putFloat(null, destAddr + 12, m.m01());
- u.putFloat(null, destAddr + 16, m.m11());
- u.putFloat(null, destAddr + 20, m.m21());
- u.putFloat(null, destAddr + 24, m.m02());
- u.putFloat(null, destAddr + 28, m.m12());
- u.putFloat(null, destAddr + 32, m.m22());
- }
-
- public static void put(Matrix3f m, long destAddr) {
- for (int i = 0; i < 4; i++) {
- UNSAFE.putLong(null, destAddr + (i << 3), UNSAFE.getLong(m, Matrix3f_m00 + (i << 3)));
- }
- UNSAFE.putFloat(null, destAddr + 32, m.m22());
- }
-
- public static void put3x4(Matrix3f m, long destAddr) {
- for (int i = 0; i < 3; i++) {
- UNSAFE.putLong(null, destAddr + (i << 4), UNSAFE.getLong(m, Matrix3f_m00 + 12 * i));
- UNSAFE.putFloat(null, destAddr + (i << 4) + 8, UNSAFE.getFloat(m, Matrix3f_m00 + 8 + 12 * i));
- UNSAFE.putFloat(null, destAddr + 12 * i, 0.0f);
- }
- }
-
- public static void put(Vector4f src, long destAddr) {
- UNSAFE.putLong(null, destAddr, UNSAFE.getLong(src, Vector4f_x));
- UNSAFE.putLong(null, destAddr+8, UNSAFE.getLong(src, Vector4f_x+8));
- }
-
- public static void put(Vector3f src, long destAddr) {
- UNSAFE.putLong(null, destAddr, UNSAFE.getLong(src, Vector3f_x));
- UNSAFE.putFloat(null, destAddr+8, src.z);
- }
-
- public static void get(Matrix4f m, long srcAddr) {
- for (int i = 0; i < 8; i++) {
- UNSAFE.putLong(m, Matrix4f_m00 + (i << 3), UNSAFE.getLong(srcAddr + (i << 3)));
- }
- }
-
- public static void getTransposed(Matrix4f m, long srcAddr) {
- m._m00(UNSAFE.getFloat(srcAddr))
- ._m10(UNSAFE.getFloat(srcAddr + 4))
- ._m20(UNSAFE.getFloat(srcAddr + 8))
- ._m30(UNSAFE.getFloat(srcAddr + 12))
- ._m01(UNSAFE.getFloat(srcAddr + 16))
- ._m11(UNSAFE.getFloat(srcAddr + 20))
- ._m21(UNSAFE.getFloat(srcAddr + 24))
- ._m31(UNSAFE.getFloat(srcAddr + 28))
- ._m02(UNSAFE.getFloat(srcAddr + 32))
- ._m12(UNSAFE.getFloat(srcAddr + 36))
- ._m22(UNSAFE.getFloat(srcAddr + 40))
- ._m32(UNSAFE.getFloat(srcAddr + 44))
- ._m03(UNSAFE.getFloat(srcAddr + 48))
- ._m13(UNSAFE.getFloat(srcAddr + 52))
- ._m23(UNSAFE.getFloat(srcAddr + 56))
- ._m33(UNSAFE.getFloat(srcAddr + 60));
- }
-
- public static void get(Matrix3f m, long srcAddr) {
- for (int i = 0; i < 4; i++) {
- UNSAFE.putLong(m, Matrix3f_m00 + (i << 3), UNSAFE.getLong(null, srcAddr + (i << 3)));
- }
- m._m22(UNSAFE.getFloat(null, srcAddr+32));
- }
-
- public static void get(Vector4f dst, long srcAddr) {
- dst.x = UNSAFE.getFloat(null, srcAddr);
- dst.y = UNSAFE.getFloat(null, srcAddr+4);
- dst.z = UNSAFE.getFloat(null, srcAddr+8);
- dst.w = UNSAFE.getFloat(null, srcAddr+12);
- }
-
- public static void get(Vector3f dst, long srcAddr) {
- dst.x = UNSAFE.getFloat(null, srcAddr);
- dst.y = UNSAFE.getFloat(null, srcAddr+4);
- dst.z = UNSAFE.getFloat(null, srcAddr+8);
- }
-
- public static void putMatrix3f(Quaternionf q, long addr) {
- float dx = q.x + q.x;
- float dy = q.y + q.y;
- float dz = q.z + q.z;
- float q00 = dx * q.x;
- float q11 = dy * q.y;
- float q22 = dz * q.z;
- float q01 = dx * q.y;
- float q02 = dx * q.z;
- float q03 = dx * q.w;
- float q12 = dy * q.z;
- float q13 = dy * q.w;
- float q23 = dz * q.w;
- sun.misc.Unsafe u = UNSAFE;
- u.putFloat(null, addr, 1.0f - q11 - q22);
- u.putFloat(null, addr + 4, q01 + q23);
- u.putFloat(null, addr + 8, q02 - q13);
- u.putFloat(null, addr + 12, q01 - q23);
- u.putFloat(null, addr + 16, 1.0f - q22 - q00);
- u.putFloat(null, addr + 20, q12 + q03);
- u.putFloat(null, addr + 24, q02 + q13);
- u.putFloat(null, addr + 28, q12 - q03);
- u.putFloat(null, addr + 32, 1.0f - q11 - q00);
- }
-
- public static void putMatrix4f(Quaternionf q, long addr) {
- float dx = q.x + q.x;
- float dy = q.y + q.y;
- float dz = q.z + q.z;
- float q00 = dx * q.x;
- float q11 = dy * q.y;
- float q22 = dz * q.z;
- float q01 = dx * q.y;
- float q02 = dx * q.z;
- float q03 = dx * q.w;
- float q12 = dy * q.z;
- float q13 = dy * q.w;
- float q23 = dz * q.w;
- sun.misc.Unsafe u = UNSAFE;
- u.putFloat(null, addr, 1.0f - q11 - q22);
- u.putFloat(null, addr + 4, q01 + q23);
- u.putLong(null, addr + 8, Float.floatToRawIntBits(q02 - q13) & 0xFFFFFFFFL);
- u.putFloat(null, addr + 16, q01 - q23);
- u.putFloat(null, addr + 20, 1.0f - q22 - q00);
- u.putLong(null, addr + 24, Float.floatToRawIntBits(q12 + q03) & 0xFFFFFFFFL);
- u.putFloat(null, addr + 32, q02 + q13);
- u.putFloat(null, addr + 36, q12 - q03);
- u.putLong(null, addr + 40, Float.floatToRawIntBits(1.0f - q11 - q00) & 0xFFFFFFFFL);
- u.putLong(null, addr + 48, 0L);
- u.putLong(null, addr + 56, 0x3F80000000000000L);
- }
-
- public static void putMatrix4x3f(Quaternionf q, long addr) {
- float dx = q.x + q.x;
- float dy = q.y + q.y;
- float dz = q.z + q.z;
- float q00 = dx * q.x;
- float q11 = dy * q.y;
- float q22 = dz * q.z;
- float q01 = dx * q.y;
- float q02 = dx * q.z;
- float q03 = dx * q.w;
- float q12 = dy * q.z;
- float q13 = dy * q.w;
- float q23 = dz * q.w;
- sun.misc.Unsafe u = UNSAFE;
- u.putFloat(null, addr, 1.0f - q11 - q22);
- u.putFloat(null, addr + 4, q01 + q23);
- u.putFloat(null, addr + 8, q02 - q13);
- u.putFloat(null, addr + 12, q01 - q23);
- u.putFloat(null, addr + 16, 1.0f - q22 - q00);
- u.putFloat(null, addr + 20, q12 + q03);
- u.putFloat(null, addr + 24, q02 + q13);
- u.putFloat(null, addr + 28, q12 - q03);
- u.putFloat(null, addr + 32, 1.0f - q11 - q00);
- u.putLong(null, addr + 36, 0L);
- u.putFloat(null, addr + 44, 0.0f);
- }
-
- private static void throwNoDirectBufferException() {
- throw new IllegalArgumentException("Must use a direct buffer");
- }
-
- public void putMatrix3f(Quaternionf q, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 9 << 2);
- putMatrix3f(q, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void putMatrix3f(Quaternionf q, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 9);
- putMatrix3f(q, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- private static void checkPut(int offset, boolean direct, int capacity, int i) {
- if (!direct)
- throwNoDirectBufferException();
- if (capacity - offset < i)
- throw new BufferOverflowException();
- }
-
- public void putMatrix4f(Quaternionf q, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 16 << 2);
- putMatrix4f(q, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void putMatrix4f(Quaternionf q, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 16);
- putMatrix4f(q, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void putMatrix4x3f(Quaternionf q, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12 << 2);
- putMatrix4x3f(q, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void putMatrix4x3f(Quaternionf q, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12);
- putMatrix4x3f(q, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void put(Matrix4f m, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 16);
- put(m, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void put(Matrix4f m, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 16 << 2);
- put(m, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void put4x3(Matrix4f m, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12);
- put4x3(m, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void put4x3(Matrix4f m, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12 << 2);
- put4x3(m, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void put3x4(Matrix4f m, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12);
- put3x4(m, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void put3x4(Matrix4f m, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12 << 2);
- put3x4(m, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void putTransposed(Matrix4f m, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 16);
- putTransposed(m, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void putTransposed(Matrix4f m, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 16 << 2);
- putTransposed(m, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void put4x3Transposed(Matrix4f m, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12);
- put4x3Transposed(m, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void put4x3Transposed(Matrix4f m, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12 << 2);
- put4x3Transposed(m, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void putTransposed(Matrix3f m, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 9);
- putTransposed(m, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void putTransposed(Matrix3f m, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 9 << 2);
- putTransposed(m, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void put(Matrix3f m, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 9);
- put(m, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void put(Matrix3f m, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 9 << 2);
- put(m, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void put3x4(Matrix3f m, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12);
- put3x4(m, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void put3x4(Matrix3f m, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 12 << 2);
- put3x4(m, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void put(Vector4f src, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 4);
- put(src, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void put(Vector4f src, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 4 << 2);
- put(src, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void put(Vector3f src, int offset, FloatBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 3);
- put(src, UNSAFE.getLong(dest, ADDRESS) + (offset << 2));
- }
-
- public void put(Vector3f src, int offset, ByteBuffer dest) {
- if (Options.DEBUG) checkPut(offset, dest.isDirect(), dest.capacity(), 3 << 2);
- put(src, UNSAFE.getLong(dest, ADDRESS) + offset);
- }
-
- public void get(Matrix4f m, int offset, FloatBuffer src) {
- if (Options.DEBUG) checkGet(offset, src.isDirect(), src.capacity(), 16);
- get(m, UNSAFE.getLong(src, ADDRESS) + (offset << 2));
- }
-
- public void get(Matrix4f m, int offset, ByteBuffer src) {
- if (Options.DEBUG) checkGet(offset, src.isDirect(), src.capacity(), 16 << 2);
- get(m, UNSAFE.getLong(src, ADDRESS) + offset);
- }
-
- public float get(Matrix4f m, int column, int row) {
- return UNSAFE.getFloat(m, Matrix4f_m00 + (column << 4) + (row << 2));
- }
-
- public Matrix4f set(Matrix4f m, int column, int row, float value) {
- UNSAFE.putFloat(m, Matrix4f_m00 + (column << 4) + (row << 2), value);
- return m;
- }
-
- public float get(Matrix3f m, int column, int row) {
- return UNSAFE.getFloat(m, Matrix3f_m00 + (column * (3<<2)) + (row << 2));
- }
-
- public Matrix3f set(Matrix3f m, int column, int row, float value) {
- UNSAFE.putFloat(m, Matrix3f_m00 + (column * (3<<2)) + (row << 2), value);
- return m;
- }
-
- private static void checkGet(int offset, boolean direct, int capacity, int i) {
- if (!direct)
- throwNoDirectBufferException();
- if (capacity - offset < i)
- throw new BufferUnderflowException();
- }
-
- public void get(Matrix3f m, int offset, FloatBuffer src) {
- if (Options.DEBUG) checkGet(offset, src.isDirect(), src.capacity(), 9);
- get(m, UNSAFE.getLong(src, ADDRESS) + (offset << 2));
- }
-
- public void get(Matrix3f m, int offset, ByteBuffer src) {
- if (Options.DEBUG) checkGet(offset, src.isDirect(), src.capacity(), 9 << 2);
- get(m, UNSAFE.getLong(src, ADDRESS) + offset);
- }
-
- public void get(Vector4f dst, int offset, FloatBuffer src) {
- if (Options.DEBUG) checkGet(offset, src.isDirect(), src.capacity(), 4);
- get(dst, UNSAFE.getLong(src, ADDRESS) + (offset << 2));
- }
-
- public void get(Vector4f dst, int offset, ByteBuffer src) {
- if (Options.DEBUG) checkGet(offset, src.isDirect(), src.capacity(), 4 << 2);
- get(dst, UNSAFE.getLong(src, ADDRESS) + offset);
- }
-
- public void get(Vector3f dst, int offset, FloatBuffer src) {
- if (Options.DEBUG) checkGet(offset, src.isDirect(), src.capacity(), 3);
- get(dst, UNSAFE.getLong(src, ADDRESS) + (offset << 2));
- }
-
- public void get(Vector3f dst, int offset, ByteBuffer src) {
- if (Options.DEBUG) checkGet(offset, src.isDirect(), src.capacity(), 3 << 2);
- get(dst, UNSAFE.getLong(src, ADDRESS) + offset);
- }
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Options.java b/src/main/java/com/jozufozu/flywheel/util/joml/Options.java
deleted file mode 100644
index e0aa98c86..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Options.java
+++ /dev/null
@@ -1,116 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2016-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-import java.util.Arrays;
-import java.util.Locale;
-
-/**
- * Utility class for reading system properties.
- *
- * @author Kai Burjack
- */
-public final class Options {
-
- /**
- * Whether certain debugging checks should be made, such as that only direct NIO Buffers are used when Unsafe is active,
- * and a proxy should be created on calls to readOnlyView().
- */
- public static final boolean DEBUG = hasOption(System.getProperty("joml.debug", "false"));
-
- /**
- * Whether not to use sun.misc.Unsafe when copying memory with MemUtil.
- */
- public static final boolean NO_UNSAFE = hasOption(System.getProperty("joml.nounsafe", "false"));
- /**
- * Whether to force the use of sun.misc.Unsafe when copying memory with MemUtil.
- */
- public static final boolean FORCE_UNSAFE = hasOption(System.getProperty("joml.forceUnsafe", "false"));
-
- /**
- * Whether fast approximations of some java.lang.Math operations should be used.
- */
- public static final boolean FASTMATH = hasOption(System.getProperty("joml.fastmath", "false"));
-
- /**
- * When {@link #FASTMATH} is true
, whether to use a lookup table for sin/cos.
- */
- public static final boolean SIN_LOOKUP = hasOption(System.getProperty("joml.sinLookup", "false"));
-
- /**
- * When {@link #SIN_LOOKUP} is true
, this determines the table size.
- */
- public static final int SIN_LOOKUP_BITS = Integer.parseInt(System.getProperty("joml.sinLookup.bits", "14"));
-
- /**
- * Whether to use a {@link NumberFormat} producing scientific notation output when formatting matrix,
- * vector and quaternion components to strings.
- */
- public static final boolean useNumberFormat = hasOption(System.getProperty("joml.format", "true"));
-
- /**
- * Whether to try using java.lang.Math.fma() in most matrix/vector/quaternion operations if it is available.
- * If the CPU does not support it, it will be a lot slower than `a*b+c` and potentially generate a lot of memory allocations
- * for the emulation with `java.util.BigDecimal`, though.
- */
- public static final boolean USE_MATH_FMA = hasOption(System.getProperty("joml.useMathFma", "false"));
-
- /**
- * When {@link #useNumberFormat} is true
then this determines the number of decimal digits
- * produced in the formatted numbers.
- */
- public static final int numberFormatDecimals = Integer.parseInt(System.getProperty("joml.format.decimals", "3"));
-
- /**
- * The {@link NumberFormat} used to format all numbers throughout all JOML classes.
- */
- public static final NumberFormat NUMBER_FORMAT = decimalFormat();
-
- private Options() {
- }
-
- private static NumberFormat decimalFormat() {
- NumberFormat df;
- if (useNumberFormat) {
- char[] prec = new char[numberFormatDecimals];
- Arrays.fill(prec, '0');
- df = new DecimalFormat(" 0." + new String(prec) + "E0;-");
- } else {
- df = NumberFormat.getNumberInstance(Locale.ENGLISH);
- df.setGroupingUsed(false);
- }
- return df;
- }
-
- private static boolean hasOption(String v) {
- if (v == null)
- return false;
- if (v.trim().length() == 0)
- return true;
- return Boolean.valueOf(v).booleanValue();
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Quaternionf.java b/src/main/java/com/jozufozu/flywheel/util/joml/Quaternionf.java
deleted file mode 100644
index ad2ef13cd..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Quaternionf.java
+++ /dev/null
@@ -1,2565 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 Richard Greenlees
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-
-import com.mojang.math.Quaternion;
-
-/**
- * Quaternion of 4 single-precision floats which can represent rotation and uniform scaling.
- *
- * @author Richard Greenlees
- * @author Kai Burjack
- */
-public class Quaternionf implements Externalizable, Cloneable, Quaternionfc {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * The first component of the vector part.
- */
- public float x;
- /**
- * The second component of the vector part.
- */
- public float y;
- /**
- * The third component of the vector part.
- */
- public float z;
- /**
- * The real/scalar part of the quaternion.
- */
- public float w;
-
- /**
- * Create a new {@link Quaternionf} and initialize it with (x=0, y=0, z=0, w=1)
,
- * where (x, y, z)
is the vector part of the quaternion and w
is the real/scalar part.
- */
- public Quaternionf() {
- this.w = 1.0f;
- }
-
- /**
- * Create a new {@link Quaternionf} and initialize its components to the given values.
- *
- * @param x
- * the first component of the imaginary part
- * @param y
- * the second component of the imaginary part
- * @param z
- * the third component of the imaginary part
- * @param w
- * the real part
- */
- public Quaternionf(double x, double y, double z, double w) {
- this.x = (float) x;
- this.y = (float) y;
- this.z = (float) z;
- this.w = (float) w;
- }
-
- /**
- * Create a new {@link Quaternionf} and initialize its components to the given values.
- *
- * @param x
- * the first component of the imaginary part
- * @param y
- * the second component of the imaginary part
- * @param z
- * the third component of the imaginary part
- * @param w
- * the real part
- */
- public Quaternionf(float x, float y, float z, float w) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.w = w;
- }
-
- /**
- * Create a new {@link Quaternionf} and initialize its components to the same values as the given {@link Quaternionfc}.
- *
- * @param source
- * the {@link Quaternionfc} to take the component values from
- */
- public Quaternionf(Quaternionfc source) {
- set(source);
- }
-
- /**
- * Create a new {@link Quaternionf} which represents the rotation of the given {@link AxisAngle4f}.
- *
- * @param axisAngle
- * the {@link AxisAngle4f}
- */
- public Quaternionf(AxisAngle4f axisAngle) {
- float sin = Math.sin(axisAngle.angle * 0.5f);
- float cos = Math.cosFromSin(sin, axisAngle.angle * 0.5f);
- x = axisAngle.x * sin;
- y = axisAngle.y * sin;
- z = axisAngle.z * sin;
- w = cos;
- }
-
- public Quaternionf(Quaternion moj) {
- x = moj.i();
- y = moj.j();
- z = moj.k();
- w = moj.r();
- }
-
- /**
- * @return the first component of the vector part
- */
- public float x() {
- return this.x;
- }
-
- /**
- * @return the second component of the vector part
- */
- public float y() {
- return this.y;
- }
-
- /**
- * @return the third component of the vector part
- */
- public float z() {
- return this.z;
- }
-
- /**
- * @return the real/scalar part of the quaternion
- */
- public float w() {
- return this.w;
- }
-
- /**
- * Normalize this quaternion.
- *
- * @return this
- */
- public Quaternionf normalize() {
- return normalize(this);
- }
-
- public Quaternionf normalize(Quaternionf dest) {
- float invNorm = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w))));
- dest.x = x * invNorm;
- dest.y = y * invNorm;
- dest.z = z * invNorm;
- dest.w = w * invNorm;
- return dest;
- }
-
- /**
- * Add the quaternion (x, y, z, w)
to this quaternion.
- *
- * @param x
- * the x component of the vector part
- * @param y
- * the y component of the vector part
- * @param z
- * the z component of the vector part
- * @param w
- * the real/scalar component
- * @return this
- */
- public Quaternionf add(float x, float y, float z, float w) {
- return add(x, y, z, w, this);
- }
-
- public Quaternionf add(float x, float y, float z, float w, Quaternionf dest) {
- dest.x = this.x + x;
- dest.y = this.y + y;
- dest.z = this.z + z;
- dest.w = this.w + w;
- return dest;
- }
-
- /**
- * Add q2
to this quaternion.
- *
- * @param q2
- * the quaternion to add to this
- * @return this
- */
- public Quaternionf add(Quaternionfc q2) {
- return add(q2, this);
- }
-
- public Quaternionf add(Quaternionfc q2, Quaternionf dest) {
- dest.x = x + q2.x();
- dest.y = y + q2.y();
- dest.z = z + q2.z();
- dest.w = w + q2.w();
- return dest;
- }
-
- /**
- * Return the dot of this quaternion and otherQuat
.
- *
- * @param otherQuat
- * the other quaternion
- * @return the dot product
- */
- public float dot(Quaternionf otherQuat) {
- return this.x * otherQuat.x + this.y * otherQuat.y + this.z * otherQuat.z + this.w * otherQuat.w;
- }
-
- public float angle() {
- return (float) (2.0 * Math.safeAcos(w));
- }
-
- public Matrix3f get(Matrix3f dest) {
- return dest.set(this);
- }
-
- public Matrix4f get(Matrix4f dest) {
- return dest.set(this);
- }
-
- public AxisAngle4f get(AxisAngle4f dest) {
- float x = this.x;
- float y = this.y;
- float z = this.z;
- float w = this.w;
- if (w > 1.0f) {
- float invNorm = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w))));
- x *= invNorm;
- y *= invNorm;
- z *= invNorm;
- w *= invNorm;
- }
- dest.angle = (float) (2.0f * Math.acos(w));
- float s = Math.sqrt(1.0f - w * w);
- if (s < 0.001f) {
- dest.x = x;
- dest.y = y;
- dest.z = z;
- } else {
- s = 1.0f / s;
- dest.x = x * s;
- dest.y = y * s;
- dest.z = z * s;
- }
- return dest;
- }
-
- /**
- * Set the given {@link Quaternionf} to the values of this
.
- *
- * @see #set(Quaternionfc)
- *
- * @param dest
- * the {@link Quaternionf} to set
- * @return the passed in destination
- */
- public Quaternionf get(Quaternionf dest) {
- return dest.set(this);
- }
-
- public ByteBuffer getAsMatrix3f(ByteBuffer dest) {
- MemUtil.INSTANCE.putMatrix3f(this, dest.position(), dest);
- return dest;
- }
-
- public FloatBuffer getAsMatrix3f(FloatBuffer dest) {
- MemUtil.INSTANCE.putMatrix3f(this, dest.position(), dest);
- return dest;
- }
-
- public ByteBuffer getAsMatrix4f(ByteBuffer dest) {
- MemUtil.INSTANCE.putMatrix4f(this, dest.position(), dest);
- return dest;
- }
-
- public FloatBuffer getAsMatrix4f(FloatBuffer dest) {
- MemUtil.INSTANCE.putMatrix4f(this, dest.position(), dest);
- return dest;
- }
-
- public ByteBuffer getAsMatrix4x3f(ByteBuffer dest) {
- MemUtil.INSTANCE.putMatrix4x3f(this, dest.position(), dest);
- return dest;
- }
-
- public FloatBuffer getAsMatrix4x3f(FloatBuffer dest) {
- MemUtil.INSTANCE.putMatrix4x3f(this, dest.position(), dest);
- return dest;
- }
-
- /**
- * Set this quaternion to the given values.
- *
- * @param x
- * the new value of x
- * @param y
- * the new value of y
- * @param z
- * the new value of z
- * @param w
- * the new value of w
- * @return this
- */
- public Quaternionf set(float x, float y, float z, float w) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.w = w;
- return this;
- }
-
- /**
- * Set this quaternion to be a copy of q
.
- *
- * @param q
- * the {@link Quaternionfc} to copy
- * @return this
- */
- public Quaternionf set(Quaternionfc q) {
- this.x = q.x();
- this.y = q.y();
- this.z = q.z();
- this.w = q.w();
- return this;
- }
-
- /**
- * Set this quaternion to a rotation equivalent to the given {@link AxisAngle4f}.
- *
- * @param axisAngle
- * the {@link AxisAngle4f}
- * @return this
- */
- public Quaternionf set(AxisAngle4f axisAngle) {
- return setAngleAxis(axisAngle.angle, axisAngle.x, axisAngle.y, axisAngle.z);
- }
-
- /**
- * Set this quaternion to a rotation equivalent to the supplied axis and
- * angle (in radians).
- * (x, y, z)
is already normalized
- *
- * @param angle
- * the angle in radians
- * @param x
- * the x-component of the normalized rotation axis
- * @param y
- * the y-component of the normalized rotation axis
- * @param z
- * the z-component of the normalized rotation axis
- * @return this
- */
- public Quaternionf setAngleAxis(float angle, float x, float y, float z) {
- float s = Math.sin(angle * 0.5f);
- this.x = x * s;
- this.y = y * s;
- this.z = z * s;
- this.w = Math.cosFromSin(s, angle * 0.5f);
- return this;
- }
-
- /**
- * Set this quaternion to a rotation equivalent to the supplied axis and
- * angle (in radians).
- * (x, y, z)
is already normalized
- *
- * @param angle
- * the angle in radians
- * @param x
- * the x-component of the normalized rotation axis
- * @param y
- * the y-component of the normalized rotation axis
- * @param z
- * the z-component of the normalized rotation axis
- * @return this
- */
- public Quaternionf setAngleAxis(double angle, double x, double y, double z) {
- double s = Math.sin(angle * 0.5f);
- this.x = (float) (x * s);
- this.y = (float) (y * s);
- this.z = (float) (z * s);
- this.w = (float) Math.cosFromSin(s, angle * 0.5f);
- return this;
- }
-
- /**
- * Set this {@link Quaternionf} to a rotation of the given angle in radians about the supplied
- * axis, all of which are specified via the {@link AxisAngle4f}.
- *
- * @see #rotationAxis(float, float, float, float)
- *
- * @param axisAngle
- * the {@link AxisAngle4f} giving the rotation angle in radians and the axis to rotate about
- * @return this
- */
- public Quaternionf rotationAxis(AxisAngle4f axisAngle) {
- return rotationAxis(axisAngle.angle, axisAngle.x, axisAngle.y, axisAngle.z);
- }
-
- /**
- * Set this quaternion to a rotation of the given angle in radians about the supplied axis.
- *
- * @param angle
- * the rotation angle in radians
- * @param axisX
- * the x-coordinate of the rotation axis
- * @param axisY
- * the y-coordinate of the rotation axis
- * @param axisZ
- * the z-coordinate of the rotation axis
- * @return this
- */
- public Quaternionf rotationAxis(float angle, float axisX, float axisY, float axisZ) {
- float hangle = angle / 2.0f;
- float sinAngle = Math.sin(hangle);
- float invVLength = Math.invsqrt(axisX * axisX + axisY * axisY + axisZ * axisZ);
- return set(axisX * invVLength * sinAngle,
- axisY * invVLength * sinAngle,
- axisZ * invVLength * sinAngle,
- Math.cosFromSin(sinAngle, hangle));
- }
-
- /**
- * Set this quaternion to a rotation of the given angle in radians about the supplied axis.
- *
- * @see #rotationAxis(float, float, float, float)
- *
- * @param angle
- * the rotation angle in radians
- * @param axis
- * the axis to rotate about
- * @return this
- */
- public Quaternionf rotationAxis(float angle, Vector3fc axis) {
- return rotationAxis(angle, axis.x(), axis.y(), axis.z());
- }
-
- /**
- * Set this quaternion to represent a rotation of the given radians about the x axis.
- *
- * @param angle
- * the angle in radians to rotate about the x axis
- * @return this
- */
- public Quaternionf rotationX(float angle) {
- float sin = Math.sin(angle * 0.5f);
- float cos = Math.cosFromSin(sin, angle * 0.5f);
- return set(sin, 0, 0, cos);
- }
-
- /**
- * Set this quaternion to represent a rotation of the given radians about the y axis.
- *
- * @param angle
- * the angle in radians to rotate about the y axis
- * @return this
- */
- public Quaternionf rotationY(float angle) {
- float sin = Math.sin(angle * 0.5f);
- float cos = Math.cosFromSin(sin, angle * 0.5f);
- return set(0, sin, 0, cos);
- }
-
- /**
- * Set this quaternion to represent a rotation of the given radians about the z axis.
- *
- * @param angle
- * the angle in radians to rotate about the z axis
- * @return this
- */
- public Quaternionf rotationZ(float angle) {
- float sin = Math.sin(angle * 0.5f);
- float cos = Math.cosFromSin(sin, angle * 0.5f);
- return set(0, 0, sin, cos);
- }
-
- private void setFromUnnormalized(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) {
- float nm00 = m00, nm01 = m01, nm02 = m02;
- float nm10 = m10, nm11 = m11, nm12 = m12;
- float nm20 = m20, nm21 = m21, nm22 = m22;
- float lenX = Math.invsqrt(m00 * m00 + m01 * m01 + m02 * m02);
- float lenY = Math.invsqrt(m10 * m10 + m11 * m11 + m12 * m12);
- float lenZ = Math.invsqrt(m20 * m20 + m21 * m21 + m22 * m22);
- nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
- nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
- nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
- setFromNormalized(nm00, nm01, nm02, nm10, nm11, nm12, nm20, nm21, nm22);
- }
-
- private void setFromNormalized(float m00, float m01, float m02, float m10, float m11, float m12, float m20, float m21, float m22) {
- float t;
- float tr = m00 + m11 + m22;
- if (tr >= 0.0f) {
- t = Math.sqrt(tr + 1.0f);
- w = t * 0.5f;
- t = 0.5f / t;
- x = (m12 - m21) * t;
- y = (m20 - m02) * t;
- z = (m01 - m10) * t;
- } else {
- if (m00 >= m11 && m00 >= m22) {
- t = Math.sqrt(m00 - (m11 + m22) + 1.0f);
- x = t * 0.5f;
- t = 0.5f / t;
- y = (m10 + m01) * t;
- z = (m02 + m20) * t;
- w = (m12 - m21) * t;
- } else if (m11 > m22) {
- t = Math.sqrt(m11 - (m22 + m00) + 1.0f);
- y = t * 0.5f;
- t = 0.5f / t;
- z = (m21 + m12) * t;
- x = (m10 + m01) * t;
- w = (m20 - m02) * t;
- } else {
- t = Math.sqrt(m22 - (m00 + m11) + 1.0f);
- z = t * 0.5f;
- t = 0.5f / t;
- x = (m02 + m20) * t;
- y = (m21 + m12) * t;
- w = (m01 - m10) * t;
- }
- }
- }
-
- private void setFromUnnormalized(double m00, double m01, double m02, double m10, double m11, double m12, double m20, double m21, double m22) {
- double nm00 = m00, nm01 = m01, nm02 = m02;
- double nm10 = m10, nm11 = m11, nm12 = m12;
- double nm20 = m20, nm21 = m21, nm22 = m22;
- double lenX = Math.invsqrt(m00 * m00 + m01 * m01 + m02 * m02);
- double lenY = Math.invsqrt(m10 * m10 + m11 * m11 + m12 * m12);
- double lenZ = Math.invsqrt(m20 * m20 + m21 * m21 + m22 * m22);
- nm00 *= lenX; nm01 *= lenX; nm02 *= lenX;
- nm10 *= lenY; nm11 *= lenY; nm12 *= lenY;
- nm20 *= lenZ; nm21 *= lenZ; nm22 *= lenZ;
- setFromNormalized(nm00, nm01, nm02, nm10, nm11, nm12, nm20, nm21, nm22);
- }
-
- private void setFromNormalized(double m00, double m01, double m02, double m10, double m11, double m12, double m20, double m21, double m22) {
- double t;
- double tr = m00 + m11 + m22;
- if (tr >= 0.0) {
- t = Math.sqrt(tr + 1.0);
- w = (float) (t * 0.5);
- t = 0.5 / t;
- x = (float) ((m12 - m21) * t);
- y = (float) ((m20 - m02) * t);
- z = (float) ((m01 - m10) * t);
- } else {
- if (m00 >= m11 && m00 >= m22) {
- t = Math.sqrt(m00 - (m11 + m22) + 1.0);
- x = (float) (t * 0.5);
- t = 0.5 / t;
- y = (float) ((m10 + m01) * t);
- z = (float) ((m02 + m20) * t);
- w = (float) ((m12 - m21) * t);
- } else if (m11 > m22) {
- t = Math.sqrt(m11 - (m22 + m00) + 1.0);
- y = (float) (t * 0.5);
- t = 0.5 / t;
- z = (float) ((m21 + m12) * t);
- x = (float) ((m10 + m01) * t);
- w = (float) ((m20 - m02) * t);
- } else {
- t = Math.sqrt(m22 - (m00 + m11) + 1.0);
- z = (float) (t * 0.5);
- t = 0.5 / t;
- x = (float) ((m02 + m20) * t);
- y = (float) ((m21 + m12) * t);
- w = (float) ((m01 - m10) * t);
- }
- }
- }
-
- /**
- * Set this quaternion to be a representation of the rotational component of the given matrix.
- * q
.
- * T
is this
and Q
is the given
- * quaternion, then the resulting quaternion R
is:
- * R = T * Q
- * Q
first, and then by T
.
- *
- * @param q
- * the quaternion to multiply this
by
- * @return this
- */
- public Quaternionf mul(Quaternionfc q) {
- return mul(q, this);
- }
-
- public Quaternionf mul(Quaternionfc q, Quaternionf dest) {
- return dest.set(Math.fma(w, q.x(), Math.fma(x, q.w(), Math.fma(y, q.z(), -z * q.y()))),
- Math.fma(w, q.y(), Math.fma(-x, q.z(), Math.fma(y, q.w(), z * q.x()))),
- Math.fma(w, q.z(), Math.fma(x, q.y(), Math.fma(-y, q.x(), z * q.w()))),
- Math.fma(w, q.w(), Math.fma(-x, q.x(), Math.fma(-y, q.y(), -z * q.z()))));
- }
-
- /**
- * Multiply this quaternion by the quaternion represented via (qx, qy, qz, qw)
.
- * T
is this
and Q
is the given
- * quaternion, then the resulting quaternion R
is:
- * R = T * Q
- * Q
first, and then by T
.
- *
- * @param qx
- * the x component of the quaternion to multiply this
by
- * @param qy
- * the y component of the quaternion to multiply this
by
- * @param qz
- * the z component of the quaternion to multiply this
by
- * @param qw
- * the w component of the quaternion to multiply this
by
- * @return this
- */
- public Quaternionf mul(float qx, float qy, float qz, float qw) {
- return mul(qx, qy, qz, qw, this);
- }
-
- public Quaternionf mul(float qx, float qy, float qz, float qw, Quaternionf dest) {
- return dest.set(Math.fma(w, qx, Math.fma(x, qw, Math.fma(y, qz, -z * qy))),
- Math.fma(w, qy, Math.fma(-x, qz, Math.fma(y, qw, z * qx))),
- Math.fma(w, qz, Math.fma(x, qy, Math.fma(-y, qx, z * qw))),
- Math.fma(w, qw, Math.fma(-x, qx, Math.fma(-y, qy, -z * qz))));
- }
-
- /**
- * Pre-multiply this quaternion by q
.
- * T
is this
and Q
is the given quaternion, then the resulting quaternion R
is:
- * R = Q * T
- * T
first, and then by Q
.
- *
- * @param q
- * the quaternion to pre-multiply this
by
- * @return this
- */
- public Quaternionf premul(Quaternionfc q) {
- return premul(q, this);
- }
-
- public Quaternionf premul(Quaternionfc q, Quaternionf dest) {
- return dest.set(Math.fma(q.w(), x, Math.fma(q.x(), w, Math.fma(q.y(), z, -q.z() * y))),
- Math.fma(q.w(), y, Math.fma(-q.x(), z, Math.fma(q.y(), w, q.z() * x))),
- Math.fma(q.w(), z, Math.fma(q.x(), y, Math.fma(-q.y(), x, q.z() * w))),
- Math.fma(q.w(), w, Math.fma(-q.x(), x, Math.fma(-q.y(), y, -q.z() * z))));
- }
-
- /**
- * Pre-multiply this quaternion by the quaternion represented via (qx, qy, qz, qw)
.
- * T
is this
and Q
is the given quaternion, then the resulting quaternion R
is:
- * R = Q * T
- * T
first, and then by Q
.
- *
- * @param qx
- * the x component of the quaternion to multiply this
by
- * @param qy
- * the y component of the quaternion to multiply this
by
- * @param qz
- * the z component of the quaternion to multiply this
by
- * @param qw
- * the w component of the quaternion to multiply this
by
- * @return this
- */
- public Quaternionf premul(float qx, float qy, float qz, float qw) {
- return premul(qx, qy, qz, qw, this);
- }
-
- public Quaternionf premul(float qx, float qy, float qz, float qw, Quaternionf dest) {
- return dest.set(Math.fma(qw, x, Math.fma(qx, w, Math.fma(qy, z, -qz * y))),
- Math.fma(qw, y, Math.fma(-qx, z, Math.fma(qy, w, qz * x))),
- Math.fma(qw, z, Math.fma(qx, y, Math.fma(-qy, x, qz * w))),
- Math.fma(qw, w, Math.fma(-qx, x, Math.fma(-qy, y, -qz * z))));
- }
-
- public Vector3f transform(Vector3f vec){
- return transform(vec.x, vec.y, vec.z, vec);
- }
-
- public Vector3f transformInverse(Vector3f vec){
- return transformInverse(vec.x, vec.y, vec.z, vec);
- }
-
- public Vector3f transformPositiveX(Vector3f dest) {
- float ww = w * w;
- float xx = x * x;
- float yy = y * y;
- float zz = z * z;
- float zw = z * w;
- float xy = x * y;
- float xz = x * z;
- float yw = y * w;
- dest.x = ww + xx - zz - yy;
- dest.y = xy + zw + zw + xy;
- dest.z = xz - yw + xz - yw;
- return dest;
- }
-
- public Vector4f transformPositiveX(Vector4f dest) {
- float ww = w * w;
- float xx = x * x;
- float yy = y * y;
- float zz = z * z;
- float zw = z * w;
- float xy = x * y;
- float xz = x * z;
- float yw = y * w;
- dest.x = ww + xx - zz - yy;
- dest.y = xy + zw + zw + xy;
- dest.z = xz - yw + xz - yw;
- return dest;
- }
-
- public Vector3f transformUnitPositiveX(Vector3f dest) {
- float xy = x * y, xz = x * z, yy = y * y;
- float yw = y * w, zz = z * z, zw = z * w;
- dest.x = 1 - yy - zz - yy - zz;
- dest.y = xy + zw + xy + zw;
- dest.z = xz - yw + xz - yw;
- return dest;
- }
-
- public Vector4f transformUnitPositiveX(Vector4f dest) {
- float yy = y * y, zz = z * z, xy = x * y;
- float xz = x * z, yw = y * w, zw = z * w;
- dest.x = 1 - yy - yy - zz - zz;
- dest.y = xy + zw + xy + zw;
- dest.z = xz - yw + xz - yw;
- return dest;
- }
-
- public Vector3f transformPositiveY(Vector3f dest) {
- float ww = w * w;
- float xx = x * x;
- float yy = y * y;
- float zz = z * z;
- float zw = z * w;
- float xy = x * y;
- float yz = y * z;
- float xw = x * w;
- dest.x = -zw + xy - zw + xy;
- dest.y = yy - zz + ww - xx;
- dest.z = yz + yz + xw + xw;
- return dest;
- }
-
- public Vector4f transformPositiveY(Vector4f dest) {
- float ww = w * w, xx = x * x, yy = y * y;
- float zz = z * z, zw = z * w, xy = x * y;
- float yz = y * z, xw = x * w;
- dest.x = -zw + xy - zw + xy;
- dest.y = yy - zz + ww - xx;
- dest.z = yz + yz + xw + xw;
- return dest;
- }
-
- public Vector4f transformUnitPositiveY(Vector4f dest) {
- float xx = x * x, zz = z * z, xy = x * y;
- float yz = y * z, xw = x * w, zw = z * w;
- dest.x = xy - zw + xy - zw;
- dest.y = 1 - xx - xx - zz - zz;
- dest.z = yz + yz + xw + xw;
- return dest;
- }
-
- public Vector3f transformUnitPositiveY(Vector3f dest) {
- float xx = x * x, zz = z * z, xy = x * y;
- float yz = y * z, xw = x * w, zw = z * w;
- dest.x = xy - zw + xy - zw;
- dest.y = 1 - xx - xx - zz - zz;
- dest.z = yz + yz + xw + xw;
- return dest;
- }
-
- public Vector3f transformPositiveZ(Vector3f dest) {
- float ww = w * w, xx = x * x, yy = y * y;
- float zz = z * z, xz = x * z, yw = y * w;
- float yz = y * z, xw = x * w;
- dest.x = yw + xz + xz + yw;
- dest.y = yz + yz - xw - xw;
- dest.z = zz - yy - xx + ww;
- return dest;
- }
-
- public Vector4f transformPositiveZ(Vector4f dest) {
- float ww = w * w, xx = x * x, yy = y * y;
- float zz = z * z, xz = x * z, yw = y * w;
- float yz = y * z, xw = x * w;
- dest.x = yw + xz + xz + yw;
- dest.y = yz + yz - xw - xw;
- dest.z = zz - yy - xx + ww;
- return dest;
- }
-
- public Vector4f transformUnitPositiveZ(Vector4f dest) {
- float xx = x * x, yy = y * y, xz = x * z;
- float yz = y * z, xw = x * w, yw = y * w;
- dest.x = xz + yw + xz + yw;
- dest.y = yz + yz - xw - xw;
- dest.z = 1 - xx - xx - yy - yy;
- return dest;
- }
-
- public Vector3f transformUnitPositiveZ(Vector3f dest) {
- float xx = x * x, yy = y * y, xz = x * z;
- float yz = y * z, xw = x * w, yw = y * w;
- dest.x = xz + yw + xz + yw;
- dest.y = yz + yz - xw - xw;
- dest.z = 1.0f - xx - xx - yy - yy;
- return dest;
- }
-
- public Vector4f transform(Vector4f vec){
- return transform(vec, vec);
- }
-
- public Vector4f transformInverse(Vector4f vec){
- return transformInverse(vec, vec);
- }
-
- public Vector3f transform(Vector3fc vec, Vector3f dest) {
- return transform(vec.x(), vec.y(), vec.z(), dest);
- }
-
- public Vector3f transformInverse(Vector3fc vec, Vector3f dest) {
- return transformInverse(vec.x(), vec.y(), vec.z(), dest);
- }
-
- public Vector3f transform(float x, float y, float z, Vector3f dest) {
- float xx = this.x * this.x, yy = this.y * this.y, zz = this.z * this.z, ww = this.w * this.w;
- float xy = this.x * this.y, xz = this.x * this.z, yz = this.y * this.z, xw = this.x * this.w;
- float zw = this.z * this.w, yw = this.y * this.w, k = 1 / (xx + yy + zz + ww);
- return dest.set(Math.fma((xx - yy - zz + ww) * k, x, Math.fma(2 * (xy - zw) * k, y, (2 * (xz + yw) * k) * z)),
- Math.fma(2 * (xy + zw) * k, x, Math.fma((yy - xx - zz + ww) * k, y, (2 * (yz - xw) * k) * z)),
- Math.fma(2 * (xz - yw) * k, x, Math.fma(2 * (yz + xw) * k, y, ((zz - xx - yy + ww) * k) * z)));
- }
-
- public Vector3f transformInverse(float x, float y, float z, Vector3f dest) {
- float n = 1.0f / Math.fma(this.x, this.x, Math.fma(this.y, this.y, Math.fma(this.z, this.z, this.w * this.w)));
- float qx = this.x * n, qy = this.y * n, qz = this.z * n, qw = this.w * n;
- float xx = qx * qx, yy = qy * qy, zz = qz * qz, ww = qw * qw;
- float xy = qx * qy, xz = qx * qz, yz = qy * qz, xw = qx * qw;
- float zw = qz * qw, yw = qy * qw, k = 1 / (xx + yy + zz + ww);
- return dest.set(Math.fma((xx - yy - zz + ww) * k, x, Math.fma(2 * (xy + zw) * k, y, (2 * (xz - yw) * k) * z)),
- Math.fma(2 * (xy - zw) * k, x, Math.fma((yy - xx - zz + ww) * k, y, (2 * (yz + xw) * k) * z)),
- Math.fma(2 * (xz + yw) * k, x, Math.fma(2 * (yz - xw) * k, y, ((zz - xx - yy + ww) * k) * z)));
- }
-
- public Vector3f transformUnit(Vector3f vec) {
- return transformUnit(vec.x, vec.y, vec.z, vec);
- }
-
- public Vector3f transformInverseUnit(Vector3f vec) {
- return transformInverseUnit(vec.x, vec.y, vec.z, vec);
- }
-
- public Vector3f transformUnit(Vector3fc vec, Vector3f dest) {
- return transformUnit(vec.x(), vec.y(), vec.z(), dest);
- }
-
- public Vector3f transformInverseUnit(Vector3fc vec, Vector3f dest) {
- return transformInverseUnit(vec.x(), vec.y(), vec.z(), dest);
- }
-
- public Vector3f transformUnit(float x, float y, float z, Vector3f dest) {
- float xx = this.x * this.x, xy = this.x * this.y, xz = this.x * this.z;
- float xw = this.x * this.w, yy = this.y * this.y, yz = this.y * this.z;
- float yw = this.y * this.w, zz = this.z * this.z, zw = this.z * this.w;
- return dest.set(Math.fma(Math.fma(-2, yy + zz, 1), x, Math.fma(2 * (xy - zw), y, (2 * (xz + yw)) * z)),
- Math.fma(2 * (xy + zw), x, Math.fma(Math.fma(-2, xx + zz, 1), y, (2 * (yz - xw)) * z)),
- Math.fma(2 * (xz - yw), x, Math.fma(2 * (yz + xw), y, Math.fma(-2, xx + yy, 1) * z)));
- }
-
- public Vector3f transformInverseUnit(float x, float y, float z, Vector3f dest) {
- float xx = this.x * this.x, xy = this.x * this.y, xz = this.x * this.z;
- float xw = this.x * this.w, yy = this.y * this.y, yz = this.y * this.z;
- float yw = this.y * this.w, zz = this.z * this.z, zw = this.z * this.w;
- return dest.set(Math.fma(Math.fma(-2, yy + zz, 1), x, Math.fma(2 * (xy + zw), y, (2 * (xz - yw)) * z)),
- Math.fma(2 * (xy - zw), x, Math.fma(Math.fma(-2, xx + zz, 1), y, (2 * (yz + xw)) * z)),
- Math.fma(2 * (xz + yw), x, Math.fma(2 * (yz - xw), y, Math.fma(-2, xx + yy, 1) * z)));
- }
-
- public Vector4f transform(Vector4fc vec, Vector4f dest) {
- return transform(vec.x(), vec.y(), vec.z(), dest);
- }
-
- public Vector4f transformInverse(Vector4fc vec, Vector4f dest) {
- return transformInverse(vec.x(), vec.y(), vec.z(), dest);
- }
-
- public Vector4f transform(float x, float y, float z, Vector4f dest) {
- float xx = this.x * this.x, yy = this.y * this.y, zz = this.z * this.z, ww = this.w * this.w;
- float xy = this.x * this.y, xz = this.x * this.z, yz = this.y * this.z, xw = this.x * this.w;
- float zw = this.z * this.w, yw = this.y * this.w, k = 1 / (xx + yy + zz + ww);
- return dest.set(Math.fma((xx - yy - zz + ww) * k, x, Math.fma(2 * (xy - zw) * k, y, (2 * (xz + yw) * k) * z)),
- Math.fma(2 * (xy + zw) * k, x, Math.fma((yy - xx - zz + ww) * k, y, (2 * (yz - xw) * k) * z)),
- Math.fma(2 * (xz - yw) * k, x, Math.fma(2 * (yz + xw) * k, y, ((zz - xx - yy + ww) * k) * z)));
- }
-
- public Vector4f transformInverse(float x, float y, float z, Vector4f dest) {
- float n = 1.0f / Math.fma(this.x, this.x, Math.fma(this.y, this.y, Math.fma(this.z, this.z, this.w * this.w)));
- float qx = this.x * n, qy = this.y * n, qz = this.z * n, qw = this.w * n;
- float xx = qx * qx, yy = qy * qy, zz = qz * qz, ww = qw * qw;
- float xy = qx * qy, xz = qx * qz, yz = qy * qz, xw = qx * qw;
- float zw = qz * qw, yw = qy * qw, k = 1 / (xx + yy + zz + ww);
- return dest.set(Math.fma((xx - yy - zz + ww) * k, x, Math.fma(2 * (xy + zw) * k, y, (2 * (xz - yw) * k) * z)),
- Math.fma(2 * (xy - zw) * k, x, Math.fma((yy - xx - zz + ww) * k, y, (2 * (yz + xw) * k) * z)),
- Math.fma(2 * (xz + yw) * k, x, Math.fma(2 * (yz - xw) * k, y, ((zz - xx - yy + ww) * k) * z)));
- }
-
- public Vector4f transformUnit(Vector4f vec) {
- return transformUnit(vec.x, vec.y, vec.z, vec);
- }
-
- public Vector4f transformInverseUnit(Vector4f vec) {
- return transformInverseUnit(vec.x, vec.y, vec.z, vec);
- }
-
- public Vector4f transformUnit(Vector4fc vec, Vector4f dest) {
- return transformUnit(vec.x(), vec.y(), vec.z(), dest);
- }
-
- public Vector4f transformInverseUnit(Vector4fc vec, Vector4f dest) {
- return transformInverseUnit(vec.x(), vec.y(), vec.z(), dest);
- }
-
- public Vector4f transformUnit(float x, float y, float z, Vector4f dest) {
- float xx = this.x * this.x, xy = this.x * this.y, xz = this.x * this.z;
- float xw = this.x * this.w, yy = this.y * this.y, yz = this.y * this.z;
- float yw = this.y * this.w, zz = this.z * this.z, zw = this.z * this.w;
- return dest.set(Math.fma(Math.fma(-2, yy + zz, 1), x, Math.fma(2 * (xy - zw), y, (2 * (xz + yw)) * z)),
- Math.fma(2 * (xy + zw), x, Math.fma(Math.fma(-2, xx + zz, 1), y, (2 * (yz - xw)) * z)),
- Math.fma(2 * (xz - yw), x, Math.fma(2 * (yz + xw), y, Math.fma(-2, xx + yy, 1) * z)));
- }
-
- public Vector4f transformInverseUnit(float x, float y, float z, Vector4f dest) {
- float xx = this.x * this.x, xy = this.x * this.y, xz = this.x * this.z;
- float xw = this.x * this.w, yy = this.y * this.y, yz = this.y * this.z;
- float yw = this.y * this.w, zz = this.z * this.z, zw = this.z * this.w;
- return dest.set(Math.fma(Math.fma(-2, yy + zz, 1), x, Math.fma(2 * (xy + zw), y, (2 * (xz - yw)) * z)),
- Math.fma(2 * (xy - zw), x, Math.fma(Math.fma(-2, xx + zz, 1), y, (2 * (yz + xw)) * z)),
- Math.fma(2 * (xz + yw), x, Math.fma(2 * (yz - xw), y, Math.fma(-2, xx + yy, 1) * z)));
- }
-
- public Quaternionf invert(Quaternionf dest) {
- float invNorm = 1.0f / Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w)));
- dest.x = -x * invNorm;
- dest.y = -y * invNorm;
- dest.z = -z * invNorm;
- dest.w = w * invNorm;
- return dest;
- }
-
- /**
- * Invert this quaternion and {@link #normalize() normalize} it.
- * this
quaternion by b
.
- * this = this * b^-1
, where b^-1
is the inverse of b
.
- *
- * @param b
- * the {@link Quaternionf} to divide this by
- * @return this
- */
- public Quaternionf div(Quaternionfc b) {
- return div(b, this);
- }
-
- /**
- * Conjugate this quaternion.
- *
- * @return this
- */
- public Quaternionf conjugate() {
- return conjugate(this);
- }
-
- public Quaternionf conjugate(Quaternionf dest) {
- dest.x = -x;
- dest.y = -y;
- dest.z = -z;
- dest.w = w;
- return dest;
- }
-
- /**
- * Set this quaternion to the identity.
- *
- * @return this
- */
- public Quaternionf identity() {
- x = 0;
- y = 0;
- z = 0;
- w = 1;
- return this;
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the cartesian base unit axes,
- * called the euler angles using rotation sequence XYZ
.
- * rotateX(angleX).rotateY(angleY).rotateZ(angleZ)
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angleX
- * the angle in radians to rotate about the x axis
- * @param angleY
- * the angle in radians to rotate about the y axis
- * @param angleZ
- * the angle in radians to rotate about the z axis
- * @return this
- */
- public Quaternionf rotateXYZ(float angleX, float angleY, float angleZ) {
- return rotateXYZ(angleX, angleY, angleZ, this);
- }
-
- public Quaternionf rotateXYZ(float angleX, float angleY, float angleZ, Quaternionf dest) {
- float sx = Math.sin(angleX * 0.5f);
- float cx = Math.cosFromSin(sx, angleX * 0.5f);
- float sy = Math.sin(angleY * 0.5f);
- float cy = Math.cosFromSin(sy, angleY * 0.5f);
- float sz = Math.sin(angleZ * 0.5f);
- float cz = Math.cosFromSin(sz, angleZ * 0.5f);
-
- float cycz = cy * cz;
- float sysz = sy * sz;
- float sycz = sy * cz;
- float cysz = cy * sz;
- float w = cx*cycz - sx*sysz;
- float x = sx*cycz + cx*sysz;
- float y = cx*sycz - sx*cysz;
- float z = cx*cysz + sx*sycz;
- // right-multiply
- return dest.set(Math.fma(this.w, x, Math.fma(this.x, w, Math.fma(this.y, z, -this.z * y))),
- Math.fma(this.w, y, Math.fma(-this.x, z, Math.fma(this.y, w, this.z * x))),
- Math.fma(this.w, z, Math.fma(this.x, y, Math.fma(-this.y, x, this.z * w))),
- Math.fma(this.w, w, Math.fma(-this.x, x, Math.fma(-this.y, y, -this.z * z))));
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the cartesian base unit axes,
- * called the euler angles, using the rotation sequence ZYX
.
- * rotateZ(angleZ).rotateY(angleY).rotateX(angleX)
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angleZ
- * the angle in radians to rotate about the z axis
- * @param angleY
- * the angle in radians to rotate about the y axis
- * @param angleX
- * the angle in radians to rotate about the x axis
- * @return this
- */
- public Quaternionf rotateZYX(float angleZ, float angleY, float angleX) {
- return rotateZYX(angleZ, angleY, angleX, this);
- }
-
- public Quaternionf rotateZYX(float angleZ, float angleY, float angleX, Quaternionf dest) {
- float sx = Math.sin(angleX * 0.5f);
- float cx = Math.cosFromSin(sx, angleX * 0.5f);
- float sy = Math.sin(angleY * 0.5f);
- float cy = Math.cosFromSin(sy, angleY * 0.5f);
- float sz = Math.sin(angleZ * 0.5f);
- float cz = Math.cosFromSin(sz, angleZ * 0.5f);
-
- float cycz = cy * cz;
- float sysz = sy * sz;
- float sycz = sy * cz;
- float cysz = cy * sz;
- float w = cx*cycz + sx*sysz;
- float x = sx*cycz - cx*sysz;
- float y = cx*sycz + sx*cysz;
- float z = cx*cysz - sx*sycz;
- // right-multiply
- return dest.set(Math.fma(this.w, x, Math.fma(this.x, w, Math.fma(this.y, z, -this.z * y))),
- Math.fma(this.w, y, Math.fma(-this.x, z, Math.fma(this.y, w, this.z * x))),
- Math.fma(this.w, z, Math.fma(this.x, y, Math.fma(-this.y, x, this.z * w))),
- Math.fma(this.w, w, Math.fma(-this.x, x, Math.fma(-this.y, y, -this.z * z))));
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the cartesian base unit axes,
- * called the euler angles, using the rotation sequence YXZ
.
- * rotateY(angleY).rotateX(angleX).rotateZ(angleZ)
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angleY
- * the angle in radians to rotate about the y axis
- * @param angleX
- * the angle in radians to rotate about the x axis
- * @param angleZ
- * the angle in radians to rotate about the z axis
- * @return this
- */
- public Quaternionf rotateYXZ(float angleY, float angleX, float angleZ) {
- return rotateYXZ(angleY, angleX, angleZ, this);
- }
-
- public Quaternionf rotateYXZ(float angleY, float angleX, float angleZ, Quaternionf dest) {
- float sx = Math.sin(angleX * 0.5f);
- float cx = Math.cosFromSin(sx, angleX * 0.5f);
- float sy = Math.sin(angleY * 0.5f);
- float cy = Math.cosFromSin(sy, angleY * 0.5f);
- float sz = Math.sin(angleZ * 0.5f);
- float cz = Math.cosFromSin(sz, angleZ * 0.5f);
-
- float yx = cy * sx;
- float yy = sy * cx;
- float yz = sy * sx;
- float yw = cy * cx;
- float x = yx * cz + yy * sz;
- float y = yy * cz - yx * sz;
- float z = yw * sz - yz * cz;
- float w = yw * cz + yz * sz;
- // right-multiply
- return dest.set(Math.fma(this.w, x, Math.fma(this.x, w, Math.fma(this.y, z, -this.z * y))),
- Math.fma(this.w, y, Math.fma(-this.x, z, Math.fma(this.y, w, this.z * x))),
- Math.fma(this.w, z, Math.fma(this.x, y, Math.fma(-this.y, x, this.z * w))),
- Math.fma(this.w, w, Math.fma(-this.x, x, Math.fma(-this.y, y, -this.z * z))));
- }
-
- public Vector3f getEulerAnglesXYZ(Vector3f eulerAngles) {
- eulerAngles.x = Math.atan2(x * w - y * z, 0.5f - x * x - y * y);
- eulerAngles.y = Math.safeAsin(2.0f * (x * z + y * w));
- eulerAngles.z = Math.atan2(z * w - x * y, 0.5f - y * y - z * z);
- return eulerAngles;
- }
-
- public Vector3f getEulerAnglesZYX(Vector3f eulerAngles) {
- eulerAngles.x = Math.atan2(y * z + w * x, 0.5f - x * x + y * y);
- eulerAngles.y = Math.safeAsin(-2.0f * (x * z - w * y));
- eulerAngles.z = Math.atan2(x * y + w * z, 0.5f - y * y - z * z);
- return eulerAngles;
- }
-
- public Vector3f getEulerAnglesZXY(Vector3f eulerAngles) {
- eulerAngles.x = Math.safeAsin(2.0f * (w * x + y * z));
- eulerAngles.y = Math.atan2(w * y - x * z, 0.5f - y * y - x * x);
- eulerAngles.z = Math.atan2(w * z - x * y, 0.5f - z * z - x * x);
- return eulerAngles;
- }
-
- public Vector3f getEulerAnglesYXZ(Vector3f eulerAngles) {
- eulerAngles.x = Math.safeAsin(-2.0f * (y * z - w * x));
- eulerAngles.y = Math.atan2(x * z + y * w, 0.5f - y * y - x * x);
- eulerAngles.z = Math.atan2(y * x + w * z, 0.5f - x * x - z * z);
- return eulerAngles;
- }
-
- public float lengthSquared() {
- return Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w)));
- }
-
- /**
- * Set this quaternion from the supplied euler angles (in radians) with rotation order XYZ.
- * rotationX(angleX).rotateY(angleY).rotateZ(angleZ)
- * rotationZ(angleZ).rotateY(angleY).rotateX(angleX)
- * rotationY(angleY).rotateX(angleX).rotateZ(angleZ)
- * this
{@link #normalize() unit} quaternion and the specified
- * target
{@link #normalize() unit} quaternion using spherical linear interpolation using the specified interpolation factor alpha
.
- * this
and target
is
- * below 1E-6f
.
- *
- * @param target
- * the target of the interpolation, which should be reached with alpha = 1.0
- * @param alpha
- * the interpolation factor, within [0..1]
- * @return this
- */
- public Quaternionf slerp(Quaternionfc target, float alpha) {
- return slerp(target, alpha, this);
- }
-
- public Quaternionf slerp(Quaternionfc target, float alpha, Quaternionf dest) {
- float cosom = Math.fma(x, target.x(), Math.fma(y, target.y(), Math.fma(z, target.z(), w * target.w())));
- float absCosom = Math.abs(cosom);
- float scale0, scale1;
- if (1.0f - absCosom > 1E-6f) {
- float sinSqr = 1.0f - absCosom * absCosom;
- float sinom = Math.invsqrt(sinSqr);
- float omega = Math.atan2(sinSqr * sinom, absCosom);
- scale0 = (float) (Math.sin((1.0 - alpha) * omega) * sinom);
- scale1 = (float) (Math.sin(alpha * omega) * sinom);
- } else {
- scale0 = 1.0f - alpha;
- scale1 = alpha;
- }
- scale1 = cosom >= 0.0f ? scale1 : -scale1;
- dest.x = Math.fma(scale0, x, scale1 * target.x());
- dest.y = Math.fma(scale0, y, scale1 * target.y());
- dest.z = Math.fma(scale0, z, scale1 * target.z());
- dest.w = Math.fma(scale0, w, scale1 * target.w());
- return dest;
- }
-
- /**
- * Interpolate between all of the quaternions given in qs
via spherical linear interpolation using the specified interpolation factors weights
,
- * and store the result in dest
.
- * 1E-6f
.
- * qs
- * @param dest
- * will hold the result
- * @return dest
- */
- public static Quaternionfc slerp(Quaternionf[] qs, float[] weights, Quaternionf dest) {
- dest.set(qs[0]);
- float w = weights[0];
- for (int i = 1; i < qs.length; i++) {
- float w0 = w;
- float w1 = weights[i];
- float rw1 = w1 / (w0 + w1);
- w += w1;
- dest.slerp(qs[i], rw1);
- }
- return dest;
- }
-
- /**
- * Apply scaling to this quaternion, which results in any vector transformed by this quaternion to change
- * its length by the given factor
.
- *
- * @param factor
- * the scaling factor
- * @return this
- */
- public Quaternionf scale(float factor) {
- return scale(factor, this);
- }
-
- public Quaternionf scale(float factor, Quaternionf dest) {
- float sqrt = Math.sqrt(factor);
- dest.x = sqrt * x;
- dest.y = sqrt * y;
- dest.z = sqrt * z;
- dest.w = sqrt * w;
- return dest;
- }
-
- /**
- * Set this quaternion to represent scaling, which results in a transformed vector to change
- * its length by the given factor
.
- *
- * @param factor
- * the scaling factor
- * @return this
- */
- public Quaternionf scaling(float factor) {
- float sqrt = Math.sqrt(factor);
- this.x = 0.0f;
- this.y = 0.0f;
- this.z = 0.0f;
- this.w = sqrt;
- return this;
- }
-
- /**
- * Integrate the rotation given by the angular velocity (vx, vy, vz)
around the x, y and z axis, respectively,
- * with respect to the given elapsed time delta dt
and add the differentiate rotation to the rotation represented by this quaternion.
- * dt
and (vx, vy, vz)
by this
, so
- * the angular velocities are always relative to the local coordinate system of the rotation represented by this
quaternion.
- * rotateLocal(dt * vx, dt * vy, dt * vz)
- * this
and the given quaternion q
- * and store the result in this
.
- *
- * @param q
- * the other quaternion
- * @param factor
- * the interpolation factor. It is between 0.0 and 1.0
- * @return this
- */
- public Quaternionf nlerp(Quaternionfc q, float factor) {
- return nlerp(q, factor, this);
- }
-
- public Quaternionf nlerp(Quaternionfc q, float factor, Quaternionf dest) {
- float cosom = Math.fma(x, q.x(), Math.fma(y, q.y(), Math.fma(z, q.z(), w * q.w())));
- float scale0 = 1.0f - factor;
- float scale1 = (cosom >= 0.0f) ? factor : -factor;
- dest.x = Math.fma(scale0, x, scale1 * q.x());
- dest.y = Math.fma(scale0, y, scale1 * q.y());
- dest.z = Math.fma(scale0, z, scale1 * q.z());
- dest.w = Math.fma(scale0, w, scale1 * q.w());
- float s = Math.invsqrt(Math.fma(dest.x, dest.x, Math.fma(dest.y, dest.y, Math.fma(dest.z, dest.z, dest.w * dest.w))));
- dest.x *= s;
- dest.y *= s;
- dest.z *= s;
- dest.w *= s;
- return dest;
- }
-
- /**
- * Interpolate between all of the quaternions given in qs
via non-spherical linear interpolation using the
- * specified interpolation factors weights
, and store the result in dest
.
- * qs
- * @param dest
- * will hold the result
- * @return dest
- */
- public static Quaternionfc nlerp(Quaternionfc[] qs, float[] weights, Quaternionf dest) {
- dest.set(qs[0]);
- float w = weights[0];
- for (int i = 1; i < qs.length; i++) {
- float w0 = w;
- float w1 = weights[i];
- float rw1 = w1 / (w0 + w1);
- w += w1;
- dest.nlerp(qs[i], rw1);
- }
- return dest;
- }
-
- public Quaternionf nlerpIterative(Quaternionfc q, float alpha, float dotThreshold, Quaternionf dest) {
- float q1x = x, q1y = y, q1z = z, q1w = w;
- float q2x = q.x(), q2y = q.y(), q2z = q.z(), q2w = q.w();
- float dot = Math.fma(q1x, q2x, Math.fma(q1y, q2y, Math.fma(q1z, q2z, q1w * q2w)));
- float absDot = Math.abs(dot);
- if (1.0f - 1E-6f < absDot) {
- return dest.set(this);
- }
- float alphaN = alpha;
- while (absDot < dotThreshold) {
- float scale0 = 0.5f;
- float scale1 = dot >= 0.0f ? 0.5f : -0.5f;
- if (alphaN < 0.5f) {
- q2x = Math.fma(scale0, q2x, scale1 * q1x);
- q2y = Math.fma(scale0, q2y, scale1 * q1y);
- q2z = Math.fma(scale0, q2z, scale1 * q1z);
- q2w = Math.fma(scale0, q2w, scale1 * q1w);
- float s = Math.invsqrt(Math.fma(q2x, q2x, Math.fma(q2y, q2y, Math.fma(q2z, q2z, q2w * q2w))));
- q2x *= s;
- q2y *= s;
- q2z *= s;
- q2w *= s;
- alphaN = alphaN + alphaN;
- } else {
- q1x = Math.fma(scale0, q1x, scale1 * q2x);
- q1y = Math.fma(scale0, q1y, scale1 * q2y);
- q1z = Math.fma(scale0, q1z, scale1 * q2z);
- q1w = Math.fma(scale0, q1w, scale1 * q2w);
- float s = Math.invsqrt(Math.fma(q1x, q1x, Math.fma(q1y, q1y, Math.fma(q1z, q1z, q1w * q1w))));
- q1x *= s;
- q1y *= s;
- q1z *= s;
- q1w *= s;
- alphaN = alphaN + alphaN - 1.0f;
- }
- dot = Math.fma(q1x, q2x, Math.fma(q1y, q2y, Math.fma(q1z, q2z, q1w * q2w)));
- absDot = Math.abs(dot);
- }
- float scale0 = 1.0f - alphaN;
- float scale1 = dot >= 0.0f ? alphaN : -alphaN;
- float resX = Math.fma(scale0, q1x, scale1 * q2x);
- float resY = Math.fma(scale0, q1y, scale1 * q2y);
- float resZ = Math.fma(scale0, q1z, scale1 * q2z);
- float resW = Math.fma(scale0, q1w, scale1 * q2w);
- float s = Math.invsqrt(Math.fma(resX, resX, Math.fma(resY, resY, Math.fma(resZ, resZ, resW * resW))));
- dest.x = resX * s;
- dest.y = resY * s;
- dest.z = resZ * s;
- dest.w = resW * s;
- return dest;
- }
-
- /**
- * Compute linear (non-spherical) interpolations of this
and the given quaternion q
- * iteratively and store the result in this
.
- * this
and q
via non-spherical linear interpolations as long as
- * the absolute dot product of this
and q
is greater than the given dotThreshold
parameter.
- * @theagentd
at http://www.java-gaming.org/ for providing the code.
- *
- * @param q
- * the other quaternion
- * @param alpha
- * the interpolation factor, between 0.0 and 1.0
- * @param dotThreshold
- * the threshold for the dot product of this
and q
above which this method performs another iteration
- * of a small-step linear interpolation
- * @return this
- */
- public Quaternionf nlerpIterative(Quaternionfc q, float alpha, float dotThreshold) {
- return nlerpIterative(q, alpha, dotThreshold, this);
- }
-
- /**
- * Interpolate between all of the quaternions given in qs
via iterative non-spherical linear interpolation using the
- * specified interpolation factors weights
, and store the result in dest
.
- * qs
- * @param dotThreshold
- * the threshold for the dot product of each two interpolated quaternions above which {@link #nlerpIterative(Quaternionfc, float, float)} performs another iteration
- * of a small-step linear interpolation
- * @param dest
- * will hold the result
- * @return dest
- */
- public static Quaternionfc nlerpIterative(Quaternionf[] qs, float[] weights, float dotThreshold, Quaternionf dest) {
- dest.set(qs[0]);
- float w = weights[0];
- for (int i = 1; i < qs.length; i++) {
- float w0 = w;
- float w1 = weights[i];
- float rw1 = w1 / (w0 + w1);
- w += w1;
- dest.nlerpIterative(qs[i], rw1, dotThreshold);
- }
- return dest;
- }
-
- /**
- * Apply a rotation to this quaternion that maps the given direction to the positive Z axis.
- * up
and dir
vectors.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- * dir
and up
- * @return this
- */
- public Quaternionf lookAlong(Vector3fc dir, Vector3fc up) {
- return lookAlong(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z(), this);
- }
-
- public Quaternionf lookAlong(Vector3fc dir, Vector3fc up, Quaternionf dest) {
- return lookAlong(dir.x(), dir.y(), dir.z(), up.x(), up.y(), up.z(), dest);
- }
-
- /**
- * Apply a rotation to this quaternion that maps the given direction to the positive Z axis.
- * up
and dir
vectors.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- * this
quaternion to a rotation that rotates the fromDir
vector to point along toDir
.
- * this
quaternion to a rotation that rotates the fromDir
vector to point along toDir
.
- * this
that rotates the fromDir
vector to point along toDir
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @see #rotateTo(float, float, float, float, float, float, Quaternionf)
- *
- * @param fromDirX
- * the x-coordinate of the direction to rotate into the destination direction
- * @param fromDirY
- * the y-coordinate of the direction to rotate into the destination direction
- * @param fromDirZ
- * the z-coordinate of the direction to rotate into the destination direction
- * @param toDirX
- * the x-coordinate of the direction to rotate to
- * @param toDirY
- * the y-coordinate of the direction to rotate to
- * @param toDirZ
- * the z-coordinate of the direction to rotate to
- * @return this
- */
- public Quaternionf rotateTo(float fromDirX, float fromDirY, float fromDirZ, float toDirX, float toDirY, float toDirZ) {
- return rotateTo(fromDirX, fromDirY, fromDirZ, toDirX, toDirY, toDirZ, this);
- }
-
- public Quaternionf rotateTo(Vector3fc fromDir, Vector3fc toDir, Quaternionf dest) {
- return rotateTo(fromDir.x(), fromDir.y(), fromDir.z(), toDir.x(), toDir.y(), toDir.z(), dest);
- }
-
- /**
- * Apply a rotation to this
that rotates the fromDir
vector to point along toDir
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @see #rotateTo(float, float, float, float, float, float, Quaternionf)
- *
- * @param fromDir
- * the starting direction
- * @param toDir
- * the destination direction
- * @return this
- */
- public Quaternionf rotateTo(Vector3fc fromDir, Vector3fc toDir) {
- return rotateTo(fromDir.x(), fromDir.y(), fromDir.z(), toDir.x(), toDir.y(), toDir.z(), this);
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the x axis.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the x axis
- * @return this
- */
- public Quaternionf rotateX(float angle) {
- return rotateX(angle, this);
- }
-
- public Quaternionf rotateX(float angle, Quaternionf dest) {
- float sin = Math.sin(angle * 0.5f);
- float cos = Math.cosFromSin(sin, angle * 0.5f);
- return dest.set(w * sin + x * cos,
- y * cos + z * sin,
- z * cos - y * sin,
- w * cos - x * sin);
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the y axis.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the y axis
- * @return this
- */
- public Quaternionf rotateY(float angle) {
- return rotateY(angle, this);
- }
-
- public Quaternionf rotateY(float angle, Quaternionf dest) {
- float sin = Math.sin(angle * 0.5f);
- float cos = Math.cosFromSin(sin, angle * 0.5f);
- return dest.set(x * cos - z * sin,
- w * sin + y * cos,
- x * sin + z * cos,
- w * cos - y * sin);
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the z axis.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the z axis
- * @return this
- */
- public Quaternionf rotateZ(float angle) {
- return rotateZ(angle, this);
- }
-
- public Quaternionf rotateZ(float angle, Quaternionf dest) {
- float sin = Math.sin(angle * 0.5f);
- float cos = Math.cosFromSin(sin, angle * 0.5f);
- return dest.set(x * cos + y * sin,
- y * cos - x * sin,
- w * sin + z * cos,
- w * cos - z * sin);
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the local x axis.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be R * Q
. So when transforming a
- * vector v
with the new quaternion by using R * Q * v
, the
- * rotation represented by this
will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the local x axis
- * @return this
- */
- public Quaternionf rotateLocalX(float angle) {
- return rotateLocalX(angle, this);
- }
-
- public Quaternionf rotateLocalX(float angle, Quaternionf dest) {
- float hangle = angle * 0.5f;
- float s = Math.sin(hangle);
- float c = Math.cosFromSin(s, hangle);
- dest.set(c * x + s * w,
- c * y - s * z,
- c * z + s * y,
- c * w - s * x);
- return dest;
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the local y axis.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be R * Q
. So when transforming a
- * vector v
with the new quaternion by using R * Q * v
, the
- * rotation represented by this
will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the local y axis
- * @return this
- */
- public Quaternionf rotateLocalY(float angle) {
- return rotateLocalY(angle, this);
- }
-
- public Quaternionf rotateLocalY(float angle, Quaternionf dest) {
- float hangle = angle * 0.5f;
- float s = Math.sin(hangle);
- float c = Math.cosFromSin(s, hangle);
- dest.set(c * x + s * z,
- c * y + s * w,
- c * z - s * x,
- c * w - s * y);
- return dest;
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the local z axis.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be R * Q
. So when transforming a
- * vector v
with the new quaternion by using R * Q * v
, the
- * rotation represented by this
will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the local z axis
- * @return this
- */
- public Quaternionf rotateLocalZ(float angle) {
- return rotateLocalZ(angle, this);
- }
-
- public Quaternionf rotateLocalZ(float angle, Quaternionf dest) {
- float hangle = angle * 0.5f;
- float s = Math.sin(hangle);
- float c = Math.cosFromSin(s, hangle);
- dest.set(c * x - s * y,
- c * y + s * x,
- c * z + s * w,
- c * w - s * z);
- return dest;
- }
-
- public Quaternionf rotateAxis(float angle, float axisX, float axisY, float axisZ, Quaternionf dest) {
- float hangle = angle / 2.0f;
- float sinAngle = Math.sin(hangle);
- float invVLength = Math.invsqrt(Math.fma(axisX, axisX, Math.fma(axisY, axisY, axisZ * axisZ)));
- float rx = axisX * invVLength * sinAngle;
- float ry = axisY * invVLength * sinAngle;
- float rz = axisZ * invVLength * sinAngle;
- float rw = Math.cosFromSin(sinAngle, hangle);
- return dest.set(Math.fma(this.w, rx, Math.fma(this.x, rw, Math.fma(this.y, rz, -this.z * ry))),
- Math.fma(this.w, ry, Math.fma(-this.x, rz, Math.fma(this.y, rw, this.z * rx))),
- Math.fma(this.w, rz, Math.fma(this.x, ry, Math.fma(-this.y, rx, this.z * rw))),
- Math.fma(this.w, rw, Math.fma(-this.x, rx, Math.fma(-this.y, ry, -this.z * rz))));
- }
-
- public Quaternionf rotateAxis(float angle, Vector3fc axis, Quaternionf dest) {
- return rotateAxis(angle, axis.x(), axis.y(), axis.z(), dest);
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the specified axis.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @see #rotateAxis(float, float, float, float, Quaternionf)
- *
- * @param angle
- * the angle in radians to rotate about the specified axis
- * @param axis
- * the rotation axis
- * @return this
- */
- public Quaternionf rotateAxis(float angle, Vector3fc axis) {
- return rotateAxis(angle, axis.x(), axis.y(), axis.z(), this);
- }
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the specified axis.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @see #rotateAxis(float, float, float, float, Quaternionf)
- *
- * @param angle
- * the angle in radians to rotate about the specified axis
- * @param axisX
- * the x coordinate of the rotation axis
- * @param axisY
- * the y coordinate of the rotation axis
- * @param axisZ
- * the z coordinate of the rotation axis
- * @return this
- */
- public Quaternionf rotateAxis(float angle, float axisX, float axisY, float axisZ) {
- return rotateAxis(angle, axisX, axisY, axisZ, this);
- }
-
- /**
- * Return a string representation of this quaternion.
- * 0.000E0;-
".
- *
- * @return the string representation
- */
- public String toString() {
- return Runtime.formatNumbers(toString(Options.NUMBER_FORMAT));
- }
-
- /**
- * Return a string representation of this quaternion by formatting the components with the given {@link NumberFormat}.
- *
- * @param formatter
- * the {@link NumberFormat} used to format the quaternion components with
- * @return the string representation
- */
- public String toString(NumberFormat formatter) {
- return "(" + Runtime.format(x, formatter) + " " + Runtime.format(y, formatter) + " " + Runtime.format(z, formatter) + " " + Runtime.format(w, formatter) + ")";
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeFloat(x);
- out.writeFloat(y);
- out.writeFloat(z);
- out.writeFloat(w);
- }
-
- public void readExternal(ObjectInput in) throws IOException,
- ClassNotFoundException {
- x = in.readFloat();
- y = in.readFloat();
- z = in.readFloat();
- w = in.readFloat();
- }
-
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Float.floatToIntBits(w);
- result = prime * result + Float.floatToIntBits(x);
- result = prime * result + Float.floatToIntBits(y);
- result = prime * result + Float.floatToIntBits(z);
- return result;
- }
-
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Quaternionf other = (Quaternionf) obj;
- if (Float.floatToIntBits(w) != Float.floatToIntBits(other.w))
- return false;
- if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x))
- return false;
- if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y))
- return false;
- if (Float.floatToIntBits(z) != Float.floatToIntBits(other.z))
- return false;
- return true;
- }
-
- /**
- * Compute the difference between this
and the other
quaternion
- * and store the result in this
.
- * this
rotation to other
. If T
is this
, Q
- * is other
and D
is the computed difference, then the following equation holds:
- * T * D = Q
- * D = T^-1 * Q
, where T^-1
denotes the {@link #invert() inverse} of T
.
- *
- * @param other
- * the other quaternion
- * @return this
- */
- public Quaternionf difference(Quaternionf other) {
- return difference(other, this);
- }
-
- public Quaternionf difference(Quaternionfc other, Quaternionf dest) {
- float invNorm = 1.0f / lengthSquared();
- float x = -this.x * invNorm;
- float y = -this.y * invNorm;
- float z = -this.z * invNorm;
- float w = this.w * invNorm;
- dest.set(Math.fma(w, other.x(), Math.fma(x, other.w(), Math.fma(y, other.z(), -z * other.y()))),
- Math.fma(w, other.y(), Math.fma(-x, other.z(), Math.fma(y, other.w(), z * other.x()))),
- Math.fma(w, other.z(), Math.fma(x, other.y(), Math.fma(-y, other.x(), z * other.w()))),
- Math.fma(w, other.w(), Math.fma(-x, other.x(), Math.fma(-y, other.y(), -z * other.z()))));
- return dest;
- }
-
- public Vector3f positiveX(Vector3f dir) {
- float invNorm = 1.0f / lengthSquared();
- float nx = -x * invNorm;
- float ny = -y * invNorm;
- float nz = -z * invNorm;
- float nw = w * invNorm;
- float dy = ny + ny;
- float dz = nz + nz;
- dir.x = -ny * dy - nz * dz + 1.0f;
- dir.y = nx * dy + nw * dz;
- dir.z = nx * dz - nw * dy;
- return dir;
- }
-
- public Vector3f normalizedPositiveX(Vector3f dir) {
- float dy = y + y;
- float dz = z + z;
- dir.x = -y * dy - z * dz + 1.0f;
- dir.y = x * dy - w * dz;
- dir.z = x * dz + w * dy;
- return dir;
- }
-
- public Vector3f positiveY(Vector3f dir) {
- float invNorm = 1.0f / lengthSquared();
- float nx = -x * invNorm;
- float ny = -y * invNorm;
- float nz = -z * invNorm;
- float nw = w * invNorm;
- float dx = nx + nx;
- float dy = ny + ny;
- float dz = nz + nz;
- dir.x = nx * dy - nw * dz;
- dir.y = -nx * dx - nz * dz + 1.0f;
- dir.z = ny * dz + nw * dx;
- return dir;
- }
-
- public Vector3f normalizedPositiveY(Vector3f dir) {
- float dx = x + x;
- float dy = y + y;
- float dz = z + z;
- dir.x = x * dy + w * dz;
- dir.y = -x * dx - z * dz + 1.0f;
- dir.z = y * dz - w * dx;
- return dir;
- }
-
- public Vector3f positiveZ(Vector3f dir) {
- float invNorm = 1.0f / lengthSquared();
- float nx = -x * invNorm;
- float ny = -y * invNorm;
- float nz = -z * invNorm;
- float nw = w * invNorm;
- float dx = nx + nx;
- float dy = ny + ny;
- float dz = nz + nz;
- dir.x = nx * dz + nw * dy;
- dir.y = ny * dz - nw * dx;
- dir.z = -nx * dx - ny * dy + 1.0f;
- return dir;
- }
-
- public Vector3f normalizedPositiveZ(Vector3f dir) {
- float dx = x + x;
- float dy = y + y;
- float dz = z + z;
- dir.x = x * dz - w * dy;
- dir.y = y * dz + w * dx;
- dir.z = -x * dx - y * dy + 1.0f;
- return dir;
- }
-
- /**
- * Conjugate this
by the given quaternion q
by computing q * this * q^-1
.
- *
- * @param q
- * the {@link Quaternionfc} to conjugate this
by
- * @return this
- */
- public Quaternionf conjugateBy(Quaternionfc q) {
- return conjugateBy(q, this);
- }
-
- /**
- * Conjugate this
by the given quaternion q
by computing q * this * q^-1
- * and store the result into dest
.
- *
- * @param q
- * the {@link Quaternionfc} to conjugate this
by
- * @param dest
- * will hold the result
- * @return dest
- */
- public Quaternionf conjugateBy(Quaternionfc q, Quaternionf dest) {
- float invNorm = 1.0f / q.lengthSquared();
- float qix = -q.x() * invNorm, qiy = -q.y() * invNorm, qiz = -q.z() * invNorm, qiw = q.w() * invNorm;
- float qpx = Math.fma(q.w(), x, Math.fma(q.x(), w, Math.fma(q.y(), z, -q.z() * y)));
- float qpy = Math.fma(q.w(), y, Math.fma(-q.x(), z, Math.fma(q.y(), w, q.z() * x)));
- float qpz = Math.fma(q.w(), z, Math.fma(q.x(), y, Math.fma(-q.y(), x, q.z() * w)));
- float qpw = Math.fma(q.w(), w, Math.fma(-q.x(), x, Math.fma(-q.y(), y, -q.z() * z)));
- return dest.set(Math.fma(qpw, qix, Math.fma(qpx, qiw, Math.fma(qpy, qiz, -qpz * qiy))),
- Math.fma(qpw, qiy, Math.fma(-qpx, qiz, Math.fma(qpy, qiw, qpz * qix))),
- Math.fma(qpw, qiz, Math.fma(qpx, qiy, Math.fma(-qpy, qix, qpz * qiw))),
- Math.fma(qpw, qiw, Math.fma(-qpx, qix, Math.fma(-qpy, qiy, -qpz * qiz))));
- }
-
- public boolean isFinite() {
- return Math.isFinite(x) && Math.isFinite(y) && Math.isFinite(z) && Math.isFinite(w);
- }
-
- public boolean equals(Quaternionfc q, float delta) {
- if (this == q)
- return true;
- if (q == null)
- return false;
- if (!(q instanceof Quaternionfc))
- return false;
- if (!Runtime.equals(x, q.x(), delta))
- return false;
- if (!Runtime.equals(y, q.y(), delta))
- return false;
- if (!Runtime.equals(z, q.z(), delta))
- return false;
- if (!Runtime.equals(w, q.w(), delta))
- return false;
- return true;
- }
-
- public boolean equals(float x, float y, float z, float w) {
- if (Float.floatToIntBits(this.x) != Float.floatToIntBits(x))
- return false;
- if (Float.floatToIntBits(this.y) != Float.floatToIntBits(y))
- return false;
- if (Float.floatToIntBits(this.z) != Float.floatToIntBits(z))
- return false;
- if (Float.floatToIntBits(this.w) != Float.floatToIntBits(w))
- return false;
- return true;
- }
-
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/QuaternionfInterpolator.java b/src/main/java/com/jozufozu/flywheel/util/joml/QuaternionfInterpolator.java
deleted file mode 100644
index 2fcf2c988..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/QuaternionfInterpolator.java
+++ /dev/null
@@ -1,354 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2016-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-/**
- * Computes the weighted average of multiple rotations represented as {@link Quaternionf} instances.
- * qs
using the specified interpolation factors weights
, and store the result in dest
.
- *
- * @param qs
- * the quaternions to interpolate over
- * @param weights
- * the weights of each individual quaternion in qs
- * @param maxSvdIterations
- * the maximum number of iterations in the Singular Value Decomposition step used by this method
- * @param dest
- * will hold the result
- * @return dest
- */
- public Quaternionf computeWeightedAverage(Quaternionfc[] qs, float[] weights, int maxSvdIterations, Quaternionf dest) {
- float m00 = 0.0f, m01 = 0.0f, m02 = 0.0f;
- float m10 = 0.0f, m11 = 0.0f, m12 = 0.0f;
- float m20 = 0.0f, m21 = 0.0f, m22 = 0.0f;
- // Sum the rotation matrices of qs
- for (int i = 0; i < qs.length; i++) {
- Quaternionfc q = qs[i];
- float dx = q.x() + q.x();
- float dy = q.y() + q.y();
- float dz = q.z() + q.z();
- float q00 = dx * q.x();
- float q11 = dy * q.y();
- float q22 = dz * q.z();
- float q01 = dx * q.y();
- float q02 = dx * q.z();
- float q03 = dx * q.w();
- float q12 = dy * q.z();
- float q13 = dy * q.w();
- float q23 = dz * q.w();
- m00 += weights[i] * (1.0f - q11 - q22);
- m01 += weights[i] * (q01 + q23);
- m02 += weights[i] * (q02 - q13);
- m10 += weights[i] * (q01 - q23);
- m11 += weights[i] * (1.0f - q22 - q00);
- m12 += weights[i] * (q12 + q03);
- m20 += weights[i] * (q02 + q13);
- m21 += weights[i] * (q12 - q03);
- m22 += weights[i] * (1.0f - q11 - q00);
- }
- m[0] = m00;
- m[1] = m01;
- m[2] = m02;
- m[3] = m10;
- m[4] = m11;
- m[5] = m12;
- m[6] = m20;
- m[7] = m21;
- m[8] = m22;
- // Compute the Singular Value Decomposition of 'm'
- svdDecomposition3f.svd(m, maxSvdIterations, u, v);
- // Compute rotation matrix
- u.mul(v.transpose());
- // Build quaternion from it
- return dest.setFromNormalized(u).normalize();
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Quaternionfc.java b/src/main/java/com/jozufozu/flywheel/util/joml/Quaternionfc.java
deleted file mode 100644
index 616dc7767..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Quaternionfc.java
+++ /dev/null
@@ -1,1500 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.util.*;
-
-/**
- * Interface to a read-only view of a quaternion of single-precision floats.
- *
- * @author Kai Burjack
- */
-public interface Quaternionfc {
-
- /**
- * @return the first component of the vector part
- */
- float x();
-
- /**
- * @return the second component of the vector part
- */
- float y();
-
- /**
- * @return the third component of the vector part
- */
- float z();
-
- /**
- * @return the real/scalar part of the quaternion
- */
- float w();
-
- /**
- * Normalize this quaternion and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf normalize(Quaternionf dest);
-
- /**
- * Add the quaternion (x, y, z, w)
to this quaternion and store the result in dest
.
- *
- * @param x
- * the x component of the vector part
- * @param y
- * the y component of the vector part
- * @param z
- * the z component of the vector part
- * @param w
- * the real/scalar component
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf add(float x, float y, float z, float w, Quaternionf dest);
-
- /**
- * Add q2
to this quaternion and store the result in dest
.
- *
- * @param q2
- * the quaternion to add to this
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf add(Quaternionfc q2, Quaternionf dest);
-
- /**
- * Return the angle in radians represented by this normalized quaternion rotation.
- * this
.
- *
- * @see Matrix3f#set(Quaternionfc)
- *
- * @param dest
- * the matrix to write the rotation into
- * @return the passed in destination
- */
- Matrix3f get(Matrix3f dest);
-
- /**
- * Set the given destination matrix to the rotation represented by this
.
- *
- * @see Matrix4f#set(Quaternionfc)
- *
- * @param dest
- * the matrix to write the rotation into
- * @return the passed in destination
- */
- Matrix4f get(Matrix4f dest);
-
- /**
- * Set the given {@link AxisAngle4f} to represent the rotation of
- * this
quaternion.
- *
- * @param dest
- * the {@link AxisAngle4f} to set
- * @return the passed in destination
- */
- AxisAngle4f get(AxisAngle4f dest);
-
- /**
- * Set the given {@link Quaternionf} to the values of this
.
- *
- * @param dest
- * the {@link Quaternionf} to set
- * @return the passed in destination
- */
- Quaternionf get(Quaternionf dest);
-
- /**
- * Store the 3x3 float matrix representation of this
quaternion in column-major order into the given {@link ByteBuffer}.
- * this.get(new Matrix3f()).get(dest)
- *
- * @param dest
- * the destination buffer
- * @return dest
- */
- ByteBuffer getAsMatrix3f(ByteBuffer dest);
-
- /**
- * Store the 3x3 float matrix representation of this
quaternion in column-major order into the given {@link FloatBuffer}.
- * this.get(new Matrix3f()).get(dest)
- *
- * @param dest
- * the destination buffer
- * @return dest
- */
- FloatBuffer getAsMatrix3f(FloatBuffer dest);
-
- /**
- * Store the 4x4 float matrix representation of this
quaternion in column-major order into the given {@link ByteBuffer}.
- * this.get(new Matrix4f()).get(dest)
- *
- * @param dest
- * the destination buffer
- * @return dest
- */
- ByteBuffer getAsMatrix4f(ByteBuffer dest);
-
- /**
- * Store the 4x4 float matrix representation of this
quaternion in column-major order into the given {@link FloatBuffer}.
- * this.get(new Matrix4f()).get(dest)
- *
- * @param dest
- * the destination buffer
- * @return dest
- */
- FloatBuffer getAsMatrix4f(FloatBuffer dest);
-
- /**
- * Store the 4x3 float matrix representation of this
quaternion in column-major order into the given {@link ByteBuffer}.
- * this.get(new Matrix4x3f()).get(dest)
- *
- * @param dest
- * the destination buffer
- * @return dest
- */
- ByteBuffer getAsMatrix4x3f(ByteBuffer dest);
-
- /**
- * Store the 4x3 float matrix representation of this
quaternion in column-major order into the given {@link FloatBuffer}.
- * this.get(new Matrix4x3f()).get(dest)
- *
- * @param dest
- * the destination buffer
- * @return dest
- */
- FloatBuffer getAsMatrix4x3f(FloatBuffer dest);
-
- /**
- * Multiply this quaternion by q
and store the result in dest
.
- * T
is this
and Q
is the given
- * quaternion, then the resulting quaternion R
is:
- * R = T * Q
- * Q
first, and then by T
.
- *
- * @param q
- * the quaternion to multiply this
by
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf mul(Quaternionfc q, Quaternionf dest);
-
- /**
- * Multiply this quaternion by the quaternion represented via (qx, qy, qz, qw)
and store the result in dest
.
- * T
is this
and Q
is the given
- * quaternion, then the resulting quaternion R
is:
- * R = T * Q
- * Q
first, and then by T
.
- *
- * @param qx
- * the x component of the quaternion to multiply this
by
- * @param qy
- * the y component of the quaternion to multiply this
by
- * @param qz
- * the z component of the quaternion to multiply this
by
- * @param qw
- * the w component of the quaternion to multiply this
by
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf mul(float qx, float qy, float qz, float qw, Quaternionf dest);
-
- /**
- * Pre-multiply this quaternion by q
and store the result in dest
.
- * T
is this
and Q
is the given quaternion, then the resulting quaternion R
is:
- * R = Q * T
- * T
first, and then by Q
.
- *
- * @param q
- * the quaternion to pre-multiply this
by
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf premul(Quaternionfc q, Quaternionf dest);
-
- /**
- * Pre-multiply this quaternion by the quaternion represented via (qx, qy, qz, qw)
and store the result in dest
.
- * T
is this
and Q
is the given quaternion, then the resulting quaternion R
is:
- * R = Q * T
- * T
first, and then by Q
.
- *
- * @param qx
- * the x component of the quaternion to multiply this
by
- * @param qy
- * the y component of the quaternion to multiply this
by
- * @param qz
- * the z component of the quaternion to multiply this
by
- * @param qw
- * the w component of the quaternion to multiply this
by
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf premul(float qx, float qy, float qz, float qw, Quaternionf dest);
-
- /**
- * Transform the given vector by this quaternion.
- * this
is a unit quaternion.
- *
- * @param vec
- * the vector to transform
- * @return vec
- */
- Vector3f transformUnit(Vector3f vec);
-
- /**
- * Transform the vector (1, 0, 0)
by this quaternion.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformPositiveX(Vector3f dest);
-
- /**
- * Transform the vector (1, 0, 0)
by this quaternion.
- * (1, 0, 0)
by this unit quaternion.
- * this
is a unit quaternion.
- * (1, 0, 0)
by this unit quaternion.
- * this
is a unit quaternion.
- * (0, 1, 0)
by this quaternion.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformPositiveY(Vector3f dest);
-
- /**
- * Transform the vector (0, 1, 0)
by this quaternion.
- * (0, 1, 0)
by this unit quaternion.
- * this
is a unit quaternion.
- * (0, 1, 0)
by this unit quaternion.
- * this
is a unit quaternion.
- * (0, 0, 1)
by this quaternion.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformPositiveZ(Vector3f dest);
-
- /**
- * Transform the vector (0, 0, 1)
by this quaternion.
- * (0, 0, 1)
by this unit quaternion.
- * this
is a unit quaternion.
- * (0, 0, 1)
by this unit quaternion.
- * this
is a unit quaternion.
- * dest
.
- * dest
.
- * (x, y, z)
by this quaternion
- * and store the result in dest
.
- * (x, y, z)
by the inverse of this quaternion
- * and store the result in dest
.
- * this
is a unit quaternion.
- *
- * @param vec
- * the vector to transform
- * @return vec
- */
- Vector3f transformInverseUnit(Vector3f vec);
-
- /**
- * Transform the given vector by this unit quaternion
- * and store the result in dest
.
- * this
is a unit quaternion.
- *
- * @param vec
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformUnit(Vector3fc vec, Vector3f dest);
-
- /**
- * Transform the given vector by the inverse of this unit quaternion
- * and store the result in dest
.
- * this
is a unit quaternion.
- *
- * @param vec
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformInverseUnit(Vector3fc vec, Vector3f dest);
-
- /**
- * Transform the given vector (x, y, z)
by this unit quaternion
- * and store the result in dest
.
- * this
is a unit quaternion.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformUnit(float x, float y, float z, Vector3f dest);
-
- /**
- * Transform the given vector (x, y, z)
by the inverse of this unit quaternion
- * and store the result in dest
.
- * this
is a unit quaternion.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f transformInverseUnit(float x, float y, float z, Vector3f dest);
-
- /**
- * Transform the given vector by this quaternion and store the result in dest
.
- * dest
.
- * (x, y, z)
by this quaternion and store the result in dest
.
- * (x, y, z)
by the inverse of
- * this quaternion and store the result in dest
.
- * dest
.
- * this
is a unit quaternion.
- *
- * @param vec
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformUnit(Vector4fc vec, Vector4f dest);
-
- /**
- * Transform the given vector by this unit quaternion.
- * this
is a unit quaternion.
- *
- * @param vec
- * the vector to transform
- * @return vec
- */
- Vector4f transformUnit(Vector4f vec);
-
- /**
- * Transform the given vector by the inverse of this unit quaternion.
- * this
is a unit quaternion.
- *
- * @param vec
- * the vector to transform
- * @return vec
- */
- Vector4f transformInverseUnit(Vector4f vec);
-
- /**
- * Transform the given vector by the inverse of this unit quaternion and store the result in dest
.
- * this
is a unit quaternion.
- *
- * @param vec
- * the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformInverseUnit(Vector4fc vec, Vector4f dest);
-
- /**
- * Transform the given vector (x, y, z)
by this unit quaternion and store the result in dest
.
- * this
is a unit quaternion.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformUnit(float x, float y, float z, Vector4f dest);
-
- /**
- * Transform the given vector (x, y, z)
by the inverse of
- * this unit quaternion and store the result in dest
.
- * this
is a unit quaternion.
- *
- * @param x
- * the x coordinate of the vector to transform
- * @param y
- * the y coordinate of the vector to transform
- * @param z
- * the z coordinate of the vector to transform
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f transformInverseUnit(float x, float y, float z, Vector4f dest);
-
- /**
- * Invert this quaternion and store the {@link #normalize(Quaternionf) normalized} result in dest
.
- * this
quaternion by b
and store the result in dest
.
- * dest = this * b^-1
, where b^-1
is the inverse of b
.
- *
- * @param b
- * the {@link Quaternionfc} to divide this by
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf div(Quaternionfc b, Quaternionf dest);
-
- /**
- * Conjugate this quaternion and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf conjugate(Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the cartesian base unit axes,
- * called the euler angles using rotation sequence XYZ
and store the result in dest
.
- * rotateX(angleX, dest).rotateY(angleY).rotateZ(angleZ)
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angleX
- * the angle in radians to rotate about the x axis
- * @param angleY
- * the angle in radians to rotate about the y axis
- * @param angleZ
- * the angle in radians to rotate about the z axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateXYZ(float angleX, float angleY, float angleZ, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the cartesian base unit axes,
- * called the euler angles, using the rotation sequence ZYX
and store the result in dest
.
- * rotateZ(angleZ, dest).rotateY(angleY).rotateX(angleX)
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angleZ
- * the angle in radians to rotate about the z axis
- * @param angleY
- * the angle in radians to rotate about the y axis
- * @param angleX
- * the angle in radians to rotate about the x axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateZYX(float angleZ, float angleY, float angleX, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the cartesian base unit axes,
- * called the euler angles, using the rotation sequence YXZ
and store the result in dest
.
- * rotateY(angleY, dest).rotateX(angleX).rotateZ(angleZ)
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angleY
- * the angle in radians to rotate about the y axis
- * @param angleX
- * the angle in radians to rotate about the x axis
- * @param angleZ
- * the angle in radians to rotate about the z axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateYXZ(float angleY, float angleX, float angleZ, Quaternionf dest);
-
- /**
- * Get the euler angles in radians in rotation sequence XYZ
of this quaternion and store them in the
- * provided parameter eulerAngles
.
- * ZYX
of this quaternion and store them in the
- * provided parameter eulerAngles
.
- * ZXY
of this quaternion and store them in the
- * provided parameter eulerAngles
.
- * YXZ
of this quaternion and store them in the
- * provided parameter eulerAngles
.
- * this
{@link #normalize(Quaternionf) unit} quaternion and the specified
- * target
{@link #normalize(Quaternionf) unit} quaternion using spherical linear interpolation using the specified interpolation factor alpha
,
- * and store the result in dest
.
- * this
and target
is
- * below 1E-6f
.
- * alpha = 1.0
- * @param alpha
- * the interpolation factor, within [0..1]
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf slerp(Quaternionfc target, float alpha, Quaternionf dest);
-
- /**
- * Apply scaling to this quaternion, which results in any vector transformed by the quaternion to change
- * its length by the given factor
, and store the result in dest
.
- *
- * @param factor
- * the scaling factor
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf scale(float factor, Quaternionf dest);
-
- /**
- * Integrate the rotation given by the angular velocity (vx, vy, vz)
around the x, y and z axis, respectively,
- * with respect to the given elapsed time delta dt
and add the differentiate rotation to the rotation represented by this quaternion
- * and store the result into dest
.
- * dt
and (vx, vy, vz)
by this
, so
- * the angular velocities are always relative to the local coordinate system of the rotation represented by this
quaternion.
- * rotateLocal(dt * vx, dt * vy, dt * vz, dest)
- * this
and the given quaternion q
- * and store the result in dest
.
- * this
and the given quaternion q
- * iteratively and store the result in dest
.
- * this
and q
via non-spherical linear interpolations as long as
- * the absolute dot product of this
and q
is greater than the given dotThreshold
parameter.
- * @theagentd
at http://www.java-gaming.org/ for providing the code.
- *
- * @param q
- * the other quaternion
- * @param alpha
- * the interpolation factor, between 0.0 and 1.0
- * @param dotThreshold
- * the threshold for the dot product of this
and q
above which this method performs another iteration
- * of a small-step linear interpolation
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf nlerpIterative(Quaternionfc q, float alpha, float dotThreshold, Quaternionf dest);
-
- /**
- * Apply a rotation to this quaternion that maps the given direction to the positive Z axis, and store the result in dest
.
- * up
and dir
vectors.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- * dir
and up
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf lookAlong(Vector3fc dir, Vector3fc up, Quaternionf dest);
-
- /**
- * Apply a rotation to this quaternion that maps the given direction to the positive Z axis, and store the result in dest
.
- * up
and dir
vectors.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- * this
that rotates the fromDir
vector to point along toDir
and
- * store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- * this
that rotates the fromDir
vector to point along toDir
and
- * store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @see #rotateTo(float, float, float, float, float, float, Quaternionf)
- *
- * @param fromDir
- * the starting direction
- * @param toDir
- * the destination direction
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateTo(Vector3fc fromDir, Vector3fc toDir, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the x axis
- * and store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the x axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateX(float angle, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the y axis
- * and store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the y axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateY(float angle, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the z axis
- * and store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the z axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateZ(float angle, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the local x axis
- * and store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be R * Q
. So when transforming a
- * vector v
with the new quaternion by using R * Q * v
, the
- * rotation represented by this
will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the local x axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateLocalX(float angle, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the local y axis
- * and store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be R * Q
. So when transforming a
- * vector v
with the new quaternion by using R * Q * v
, the
- * rotation represented by this
will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the local y axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateLocalY(float angle, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the local z axis
- * and store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be R * Q
. So when transforming a
- * vector v
with the new quaternion by using R * Q * v
, the
- * rotation represented by this
will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the local z axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateLocalZ(float angle, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the specified axis
- * and store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @param angle
- * the angle in radians to rotate about the specified axis
- * @param axisX
- * the x coordinate of the rotation axis
- * @param axisY
- * the y coordinate of the rotation axis
- * @param axisZ
- * the z coordinate of the rotation axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateAxis(float angle, float axisX, float axisY, float axisZ, Quaternionf dest);
-
- /**
- * Apply a rotation to this
quaternion rotating the given radians about the specified axis
- * and store the result in dest
.
- * Q
is this
quaternion and R
the quaternion representing the
- * specified rotation, then the new quaternion will be Q * R
. So when transforming a
- * vector v
with the new quaternion by using Q * R * v
, the
- * rotation added by this method will be applied first!
- *
- * @see #rotateAxis(float, float, float, float, Quaternionf)
- *
- * @param angle
- * the angle in radians to rotate about the specified axis
- * @param axis
- * the rotation axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf rotateAxis(float angle, Vector3fc axis, Quaternionf dest);
-
- /**
- * Compute the difference between this
and the other
quaternion
- * and store the result in dest
.
- * this
rotation to other
. If T
is this
, Q
- * is other
and D
is the computed difference, then the following equation holds:
- * T * D = Q
- * D = T^-1 * Q
, where T^-1
denotes the {@link #invert(Quaternionf) inverse} of T
.
- *
- * @param other
- * the other quaternion
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf difference(Quaternionfc other, Quaternionf dest);
-
- /**
- * Obtain the direction of +X
before the rotation transformation represented by this
quaternion is applied.
- *
- * Quaternionf inv = new Quaternionf(this).invert();
- * inv.transform(dir.set(1, 0, 0));
- *
- *
- * @param dir
- * will hold the direction of +X
- * @return dir
- */
- Vector3f positiveX(Vector3f dir);
-
- /**
- * Obtain the direction of +X
before the rotation transformation represented by this
normalized quaternion is applied.
- * The quaternion must be {@link #normalize(Quaternionf) normalized} for this method to work.
- *
- * Quaternionf inv = new Quaternionf(this).conjugate();
- * inv.transform(dir.set(1, 0, 0));
- *
- *
- * @param dir
- * will hold the direction of +X
- * @return dir
- */
- Vector3f normalizedPositiveX(Vector3f dir);
-
- /**
- * Obtain the direction of +Y
before the rotation transformation represented by this
quaternion is applied.
- *
- * Quaternionf inv = new Quaternionf(this).invert();
- * inv.transform(dir.set(0, 1, 0));
- *
- *
- * @param dir
- * will hold the direction of +Y
- * @return dir
- */
- Vector3f positiveY(Vector3f dir);
-
- /**
- * Obtain the direction of +Y
before the rotation transformation represented by this
normalized quaternion is applied.
- * The quaternion must be {@link #normalize(Quaternionf) normalized} for this method to work.
- *
- * Quaternionf inv = new Quaternionf(this).conjugate();
- * inv.transform(dir.set(0, 1, 0));
- *
- *
- * @param dir
- * will hold the direction of +Y
- * @return dir
- */
- Vector3f normalizedPositiveY(Vector3f dir);
-
- /**
- * Obtain the direction of +Z
before the rotation transformation represented by this
quaternion is applied.
- *
- * Quaternionf inv = new Quaternionf(this).invert();
- * inv.transform(dir.set(0, 0, 1));
- *
- *
- * @param dir
- * will hold the direction of +Z
- * @return dir
- */
- Vector3f positiveZ(Vector3f dir);
-
- /**
- * Obtain the direction of +Z
before the rotation transformation represented by this
normalized quaternion is applied.
- * The quaternion must be {@link #normalize(Quaternionf) normalized} for this method to work.
- *
- * Quaternionf inv = new Quaternionf(this).conjugate();
- * inv.transform(dir.set(0, 0, 1));
- *
- *
- * @param dir
- * will hold the direction of +Z
- * @return dir
- */
- Vector3f normalizedPositiveZ(Vector3f dir);
-
- /**
- * Conjugate this
by the given quaternion q
by computing q * this * q^-1
- * and store the result into dest
.
- *
- * @param q
- * the {@link Quaternionfc} to conjugate this
by
- * @param dest
- * will hold the result
- * @return dest
- */
- Quaternionf conjugateBy(Quaternionfc q, Quaternionf dest);
-
- /**
- * Determine whether all components are finite floating-point values, that
- * is, they are not {@link Float#isNaN() NaN} and not
- * {@link Float#isInfinite() infinity}.
- *
- * @return {@code true} if all components are finite floating-point values;
- * {@code false} otherwise
- */
- boolean isFinite();
-
- /**
- Compare the quaternion components of this
quaternion with the given quaternion using the given delta
- * and return whether all of them are equal within a maximum difference of delta
.
- * true
whether all of the quaternion components are equal; false
otherwise
- */
- boolean equals(Quaternionfc q, float delta);
-
- /**
- *
- * @param x
- * the x component to compare to
- * @param y
- * the y component to compare to
- * @param z
- * the z component to compare to
- * @param w
- * the w component to compare to
- * @return true
if all the quaternion components are equal
- */
- boolean equals(float x, float y, float z, float w);
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/RayAabIntersection.java b/src/main/java/com/jozufozu/flywheel/util/joml/RayAabIntersection.java
deleted file mode 100644
index fcda32a3d..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/RayAabIntersection.java
+++ /dev/null
@@ -1,399 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 Kai Burjack
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-/**
- * This is an implementation of the Fast Ray/Axis-Aligned Bounding Box
- * Overlap Tests using Ray Slopes paper.
- * (originX, originY, originZ)
- * and direction (dirX, dirY, dirZ)
.
- * (originX, originY, originZ)
- * and direction (dirX, dirY, dirZ)
.
- *
- * @param originX
- * the x coordinate of the ray origin
- * @param originY
- * the y coordinate of the ray origin
- * @param originZ
- * the z coordinate of the ray origin
- * @param dirX
- * the x coordinate of the ray direction
- * @param dirY
- * the y coordinate of the ray direction
- * @param dirZ
- * the z coordinate of the ray direction
- */
- public void set(float originX, float originY, float originZ, float dirX, float dirY, float dirZ) {
- this.originX = originX;
- this.originY = originY;
- this.originZ = originZ;
- this.dirX = dirX;
- this.dirY = dirY;
- this.dirZ = dirZ;
- precomputeSlope();
- }
-
- private static int signum(float f) {
- return (f == 0.0f || Float.isNaN(f)) ? 0 : ((1 - Float.floatToIntBits(f) >>> 31) << 1) - 1;
- }
-
- /**
- * Precompute the values necessary for the ray slope algorithm.
- */
- private void precomputeSlope() {
- float invDirX = 1.0f / dirX;
- float invDirY = 1.0f / dirY;
- float invDirZ = 1.0f / dirZ;
- s_yx = dirX * invDirY;
- s_xy = dirY * invDirX;
- s_zy = dirY * invDirZ;
- s_yz = dirZ * invDirY;
- s_xz = dirZ * invDirX;
- s_zx = dirX * invDirZ;
- c_xy = originY - s_xy * originX;
- c_yx = originX - s_yx * originY;
- c_zy = originY - s_zy * originZ;
- c_yz = originZ - s_yz * originY;
- c_xz = originZ - s_xz * originX; // <- original paper had a bug here. It switched originZ/originX
- c_zx = originX - s_zx * originZ; // <- original paper had a bug here. It switched originZ/originX
- int sgnX = signum(dirX);
- int sgnY = signum(dirY);
- int sgnZ = signum(dirZ);
- classification = (byte) ((sgnZ+1) << 4 | (sgnY+1) << 2 | (sgnX+1));
- }
-
- /**
- * Test whether the ray stored in this {@link RayAabIntersection} intersect the axis-aligned box
- * given via its minimum corner (minX, minY, minZ)
and its maximum corner (maxX, maxY, maxZ)
.
- * true
iff the ray intersects the given axis-aligned box; false
otherwise
- */
- public boolean test(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- // tableswitch with dense and consecutive cases (will be a simple jump based on the switch argument)
- switch (classification) {
- case 0: // 0b000000: // MMM
- return MMM(minX, minY, minZ, maxX, maxY, maxZ);
- case 1: // 0b000001: // OMM
- return OMM(minX, minY, minZ, maxX, maxY, maxZ);
- case 2: // 0b000010: // PMM
- return PMM(minX, minY, minZ, maxX, maxY, maxZ);
- case 3: // 0b000011: // not used
- return false;
- case 4: // 0b000100: // MOM
- return MOM(minX, minY, minZ, maxX, maxY, maxZ);
- case 5: // 0b000101: // OOM
- return OOM(minX, minY, minZ, maxX, maxY);
- case 6: // 0b000110: // POM
- return POM(minX, minY, minZ, maxX, maxY, maxZ);
- case 7: // 0b000111: // not used
- return false;
- case 8: // 0b001000: // MPM
- return MPM(minX, minY, minZ, maxX, maxY, maxZ);
- case 9: // 0b001001: // OPM
- return OPM(minX, minY, minZ, maxX, maxY, maxZ);
- case 10: // 0b001010: // PPM
- return PPM(minX, minY, minZ, maxX, maxY, maxZ);
- case 11: // 0b001011: // not used
- case 12: // 0b001100: // not used
- case 13: // 0b001101: // not used
- case 14: // 0b001110: // not used
- case 15: // 0b001111: // not used
- return false;
- case 16: // 0b010000: // MMO
- return MMO(minX, minY, minZ, maxX, maxY, maxZ);
- case 17: // 0b010001: // OMO
- return OMO(minX, minY, minZ, maxX, maxZ);
- case 18: // 0b010010: // PMO
- return PMO(minX, minY, minZ, maxX, maxY, maxZ);
- case 19: // 0b010011: // not used
- return false;
- case 20: // 0b010100: // MOO
- return MOO(minX, minY, minZ, maxY, maxZ);
- case 21: // 0b010101: // OOO
- return false; // <- degenerate case
- case 22: // 0b010110: // POO
- return POO(minY, minZ, maxX, maxY, maxZ);
- case 23: // 0b010111: // not used
- return false;
- case 24: // 0b011000: // MPO
- return MPO(minX, minY, minZ, maxX, maxY, maxZ);
- case 25: // 0b011001: // OPO
- return OPO(minX, minZ, maxX, maxY, maxZ);
- case 26: // 0b011010: // PPO
- return PPO(minX, minY, minZ, maxX, maxY, maxZ);
- case 27: // 0b011011: // not used
- case 28: // 0b011100: // not used
- case 29: // 0b011101: // not used
- case 30: // 0b011110: // not used
- case 31: // 0b011111: // not used
- return false;
- case 32: // 0b100000: // MMP
- return MMP(minX, minY, minZ, maxX, maxY, maxZ);
- case 33: // 0b100001: // OMP
- return OMP(minX, minY, minZ, maxX, maxY, maxZ);
- case 34: // 0b100010: // PMP
- return PMP(minX, minY, minZ, maxX, maxY, maxZ);
- case 35: // 0b100011: // not used
- return false;
- case 36: // 0b100100: // MOP
- return MOP(minX, minY, minZ, maxX, maxY, maxZ);
- case 37: // 0b100101: // OOP
- return OOP(minX, minY, maxX, maxY, maxZ);
- case 38: // 0b100110: // POP
- return POP(minX, minY, minZ, maxX, maxY, maxZ);
- case 39: // 0b100111: // not used
- return false;
- case 40: // 0b101000: // MPP
- return MPP(minX, minY, minZ, maxX, maxY, maxZ);
- case 41: // 0b101001: // OPP
- return OPP(minX, minY, minZ, maxX, maxY, maxZ);
- case 42: // 0b101010: // PPP
- return PPP(minX, minY, minZ, maxX, maxY, maxZ);
- default:
- return false;
- }
- }
-
- /* Intersection tests for all possible ray direction cases */
-
- private boolean MMM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX >= minX && originY >= minY && originZ >= minZ
- && s_xy * minX - maxY + c_xy <= 0.0f
- && s_yx * minY - maxX + c_yx <= 0.0f
- && s_zy * minZ - maxY + c_zy <= 0.0f
- && s_yz * minY - maxZ + c_yz <= 0.0f
- && s_xz * minX - maxZ + c_xz <= 0.0f
- && s_zx * minZ - maxX + c_zx <= 0.0f;
- }
- private boolean OMM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX >= minX && originX <= maxX && originY >= minY && originZ >= minZ
- && s_zy * minZ - maxY + c_zy <= 0.0f
- && s_yz * minY - maxZ + c_yz <= 0.0f;
- }
- private boolean PMM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX <= maxX && originY >= minY && originZ >= minZ
- && s_xy * maxX - maxY + c_xy <= 0.0f
- && s_yx * minY - minX + c_yx >= 0.0f
- && s_zy * minZ - maxY + c_zy <= 0.0f
- && s_yz * minY - maxZ + c_yz <= 0.0f
- && s_xz * maxX - maxZ + c_xz <= 0.0f
- && s_zx * minZ - minX + c_zx >= 0.0f;
- }
- private boolean MOM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originY >= minY && originY <= maxY && originX >= minX && originZ >= minZ
- && s_xz * minX - maxZ + c_xz <= 0.0f
- && s_zx * minZ - maxX + c_zx <= 0.0f;
- }
- private boolean OOM(float minX, float minY, float minZ, float maxX, float maxY) {
- return originZ >= minZ && originX >= minX && originX <= maxX && originY >= minY && originY <= maxY;
- }
- private boolean POM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originY >= minY && originY <= maxY && originX <= maxX && originZ >= minZ
- && s_xz * maxX - maxZ + c_xz <= 0.0f
- && s_zx * minZ - minX + c_zx >= 0.0f;
- }
- private boolean MPM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX >= minX && originY <= maxY && originZ >= minZ
- && s_xy * minX - minY + c_xy >= 0.0f
- && s_yx * maxY - maxX + c_yx <= 0.0f
- && s_zy * minZ - minY + c_zy >= 0.0f
- && s_yz * maxY - maxZ + c_yz <= 0.0f
- && s_xz * minX - maxZ + c_xz <= 0.0f
- && s_zx * minZ - maxX + c_zx <= 0.0f;
- }
- private boolean OPM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX >= minX && originX <= maxX && originY <= maxY && originZ >= minZ
- && s_zy * minZ - minY + c_zy >= 0.0f
- && s_yz * maxY - maxZ + c_yz <= 0.0f;
- }
- private boolean PPM(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX <= maxX && originY <= maxY && originZ >= minZ
- && s_xy * maxX - minY + c_xy >= 0.0f
- && s_yx * maxY - minX + c_yx >= 0.0f
- && s_zy * minZ - minY + c_zy >= 0.0f
- && s_yz * maxY - maxZ + c_yz <= 0.0f
- && s_xz * maxX - maxZ + c_xz <= 0.0f
- && s_zx * minZ - minX + c_zx >= 0.0f;
- }
- private boolean MMO(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originZ >= minZ && originZ <= maxZ && originX >= minX && originY >= minY
- && s_xy * minX - maxY + c_xy <= 0.0f
- && s_yx * minY - maxX + c_yx <= 0.0f;
- }
- private boolean OMO(float minX, float minY, float minZ, float maxX, float maxZ) {
- return originY >= minY && originX >= minX && originX <= maxX && originZ >= minZ && originZ <= maxZ;
- }
- private boolean PMO(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originZ >= minZ && originZ <= maxZ && originX <= maxX && originY >= minY
- && s_xy * maxX - maxY + c_xy <= 0.0f
- && s_yx * minY - minX + c_yx >= 0.0f;
- }
- private boolean MOO(float minX, float minY, float minZ, float maxY, float maxZ) {
- return originX >= minX && originY >= minY && originY <= maxY && originZ >= minZ && originZ <= maxZ;
- }
- private boolean POO(float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX <= maxX && originY >= minY && originY <= maxY && originZ >= minZ && originZ <= maxZ;
- }
- private boolean MPO(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originZ >= minZ && originZ <= maxZ && originX >= minX && originY <= maxY
- && s_xy * minX - minY + c_xy >= 0.0f
- && s_yx * maxY - maxX + c_yx <= 0.0f;
- }
- private boolean OPO(float minX, float minZ, float maxX, float maxY, float maxZ) {
- return originY <= maxY && originX >= minX && originX <= maxX && originZ >= minZ && originZ <= maxZ;
- }
- private boolean PPO(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originZ >= minZ && originZ <= maxZ && originX <= maxX && originY <= maxY
- && s_xy * maxX - minY + c_xy >= 0.0f
- && s_yx * maxY - minX + c_yx >= 0.0f;
- }
- private boolean MMP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX >= minX && originY >= minY && originZ <= maxZ
- && s_xy * minX - maxY + c_xy <= 0.0f
- && s_yx * minY - maxX + c_yx <= 0.0f
- && s_zy * maxZ - maxY + c_zy <= 0.0f
- && s_yz * minY - minZ + c_yz >= 0.0f
- && s_xz * minX - minZ + c_xz >= 0.0f
- && s_zx * maxZ - maxX + c_zx <= 0.0f;
- }
- private boolean OMP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX >= minX && originX <= maxX && originY >= minY && originZ <= maxZ
- && s_zy * maxZ - maxY + c_zy <= 0.0f
- && s_yz * minY - minZ + c_yz >= 0.0f;
- }
- private boolean PMP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX <= maxX && originY >= minY && originZ <= maxZ
- && s_xy * maxX - maxY + c_xy <= 0.0f
- && s_yx * minY - minX + c_yx >= 0.0f
- && s_zy * maxZ - maxY + c_zy <= 0.0f
- && s_yz * minY - minZ + c_yz >= 0.0f
- && s_xz * maxX - minZ + c_xz >= 0.0f
- && s_zx * maxZ - minX + c_zx >= 0.0f;
- }
- private boolean MOP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originY >= minY && originY <= maxY && originX >= minX && originZ <= maxZ
- && s_xz * minX - minZ + c_xz >= 0.0f
- && s_zx * maxZ - maxX + c_zx <= 0.0f;
- }
- private boolean OOP(float minX, float minY, float maxX, float maxY, float maxZ) {
- return originZ <= maxZ && originX >= minX && originX <= maxX && originY >= minY && originY <= maxY;
- }
- private boolean POP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originY >= minY && originY <= maxY && originX <= maxX && originZ <= maxZ
- && s_xz * maxX - minZ + c_xz >= 0.0f
- && s_zx * maxZ - minX + c_zx <= 0.0f;
- }
- private boolean MPP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX >= minX && originY <= maxY && originZ <= maxZ
- && s_xy * minX - minY + c_xy >= 0.0f
- && s_yx * maxY - maxX + c_yx <= 0.0f
- && s_zy * maxZ - minY + c_zy >= 0.0f
- && s_yz * maxY - minZ + c_yz >= 0.0f
- && s_xz * minX - minZ + c_xz >= 0.0f
- && s_zx * maxZ - maxX + c_zx <= 0.0f;
- }
- private boolean OPP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX >= minX && originX <= maxX && originY <= maxY && originZ <= maxZ
- && s_zy * maxZ - minY + c_zy <= 0.0f
- && s_yz * maxY - minZ + c_yz <= 0.0f;
- }
- private boolean PPP(float minX, float minY, float minZ, float maxX, float maxY, float maxZ) {
- return originX <= maxX && originY <= maxY && originZ <= maxZ
- && s_xy * maxX - minY + c_xy >= 0.0f
- && s_yx * maxY - minX + c_yx >= 0.0f
- && s_zy * maxZ - minY + c_zy >= 0.0f
- && s_yz * maxY - minZ + c_yz >= 0.0f
- && s_xz * maxX - minZ + c_xz >= 0.0f
- && s_zx * maxZ - minX + c_zx >= 0.0f;
- }
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/RoundingMode.java b/src/main/java/com/jozufozu/flywheel/util/joml/RoundingMode.java
deleted file mode 100644
index 4f3ef6cf2..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/RoundingMode.java
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2020-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-/**
- * Rounding modes.
- *
- * @author Kai Burjack
- */
-public class RoundingMode {
- private RoundingMode() {}
- /**
- * Discards the fractional part.
- */
- public static final int TRUNCATE = 0;
- /**
- * Round towards positive infinity.
- */
- public static final int CEILING = 1;
- /**
- * Round towards negative infinity.
- */
- public static final int FLOOR = 2;
- /**
- * Round towards the nearest neighbor. If both neighbors are equidistant, round
- * towards the even neighbor.
- */
- public static final int HALF_EVEN = 3;
- /**
- * Round towards the nearest neighbor. If both neighbors are equidistant, round
- * down.
- */
- public static final int HALF_DOWN = 4;
- /**
- * Round towards the nearest neighbor. If both neighbors are equidistant, round
- * up.
- */
- public static final int HALF_UP = 5;
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Runtime.java b/src/main/java/com/jozufozu/flywheel/util/joml/Runtime.java
deleted file mode 100644
index f46f4d18d..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Runtime.java
+++ /dev/null
@@ -1,148 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2017-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.text.NumberFormat;
-
-/**
- * Internal class to detect features of the runtime.
- *
- * @author Kai Burjack
- */
-public final class Runtime {
-
- public static final boolean HAS_floatToRawIntBits = hasFloatToRawIntBits();
- public static final boolean HAS_doubleToRawLongBits = hasDoubleToRawLongBits();
- public static final boolean HAS_Long_rotateLeft = hasLongRotateLeft();
- public static final boolean HAS_Math_fma = Options.USE_MATH_FMA && hasMathFma();
-
- private static boolean hasMathFma() {
- try {
- java.lang.Math.class.getDeclaredMethod("fma", new Class[] { float.class, float.class, float.class });
- return true;
- } catch (NoSuchMethodException e) {
- return false;
- }
- }
-
- private Runtime() {
- }
-
- private static boolean hasFloatToRawIntBits() {
- try {
- Float.class.getDeclaredMethod("floatToRawIntBits", new Class[] { float.class });
- return true;
- } catch (NoSuchMethodException e) {
- return false;
- }
- }
-
- private static boolean hasDoubleToRawLongBits() {
- try {
- Double.class.getDeclaredMethod("doubleToRawLongBits", new Class[] { double.class });
- return true;
- } catch (NoSuchMethodException e) {
- return false;
- }
- }
-
- private static boolean hasLongRotateLeft() {
- try {
- Long.class.getDeclaredMethod("rotateLeft", new Class[] { long.class, int.class });
- return true;
- } catch (NoSuchMethodException e) {
- return false;
- }
- }
-
- public static int floatToIntBits(float flt) {
- if (HAS_floatToRawIntBits)
- return floatToIntBits1_3(flt);
- return floatToIntBits1_2(flt);
- }
- private static int floatToIntBits1_3(float flt) {
- return Float.floatToRawIntBits(flt);
- }
- private static int floatToIntBits1_2(float flt) {
- return Float.floatToIntBits(flt);
- }
-
- public static long doubleToLongBits(double dbl) {
- if (HAS_doubleToRawLongBits)
- return doubleToLongBits1_3(dbl);
- return doubleToLongBits1_2(dbl);
- }
- private static long doubleToLongBits1_3(double dbl) {
- return Double.doubleToRawLongBits(dbl);
- }
- private static long doubleToLongBits1_2(double dbl) {
- return Double.doubleToLongBits(dbl);
- }
-
- public static String formatNumbers(String str) {
- StringBuffer res = new StringBuffer();
- int eIndex = Integer.MIN_VALUE;
- for (int i = 0; i < str.length(); i++) {
- char c = str.charAt(i);
- if (c == 'E') {
- eIndex = i;
- } else if (c == ' ' && eIndex == i - 1) {
- // workaround Java 1.4 DecimalFormat bug
- res.append('+');
- continue;
- } else if (Character.isDigit(c) && eIndex == i - 1) {
- res.append('+');
- }
- res.append(c);
- }
- return res.toString();
- }
-
- public static String format(double number, NumberFormat format) {
- if (Double.isNaN(number)) {
- return padLeft(format, " NaN");
- } else if (Double.isInfinite(number)) {
- return padLeft(format, number > 0.0 ? " +Inf" : " -Inf");
- }
- return format.format(number);
- }
-
- private static String padLeft(NumberFormat format, String str) {
- int len = format.format(0.0).length();
- StringBuffer sb = new StringBuffer();
- for (int i = 0; i < len - str.length() + 1; i++) {
- sb.append(" ");
- }
- return sb.append(str).toString();
- }
-
- public static boolean equals(float a, float b, float delta) {
- return Float.floatToIntBits(a) == Float.floatToIntBits(b) || Math.abs(a - b) <= delta;
- }
-
- public static boolean equals(double a, double b, double delta) {
- return Double.doubleToLongBits(a) == Double.doubleToLongBits(b) || Math.abs(a - b) <= delta;
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Vector3f.java b/src/main/java/com/jozufozu/flywheel/util/joml/Vector3f.java
deleted file mode 100644
index 93627940b..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Vector3f.java
+++ /dev/null
@@ -1,1827 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 Richard Greenlees
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-
-/**
- * Contains the definition of a Vector comprising 3 floats and associated
- * transformations.
- *
- * @author Richard Greenlees
- * @author Kai Burjack
- * @author F. Neurath
- */
-public class Vector3f implements Externalizable, Cloneable, Vector3fc {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * The x component of the vector.
- */
- public float x;
- /**
- * The y component of the vector.
- */
- public float y;
- /**
- * The z component of the vector.
- */
- public float z;
-
- /**
- * Create a new {@link Vector3f} of (0, 0, 0)
.
- */
- public Vector3f() {
- }
-
- /**
- * Create a new {@link Vector3f} and initialize all three components with the given value.
- *
- * @param d
- * the value of all three components
- */
- public Vector3f(float d) {
- this.x = d;
- this.y = d;
- this.z = d;
- }
-
- /**
- * Create a new {@link Vector3f} with the given component values.
- *
- * @param x
- * the value of x
- * @param y
- * the value of y
- * @param z
- * the value of z
- */
- public Vector3f(float x, float y, float z) {
- this.x = x;
- this.y = y;
- this.z = z;
- }
-
- /**
- * Create a new {@link Vector3f} with the same values as v
.
- *
- * @param v
- * the {@link Vector3fc} to copy the values from
- */
- public Vector3f(Vector3fc v) {
- this.x = v.x();
- this.y = v.y();
- this.z = v.z();
- }
-
- /**
- * Create a new {@link Vector3f} and initialize its three components from the first
- * three elements of the given array.
- *
- * @param xyz
- * the array containing at least three elements
- */
- public Vector3f(float[] xyz) {
- this.x = xyz[0];
- this.y = xyz[1];
- this.z = xyz[2];
- }
-
- /**
- * Create a new {@link Vector3f} and read this vector from the supplied {@link ByteBuffer}
- * at the current buffer {@link ByteBuffer#position() position}.
- * x, y, z
order
- * @see #Vector3f(int, ByteBuffer)
- */
- public Vector3f(ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- }
-
- /**
- * Create a new {@link Vector3f} and read this vector from the supplied {@link ByteBuffer}
- * starting at the specified absolute buffer position/index.
- * x, y, z
order
- */
- public Vector3f(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- }
-
- /**
- * Create a new {@link Vector3f} and read this vector from the supplied {@link FloatBuffer}
- * at the current buffer {@link FloatBuffer#position() position}.
- * x, y, z
order
- * @see #Vector3f(int, FloatBuffer)
- */
- public Vector3f(FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- }
-
- /**
- * Create a new {@link Vector3f} and read this vector from the supplied {@link FloatBuffer}
- * starting at the specified absolute buffer position/index.
- * x, y, z
order
- */
- public Vector3f(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- }
-
- public float x() {
- return this.x;
- }
-
- public float y() {
- return this.y;
- }
-
- public float z() {
- return this.z;
- }
-
- /**
- * Set the x, y and z components to match the supplied vector.
- *
- * @param v
- * contains the values of x, y and z to set
- * @return this
- */
- public Vector3f set(Vector3fc v) {
- this.x = v.x();
- this.y = v.y();
- this.z = v.z();
- return this;
- }
-
- /**
- * Set the x, y, and z components to the supplied value.
- *
- * @param d
- * the value of all three components
- * @return this
- */
- public Vector3f set(float d) {
- this.x = d;
- this.y = d;
- this.z = d;
- return this;
- }
-
- /**
- * Set the x, y and z components to the supplied values.
- *
- * @param x
- * the x component
- * @param y
- * the y component
- * @param z
- * the z component
- * @return this
- */
- public Vector3f set(float x, float y, float z) {
- this.x = x;
- this.y = y;
- this.z = z;
- return this;
- }
-
- /**
- * Set the x, y, and z components to the supplied value.
- *
- * @param d
- * the value of all three components
- * @return this
- */
- public Vector3f set(double d) {
- this.x = (float) d;
- this.y = (float) d;
- this.z = (float) d;
- return this;
- }
-
- /**
- * Set the x, y and z components to the supplied values.
- *
- * @param x
- * the x component
- * @param y
- * the y component
- * @param z
- * the z component
- * @return this
- */
- public Vector3f set(double x, double y, double z) {
- this.x = (float) x;
- this.y = (float) y;
- this.z = (float) z;
- return this;
- }
-
- /**
- * Set the three components of this vector to the first three elements of the given array.
- *
- * @param xyz
- * the array containing at least three elements
- * @return this
- */
- public Vector3f set(float[] xyz) {
- this.x = xyz[0];
- this.y = xyz[1];
- this.z = xyz[2];
- return this;
- }
-
- /**
- * Read this vector from the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- * x, y, z
order
- * @return this
- * @see #set(int, ByteBuffer)
- */
- public Vector3f set(ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- return this;
- }
-
- /**
- * Read this vector from the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- * x, y, z
order
- * @return this
- */
- public Vector3f set(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- return this;
- }
-
- /**
- * Read this vector from the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- * x, y, z
order
- * @return this
- * @see #set(int, FloatBuffer)
- */
- public Vector3f set(FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- return this;
- }
-
- /**
- * Read this vector from the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- * x, y, z
order
- * @return this
- */
- public Vector3f set(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- return this;
- }
-
- /**
- * Set the values of this vector by reading 3 float values from off-heap memory,
- * starting at the given address.
- * [0..2]
- * @param value
- * the value to set
- * @return this
- * @throws IllegalArgumentException if component
is not within [0..2]
- */
- public Vector3f setComponent(int component, float value) throws IllegalArgumentException {
- switch (component) {
- case 0:
- x = value;
- break;
- case 1:
- y = value;
- break;
- case 2:
- z = value;
- break;
- default:
- throw new IllegalArgumentException();
- }
- return this;
- }
-
- public FloatBuffer get(FloatBuffer buffer) {
- MemUtil.INSTANCE.put(this, buffer.position(), buffer);
- return buffer;
- }
-
- public FloatBuffer get(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.put(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer get(ByteBuffer buffer) {
- MemUtil.INSTANCE.put(this, buffer.position(), buffer);
- return buffer;
- }
-
- public ByteBuffer get(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.put(this, index, buffer);
- return buffer;
- }
-
- public Vector3fc getToAddress(long address) {
- if (Options.NO_UNSAFE)
- throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
- MemUtil.MemUtilUnsafe.put(this, address);
- return this;
- }
-
- /**
- * Subtract the supplied vector from this one and store the result in this
.
- *
- * @param v
- * the vector to subtract
- * @return this
- */
- public Vector3f sub(Vector3fc v) {
- this.x = x - v.x();
- this.y = y - v.y();
- this.z = z - v.z();
- return this;
- }
-
- public Vector3f sub(Vector3fc v, Vector3f dest) {
- dest.x = x - v.x();
- dest.y = y - v.y();
- dest.z = z - v.z();
- return dest;
- }
-
- /**
- * Decrement the components of this vector by the given values.
- *
- * @param x
- * the x component to subtract
- * @param y
- * the y component to subtract
- * @param z
- * the z component to subtract
- * @return this
- */
- public Vector3f sub(float x, float y, float z) {
- this.x = this.x - x;
- this.y = this.y - y;
- this.z = this.z - z;
- return this;
- }
-
- public Vector3f sub(float x, float y, float z, Vector3f dest) {
- dest.x = this.x - x;
- dest.y = this.y - y;
- dest.z = this.z - z;
- return dest;
- }
-
- /**
- * Add the supplied vector to this one.
- *
- * @param v
- * the vector to add
- * @return this
- */
- public Vector3f add(Vector3fc v) {
- this.x = this.x + v.x();
- this.y = this.y + v.y();
- this.z = this.z + v.z();
- return this;
- }
-
- public Vector3f add(Vector3fc v, Vector3f dest) {
- dest.x = this.x + v.x();
- dest.y = this.y + v.y();
- dest.z = this.z + v.z();
- return dest;
- }
-
- /**
- * Increment the components of this vector by the given values.
- *
- * @param x
- * the x component to add
- * @param y
- * the y component to add
- * @param z
- * the z component to add
- * @return this
- */
- public Vector3f add(float x, float y, float z) {
- this.x = this.x + x;
- this.y = this.y + y;
- this.z = this.z + z;
- return this;
- }
-
- public Vector3f add(float x, float y, float z, Vector3f dest) {
- dest.x = this.x + x;
- dest.y = this.y + y;
- dest.z = this.z + z;
- return dest;
- }
-
- /**
- * Add the component-wise multiplication of a * b
to this vector.
- *
- * @param a
- * the first multiplicand
- * @param b
- * the second multiplicand
- * @return this
- */
- public Vector3f fma(Vector3fc a, Vector3fc b) {
- this.x = Math.fma(a.x(), b.x(), x);
- this.y = Math.fma(a.y(), b.y(), y);
- this.z = Math.fma(a.z(), b.z(), z);
- return this;
- }
-
- /**
- * Add the component-wise multiplication of a * b
to this vector.
- *
- * @param a
- * the first multiplicand
- * @param b
- * the second multiplicand
- * @return this
- */
- public Vector3f fma(float a, Vector3fc b) {
- this.x = Math.fma(a, b.x(), x);
- this.y = Math.fma(a, b.y(), y);
- this.z = Math.fma(a, b.z(), z);
- return this;
- }
-
- public Vector3f fma(Vector3fc a, Vector3fc b, Vector3f dest) {
- dest.x = Math.fma(a.x(), b.x(), x);
- dest.y = Math.fma(a.y(), b.y(), y);
- dest.z = Math.fma(a.z(), b.z(), z);
- return dest;
- }
-
- public Vector3f fma(float a, Vector3fc b, Vector3f dest) {
- dest.x = Math.fma(a, b.x(), x);
- dest.y = Math.fma(a, b.y(), y);
- dest.z = Math.fma(a, b.z(), z);
- return dest;
- }
-
- /**
- * Add the component-wise multiplication of this * a
to b
- * and store the result in this
.
- *
- * @param a
- * the multiplicand
- * @param b
- * the addend
- * @return this
- */
- public Vector3f mulAdd(Vector3fc a, Vector3fc b) {
- this.x = Math.fma(x, a.x(), b.x());
- this.y = Math.fma(y, a.y(), b.y());
- this.z = Math.fma(z, a.z(), b.z());
- return this;
- }
-
- /**
- * Add the component-wise multiplication of this * a
to b
- * and store the result in this
.
- *
- * @param a
- * the multiplicand
- * @param b
- * the addend
- * @return this
- */
- public Vector3f mulAdd(float a, Vector3fc b) {
- this.x = Math.fma(x, a, b.x());
- this.y = Math.fma(y, a, b.y());
- this.z = Math.fma(z, a, b.z());
- return this;
- }
-
- public Vector3f mulAdd(Vector3fc a, Vector3fc b, Vector3f dest) {
- dest.x = Math.fma(x, a.x(), b.x());
- dest.y = Math.fma(y, a.y(), b.y());
- dest.z = Math.fma(z, a.z(), b.z());
- return dest;
- }
-
- public Vector3f mulAdd(float a, Vector3fc b, Vector3f dest) {
- dest.x = Math.fma(x, a, b.x());
- dest.y = Math.fma(y, a, b.y());
- dest.z = Math.fma(z, a, b.z());
- return dest;
- }
-
- /**
- * Multiply this Vector3f component-wise by another Vector3fc.
- *
- * @param v
- * the vector to multiply by
- * @return this
- */
- public Vector3f mul(Vector3fc v) {
- this.x = x * v.x();
- this.y = y * v.y();
- this.z = z * v.z();
- return this;
- }
-
- public Vector3f mul(Vector3fc v, Vector3f dest) {
- dest.x = x * v.x();
- dest.y = y * v.y();
- dest.z = z * v.z();
- return dest;
- }
-
- /**
- * Divide this Vector3f component-wise by another Vector3fc.
- *
- * @param v
- * the vector to divide by
- * @return this
- */
- public Vector3f div(Vector3fc v) {
- this.x = this.x / v.x();
- this.y = this.y / v.y();
- this.z = this.z / v.z();
- return this;
- }
-
- public Vector3f div(Vector3fc v, Vector3f dest) {
- dest.x = x / v.x();
- dest.y = y / v.y();
- dest.z = z / v.z();
- return dest;
- }
-
- public Vector3f mulProject(Matrix4fc mat, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- float invW = 1.0f / Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33())));
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30()))) * invW;
- dest.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31()))) * invW;
- dest.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32()))) * invW;
- return dest;
- }
-
- public Vector3f mulProject(Matrix4fc mat, float w, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- float invW = 1.0f / Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33() * w)));
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30() * w))) * invW;
- dest.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31() * w))) * invW;
- dest.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32() * w))) * invW;
- return dest;
- }
-
- /**
- * Multiply the given matrix mat
with this Vector3f, perform perspective division.
- * w=1.0
as the fourth vector component.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @return this
- */
- public Vector3f mulProject(Matrix4fc mat) {
- float x = this.x, y = this.y, z = this.z;
- float invW = 1.0f / Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33())));
- this.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30()))) * invW;
- this.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31()))) * invW;
- this.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32()))) * invW;
- return this;
- }
-
- /**
- * Multiply the given matrix with this Vector3f and store the result in this
.
- *
- * @param mat
- * the matrix
- * @return this
- */
- public Vector3f mul(Matrix3fc mat) {
- float lx = x, ly = y, lz = z;
- this.x = Math.fma(mat.m00(), lx, Math.fma(mat.m10(), ly, mat.m20() * lz));
- this.y = Math.fma(mat.m01(), lx, Math.fma(mat.m11(), ly, mat.m21() * lz));
- this.z = Math.fma(mat.m02(), lx, Math.fma(mat.m12(), ly, mat.m22() * lz));
- return this;
- }
-
- public Vector3f mul(Matrix3fc mat, Vector3f dest) {
- float lx = x, ly = y, lz = z;
- dest.x = Math.fma(mat.m00(), lx, Math.fma(mat.m10(), ly, mat.m20() * lz));
- dest.y = Math.fma(mat.m01(), lx, Math.fma(mat.m11(), ly, mat.m21() * lz));
- dest.z = Math.fma(mat.m02(), lx, Math.fma(mat.m12(), ly, mat.m22() * lz));
- return dest;
- }
-
- /**
- * Multiply the transpose of the given matrix with this Vector3f store the result in this
.
- *
- * @param mat
- * the matrix
- * @return this
- */
- public Vector3f mulTranspose(Matrix3fc mat) {
- float x = this.x, y = this.y, z = this.z;
- this.x = Math.fma(mat.m00(), x, Math.fma(mat.m01(), y, mat.m02() * z));
- this.y = Math.fma(mat.m10(), x, Math.fma(mat.m11(), y, mat.m12() * z));
- this.z = Math.fma(mat.m20(), x, Math.fma(mat.m21(), y, mat.m22() * z));
- return this;
- }
-
- public Vector3f mulTranspose(Matrix3fc mat, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m01(), y, mat.m02() * z));
- dest.y = Math.fma(mat.m10(), x, Math.fma(mat.m11(), y, mat.m12() * z));
- dest.z = Math.fma(mat.m20(), x, Math.fma(mat.m21(), y, mat.m22() * z));
- return dest;
- }
-
- /**
- * Multiply the given 4x4 matrix mat
with this
.
- * w
component of this
to be 1.0
.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @return this
- */
- public Vector3f mulPosition(Matrix4fc mat) {
- float x = this.x, y = this.y, z = this.z;
- this.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30())));
- this.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31())));
- this.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32())));
- return this;
- }
-
- public Vector3f mulPosition(Matrix4fc mat, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30())));
- dest.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31())));
- dest.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32())));
- return dest;
- }
-
- /**
- * Multiply the transpose of the given 4x4 matrix mat
with this
.
- * w
component of this
to be 1.0
.
- *
- * @param mat
- * the matrix whose transpose to multiply this vector by
- * @return this
- */
- public Vector3f mulTransposePosition(Matrix4fc mat) {
- float x = this.x, y = this.y, z = this.z;
- this.x = Math.fma(mat.m00(), x, Math.fma(mat.m01(), y, Math.fma(mat.m02(), z, mat.m03())));
- this.y = Math.fma(mat.m10(), x, Math.fma(mat.m11(), y, Math.fma(mat.m12(), z, mat.m13())));
- this.z = Math.fma(mat.m20(), x, Math.fma(mat.m21(), y, Math.fma(mat.m22(), z, mat.m23())));
- return this;
- }
-
- public Vector3f mulTransposePosition(Matrix4fc mat, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m01(), y, Math.fma(mat.m02(), z, mat.m03())));
- dest.y = Math.fma(mat.m10(), x, Math.fma(mat.m11(), y, Math.fma(mat.m12(), z, mat.m13())));
- dest.z = Math.fma(mat.m20(), x, Math.fma(mat.m21(), y, Math.fma(mat.m22(), z, mat.m23())));
- return dest;
- }
-
- /**
- * Multiply the given 4x4 matrix mat
with this
and return the w component
- * of the resulting 4D vector.
- * w
component of this
to be 1.0
.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @return the w component of the resulting 4D vector after multiplication
- */
- public float mulPositionW(Matrix4fc mat) {
- float x = this.x, y = this.y, z = this.z;
- float w = Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33())));
- this.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30())));
- this.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31())));
- this.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32())));
- return w;
- }
-
- public float mulPositionW(Matrix4fc mat, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- float w = Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33())));
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30())));
- dest.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31())));
- dest.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32())));
- return w;
- }
-
- /**
- * Multiply the given 4x4 matrix mat
with this
.
- * w
component of this
to be 0.0
.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @return this
- */
- public Vector3f mulDirection(Matrix4fc mat) {
- float x = this.x, y = this.y, z = this.z;
- this.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, mat.m20() * z));
- this.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, mat.m21() * z));
- this.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, mat.m22() * z));
- return this;
- }
-
- public Vector3f mulDirection(Matrix4fc mat, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, mat.m20() * z));
- dest.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, mat.m21() * z));
- dest.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, mat.m22() * z));
- return dest;
- }
-
- /**
- * Multiply the transpose of the given 4x4 matrix mat
with this
.
- * w
component of this
to be 0.0
.
- *
- * @param mat
- * the matrix whose transpose to multiply this vector by
- * @return this
- */
- public Vector3f mulTransposeDirection(Matrix4fc mat) {
- float x = this.x, y = this.y, z = this.z;
- this.x = Math.fma(mat.m00(), x, Math.fma(mat.m01(), y, mat.m02() * z));
- this.y = Math.fma(mat.m10(), x, Math.fma(mat.m11(), y, mat.m12() * z));
- this.z = Math.fma(mat.m20(), x, Math.fma(mat.m21(), y, mat.m22() * z));
- return this;
- }
-
- public Vector3f mulTransposeDirection(Matrix4fc mat, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m01(), y, mat.m02() * z));
- dest.y = Math.fma(mat.m10(), x, Math.fma(mat.m11(), y, mat.m12() * z));
- dest.z = Math.fma(mat.m20(), x, Math.fma(mat.m21(), y, mat.m22() * z));
- return dest;
- }
-
- /**
- * Multiply all components of this {@link Vector3f} by the given scalar
- * value.
- *
- * @param scalar
- * the scalar to multiply this vector by
- * @return this
- */
- public Vector3f mul(float scalar) {
- this.x = this.x * scalar;
- this.y = this.y * scalar;
- this.z = this.z * scalar;
- return this;
- }
-
- public Vector3f mul(float scalar, Vector3f dest) {
- dest.x = this.x * scalar;
- dest.y = this.y * scalar;
- dest.z = this.z * scalar;
- return dest;
- }
-
- /**
- * Multiply the components of this Vector3f by the given scalar values and store the result in this
.
- *
- * @param x
- * the x component to multiply this vector by
- * @param y
- * the y component to multiply this vector by
- * @param z
- * the z component to multiply this vector by
- * @return this
- */
- public Vector3f mul(float x, float y, float z) {
- this.x = this.x * x;
- this.y = this.y * y;
- this.z = this.z * z;
- return this;
- }
-
- public Vector3f mul(float x, float y, float z, Vector3f dest) {
- dest.x = this.x * x;
- dest.y = this.y * y;
- dest.z = this.z * z;
- return dest;
- }
-
- /**
- * Divide all components of this {@link Vector3f} by the given scalar
- * value.
- *
- * @param scalar
- * the scalar to divide by
- * @return this
- */
- public Vector3f div(float scalar) {
- float inv = 1.0f / scalar;
- this.x = this.x * inv;
- this.y = this.y * inv;
- this.z = this.z * inv;
- return this;
- }
-
- public Vector3f div(float scalar, Vector3f dest) {
- float inv = 1.0f / scalar;
- dest.x = this.x * inv;
- dest.y = this.y * inv;
- dest.z = this.z * inv;
- return dest;
- }
-
- /**
- * Divide the components of this Vector3f by the given scalar values and store the result in this
.
- *
- * @param x
- * the x component to divide this vector by
- * @param y
- * the y component to divide this vector by
- * @param z
- * the z component to divide this vector by
- * @return this
- */
- public Vector3f div(float x, float y, float z) {
- this.x = this.x / x;
- this.y = this.y / y;
- this.z = this.z / z;
- return this;
- }
-
- public Vector3f div(float x, float y, float z, Vector3f dest) {
- dest.x = this.x / x;
- dest.y = this.y / y;
- dest.z = this.z / z;
- return dest;
- }
-
- /**
- * Rotate this vector by the given quaternion quat
and store the result in this
.
- *
- * @see Quaternionfc#transform(Vector3f)
- *
- * @param quat
- * the quaternion to rotate this vector
- * @return this
- */
- public Vector3f rotate(Quaternionfc quat) {
- return quat.transform(this, this);
- }
-
- public Vector3f rotate(Quaternionfc quat, Vector3f dest) {
- return quat.transform(this, dest);
- }
-
- public Quaternionf rotationTo(Vector3fc toDir, Quaternionf dest) {
- return dest.rotationTo(this, toDir);
- }
-
- public Quaternionf rotationTo(float toDirX, float toDirY, float toDirZ, Quaternionf dest) {
- return dest.rotationTo(x, y, z, toDirX, toDirY, toDirZ);
- }
-
- /**
- * Rotate this vector the specified radians around the given rotation axis.
- *
- * @param angle
- * the angle in radians
- * @param x
- * the x component of the rotation axis
- * @param y
- * the y component of the rotation axis
- * @param z
- * the z component of the rotation axis
- * @return this
- */
- public Vector3f rotateAxis(float angle, float x, float y, float z) {
- if (y == 0.0f && z == 0.0f && Math.absEqualsOne(x))
- return rotateX(x * angle, this);
- else if (x == 0.0f && z == 0.0f && Math.absEqualsOne(y))
- return rotateY(y * angle, this);
- else if (x == 0.0f && y == 0.0f && Math.absEqualsOne(z))
- return rotateZ(z * angle, this);
- return rotateAxisInternal(angle, x, y, z, this);
- }
-
- public Vector3f rotateAxis(float angle, float aX, float aY, float aZ, Vector3f dest) {
- if (aY == 0.0f && aZ == 0.0f && Math.absEqualsOne(aX))
- return rotateX(aX * angle, dest);
- else if (aX == 0.0f && aZ == 0.0f && Math.absEqualsOne(aY))
- return rotateY(aY * angle, dest);
- else if (aX == 0.0f && aY == 0.0f && Math.absEqualsOne(aZ))
- return rotateZ(aZ * angle, dest);
- return rotateAxisInternal(angle, aX, aY, aZ, dest);
- }
- private Vector3f rotateAxisInternal(float angle, float aX, float aY, float aZ, Vector3f dest) {
- float hangle = angle * 0.5f;
- float sinAngle = Math.sin(hangle);
- float qx = aX * sinAngle, qy = aY * sinAngle, qz = aZ * sinAngle;
- float qw = Math.cosFromSin(sinAngle, hangle);
- float w2 = qw * qw, x2 = qx * qx, y2 = qy * qy, z2 = qz * qz, zw = qz * qw;
- float xy = qx * qy, xz = qx * qz, yw = qy * qw, yz = qy * qz, xw = qx * qw;
- float x = this.x, y = this.y, z = this.z;
- dest.x = (w2 + x2 - z2 - y2) * x + (-zw + xy - zw + xy) * y + (yw + xz + xz + yw) * z;
- dest.y = (xy + zw + zw + xy) * x + ( y2 - z2 + w2 - x2) * y + (yz + yz - xw - xw) * z;
- dest.z = (xz - yw + xz - yw) * x + ( yz + yz + xw + xw) * y + (z2 - y2 - x2 + w2) * z;
- return dest;
- }
-
- /**
- * Rotate this vector the specified radians around the X axis.
- *
- * @param angle
- * the angle in radians
- * @return this
- */
- public Vector3f rotateX(float angle) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float y = this.y * cos - this.z * sin;
- float z = this.y * sin + this.z * cos;
- this.y = y;
- this.z = z;
- return this;
- }
-
- public Vector3f rotateX(float angle, Vector3f dest) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float y = this.y * cos - this.z * sin;
- float z = this.y * sin + this.z * cos;
- dest.x = this.x;
- dest.y = y;
- dest.z = z;
- return dest;
- }
-
- /**
- * Rotate this vector the specified radians around the Y axis.
- *
- * @param angle
- * the angle in radians
- * @return this
- */
- public Vector3f rotateY(float angle) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float x = this.x * cos + this.z * sin;
- float z = -this.x * sin + this.z * cos;
- this.x = x;
- this.z = z;
- return this;
- }
-
- public Vector3f rotateY(float angle, Vector3f dest) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float x = this.x * cos + this.z * sin;
- float z = -this.x * sin + this.z * cos;
- dest.x = x;
- dest.y = this.y;
- dest.z = z;
- return dest;
- }
-
- /**
- * Rotate this vector the specified radians around the Z axis.
- *
- * @param angle
- * the angle in radians
- * @return this
- */
- public Vector3f rotateZ(float angle) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float x = this.x * cos - this.y * sin;
- float y = this.x * sin + this.y * cos;
- this.x = x;
- this.y = y;
- return this;
- }
-
- public Vector3f rotateZ(float angle, Vector3f dest) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float x = this.x * cos - this.y * sin;
- float y = this.x * sin + this.y * cos;
- dest.x = x;
- dest.y = y;
- dest.z = this.z;
- return dest;
- }
-
- public float lengthSquared() {
- return Math.fma(x, x, Math.fma(y, y, z * z));
- }
-
- /**
- * Get the length squared of a 3-dimensional single-precision vector.
- *
- * @param x The vector's x component
- * @param y The vector's y component
- * @param z The vector's z component
- *
- * @return the length squared of the given vector
- *
- * @author F. Neurath
- */
- public static float lengthSquared(float x, float y, float z) {
- return Math.fma(x, x, Math.fma(y, y, z * z));
- }
-
- public float length() {
- return Math.sqrt(Math.fma(x, x, Math.fma(y, y, z * z)));
- }
-
- /**
- * Get the length of a 3-dimensional single-precision vector.
- *
- * @param x The vector's x component
- * @param y The vector's y component
- * @param z The vector's z component
- *
- * @return the length of the given vector
- *
- * @author F. Neurath
- */
- public static float length(float x, float y, float z) {
- return Math.sqrt(Math.fma(x, x, Math.fma(y, y, z * z)));
- }
-
- /**
- * Normalize this vector.
- *
- * @return this
- */
- public Vector3f normalize() {
- float scalar = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, z * z)));
- this.x = this.x * scalar;
- this.y = this.y * scalar;
- this.z = this.z * scalar;
- return this;
- }
-
- public Vector3f normalize(Vector3f dest) {
- float scalar = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, z * z)));
- dest.x = this.x * scalar;
- dest.y = this.y * scalar;
- dest.z = this.z * scalar;
- return dest;
- }
-
- /**
- * Scale this vector to have the given length.
- *
- * @param length
- * the desired length
- * @return this
- */
- public Vector3f normalize(float length) {
- float scalar = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, z * z))) * length;
- this.x = this.x * scalar;
- this.y = this.y * scalar;
- this.z = this.z * scalar;
- return this;
- }
-
- public Vector3f normalize(float length, Vector3f dest) {
- float scalar = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, z * z))) * length;
- dest.x = this.x * scalar;
- dest.y = this.y * scalar;
- dest.z = this.z * scalar;
- return dest;
- }
-
- /**
- * Set this vector to be the cross product of itself and v
.
- *
- * @param v
- * the other vector
- * @return this
- */
- public Vector3f cross(Vector3fc v) {
- float rx = Math.fma(y, v.z(), -z * v.y());
- float ry = Math.fma(z, v.x(), -x * v.z());
- float rz = Math.fma(x, v.y(), -y * v.x());
- this.x = rx;
- this.y = ry;
- this.z = rz;
- return this;
- }
-
- /**
- * Set this vector to be the cross product of itself and (x, y, z)
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @return this
- */
- public Vector3f cross(float x, float y, float z) {
- float rx = Math.fma(this.y, z, -this.z * y);
- float ry = Math.fma(this.z, x, -this.x * z);
- float rz = Math.fma(this.x, y, -this.y * x);
- this.x = rx;
- this.y = ry;
- this.z = rz;
- return this;
- }
-
- public Vector3f cross(Vector3fc v, Vector3f dest) {
- float rx = Math.fma(y, v.z(), -z * v.y());
- float ry = Math.fma(z, v.x(), -x * v.z());
- float rz = Math.fma(x, v.y(), -y * v.x());
- dest.x = rx;
- dest.y = ry;
- dest.z = rz;
- return dest;
- }
-
- public Vector3f cross(float x, float y, float z, Vector3f dest) {
- float rx = Math.fma(this.y, z, -this.z * y);
- float ry = Math.fma(this.z, x, -this.x * z);
- float rz = Math.fma(this.x, y, -this.y * x);
- dest.x = rx;
- dest.y = ry;
- dest.z = rz;
- return dest;
- }
-
- public float distance(Vector3fc v) {
- float dx = this.x - v.x();
- float dy = this.y - v.y();
- float dz = this.z - v.z();
- return Math.sqrt(Math.fma(dx, dx, Math.fma(dy, dy, dz * dz)));
- }
-
- public float distance(float x, float y, float z) {
- float dx = this.x - x;
- float dy = this.y - y;
- float dz = this.z - z;
- return Math.sqrt(Math.fma(dx, dx, Math.fma(dy, dy, dz * dz)));
- }
-
- public float distanceSquared(Vector3fc v) {
- float dx = this.x - v.x();
- float dy = this.y - v.y();
- float dz = this.z - v.z();
- return Math.fma(dx, dx, Math.fma(dy, dy, dz * dz));
- }
-
- public float distanceSquared(float x, float y, float z) {
- float dx = this.x - x;
- float dy = this.y - y;
- float dz = this.z - z;
- return Math.fma(dx, dx, Math.fma(dy, dy, dz * dz));
- }
-
- /**
- * Return the distance between (x1, y1, z1)
and (x2, y2, z2)
.
- *
- * @param x1
- * the x component of the first vector
- * @param y1
- * the y component of the first vector
- * @param z1
- * the z component of the first vector
- * @param x2
- * the x component of the second vector
- * @param y2
- * the y component of the second vector
- * @param z2
- * the z component of the second vector
- * @return the euclidean distance
- */
- public static float distance(float x1, float y1, float z1, float x2, float y2, float z2) {
- return Math.sqrt(distanceSquared(x1, y1, z1, x2, y2, z2));
- }
-
- /**
- * Return the squared distance between (x1, y1, z1)
and (x2, y2, z2)
.
- *
- * @param x1
- * the x component of the first vector
- * @param y1
- * the y component of the first vector
- * @param z1
- * the z component of the first vector
- * @param x2
- * the x component of the second vector
- * @param y2
- * the y component of the second vector
- * @param z2
- * the z component of the second vector
- * @return the euclidean distance squared
- */
- public static float distanceSquared(float x1, float y1, float z1, float x2, float y2, float z2) {
- float dx = x1 - x2;
- float dy = y1 - y2;
- float dz = z1 - z2;
- return Math.fma(dx, dx, Math.fma(dy, dy, dz * dz));
- }
-
- public float dot(Vector3fc v) {
- return Math.fma(this.x, v.x(), Math.fma(this.y, v.y(), this.z * v.z()));
- }
-
- public float dot(float x, float y, float z) {
- return Math.fma(this.x, x, Math.fma(this.y, y, this.z * z));
- }
-
- public float angleCos(Vector3fc v) {
- float x = this.x, y = this.y, z = this.z;
- float length1Squared = Math.fma(x, x, Math.fma(y, y, z * z));
- float length2Squared = Math.fma(v.x(), v.x(), Math.fma(v.y(), v.y(), v.z() * v.z()));
- float dot = Math.fma(x, v.x(), Math.fma(y, v.y(), z * v.z()));
- return dot / (float)Math.sqrt(length1Squared * length2Squared);
- }
-
- public float angle(Vector3fc v) {
- float cos = angleCos(v);
- // This is because sometimes cos goes above 1 or below -1 because of lost precision
- cos = cos < 1 ? cos : 1;
- cos = cos > -1 ? cos : -1;
- return Math.acos(cos);
- }
-
- public float angleSigned(Vector3fc v, Vector3fc n) {
- return angleSigned(v.x(), v.y(), v.z(), n.x(), n.y(), n.z());
- }
-
- public float angleSigned(float x, float y, float z, float nx, float ny, float nz) {
- float tx = this.x, ty = this.y, tz = this.z;
- return Math.atan2(
- (ty * z - tz * y) * nx + (tz * x - tx * z) * ny + (tx * y - ty * x) * nz,
- tx * x + ty * y + tz * z);
- }
-
- /**
- * Set the components of this vector to be the component-wise minimum of this and the other vector.
- *
- * @param v
- * the other vector
- * @return this
- */
- public Vector3f min(Vector3fc v) {
- float x = this.x, y = this.y, z = this.z;
- this.x = x < v.x() ? x : v.x();
- this.y = y < v.y() ? y : v.y();
- this.z = z < v.z() ? z : v.z();
- return this;
- }
-
- public Vector3f min(Vector3fc v, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- dest.x = x < v.x() ? x : v.x();
- dest.y = y < v.y() ? y : v.y();
- dest.z = z < v.z() ? z : v.z();
- return dest;
- }
-
- /**
- * Set the components of this vector to be the component-wise maximum of this and the other vector.
- *
- * @param v
- * the other vector
- * @return this
- */
- public Vector3f max(Vector3fc v) {
- float x = this.x, y = this.y, z = this.z;
- this.x = x > v.x() ? x : v.x();
- this.y = y > v.y() ? y : v.y();
- this.z = z > v.z() ? z : v.z();
- return this;
- }
-
- public Vector3f max(Vector3fc v, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- dest.x = x > v.x() ? x : v.x();
- dest.y = y > v.y() ? y : v.y();
- dest.z = z > v.z() ? z : v.z();
- return dest;
- }
-
- /**
- * Set all components to zero.
- *
- * @return this
- */
- public Vector3f zero() {
- this.x = 0;
- this.y = 0;
- this.z = 0;
- return this;
- }
-
- /**
- * Return a string representation of this vector.
- * 0.000E0;-
".
- *
- * @return the string representation
- */
- public String toString() {
- return Runtime.formatNumbers(toString(Options.NUMBER_FORMAT));
- }
-
- /**
- * Return a string representation of this vector by formatting the vector components with the given {@link NumberFormat}.
- *
- * @param formatter
- * the {@link NumberFormat} used to format the vector components with
- * @return the string representation
- */
- public String toString(NumberFormat formatter) {
- return "(" + Runtime.format(x, formatter) + " " + Runtime.format(y, formatter) + " " + Runtime.format(z, formatter) + ")";
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeFloat(x);
- out.writeFloat(y);
- out.writeFloat(z);
- }
-
- public void readExternal(ObjectInput in) throws IOException,
- ClassNotFoundException {
- set(in.readFloat(), in.readFloat(), in.readFloat());
- }
-
- /**
- * Negate this vector.
- *
- * @return this
- */
- public Vector3f negate() {
- this.x = -x;
- this.y = -y;
- this.z = -z;
- return this;
- }
-
- public Vector3f negate(Vector3f dest) {
- dest.x = -x;
- dest.y = -y;
- dest.z = -z;
- return dest;
- }
-
- /**
- * Set this
vector's components to their respective absolute values.
- *
- * @return this
- */
- public Vector3f absolute() {
- this.x = Math.abs(this.x);
- this.y = Math.abs(this.y);
- this.z = Math.abs(this.z);
- return this;
- }
-
- public Vector3f absolute(Vector3f dest) {
- dest.x = Math.abs(this.x);
- dest.y = Math.abs(this.y);
- dest.z = Math.abs(this.z);
- return dest;
- }
-
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Float.floatToIntBits(x);
- result = prime * result + Float.floatToIntBits(y);
- result = prime * result + Float.floatToIntBits(z);
- return result;
- }
-
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Vector3f other = (Vector3f) obj;
- if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x))
- return false;
- if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y))
- return false;
- if (Float.floatToIntBits(z) != Float.floatToIntBits(other.z))
- return false;
- return true;
- }
-
- public boolean equals(Vector3fc v, float delta) {
- if (this == v)
- return true;
- if (v == null)
- return false;
- if (!(v instanceof Vector3fc))
- return false;
- if (!Runtime.equals(x, v.x(), delta))
- return false;
- if (!Runtime.equals(y, v.y(), delta))
- return false;
- if (!Runtime.equals(z, v.z(), delta))
- return false;
- return true;
- }
-
- public boolean equals(float x, float y, float z) {
- if (Float.floatToIntBits(this.x) != Float.floatToIntBits(x))
- return false;
- if (Float.floatToIntBits(this.y) != Float.floatToIntBits(y))
- return false;
- if (Float.floatToIntBits(this.z) != Float.floatToIntBits(z))
- return false;
- return true;
- }
-
- /**
- * Reflect this vector about the given normal
vector.
- *
- * @param normal
- * the vector to reflect about
- * @return this
- */
- public Vector3f reflect(Vector3fc normal) {
- float x = normal.x();
- float y = normal.y();
- float z = normal.z();
- float dot = Math.fma(this.x, x, Math.fma(this.y, y, this.z * z));
- this.x = this.x - (dot + dot) * x;
- this.y = this.y - (dot + dot) * y;
- this.z = this.z - (dot + dot) * z;
- return this;
- }
-
- /**
- * Reflect this vector about the given normal vector.
- *
- * @param x
- * the x component of the normal
- * @param y
- * the y component of the normal
- * @param z
- * the z component of the normal
- * @return this
- */
- public Vector3f reflect(float x, float y, float z) {
- float dot = Math.fma(this.x, x, Math.fma(this.y, y, this.z * z));
- this.x = this.x - (dot + dot) * x;
- this.y = this.y - (dot + dot) * y;
- this.z = this.z - (dot + dot) * z;
- return this;
- }
-
- public Vector3f reflect(Vector3fc normal, Vector3f dest) {
- return reflect(normal.x(), normal.y(), normal.z(), dest);
- }
-
- public Vector3f reflect(float x, float y, float z, Vector3f dest) {
- float dot = this.dot(x, y, z);
- dest.x = this.x - (dot + dot) * x;
- dest.y = this.y - (dot + dot) * y;
- dest.z = this.z - (dot + dot) * z;
- return dest;
- }
-
- /**
- * Compute the half vector between this and the other vector.
- *
- * @param other
- * the other vector
- * @return this
- */
- public Vector3f half(Vector3fc other) {
- return this.set(this).add(other.x(), other.y(), other.z()).normalize();
- }
-
- /**
- * Compute the half vector between this and the vector (x, y, z)
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @return this
- */
- public Vector3f half(float x, float y, float z) {
- return half(x, y, z, this);
- }
-
- public Vector3f half(Vector3fc other, Vector3f dest) {
- return half(other.x(), other.y(), other.z(), dest);
- }
-
- public Vector3f half(float x, float y, float z, Vector3f dest) {
- return dest.set(this).add(x, y, z).normalize();
- }
-
- public Vector3f smoothStep(Vector3fc v, float t, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- float t2 = t * t;
- float t3 = t2 * t;
- dest.x = (x + x - v.x() - v.x()) * t3 + (3.0f * v.x() - 3.0f * x) * t2 + x * t + x;
- dest.y = (y + y - v.y() - v.y()) * t3 + (3.0f * v.y() - 3.0f * y) * t2 + y * t + y;
- dest.z = (z + z - v.z() - v.z()) * t3 + (3.0f * v.z() - 3.0f * z) * t2 + z * t + z;
- return dest;
- }
-
- public Vector3f hermite(Vector3fc t0, Vector3fc v1, Vector3fc t1, float t, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z;
- float t2 = t * t;
- float t3 = t2 * t;
- dest.x = (x + x - v1.x() - v1.x() + t1.x() + t0.x()) * t3 + (3.0f * v1.x() - 3.0f * x - t0.x() - t0.x() - t1.x()) * t2 + x * t + x;
- dest.y = (y + y - v1.y() - v1.y() + t1.y() + t0.y()) * t3 + (3.0f * v1.y() - 3.0f * y - t0.y() - t0.y() - t1.y()) * t2 + y * t + y;
- dest.z = (z + z - v1.z() - v1.z() + t1.z() + t0.z()) * t3 + (3.0f * v1.z() - 3.0f * z - t0.z() - t0.z() - t1.z()) * t2 + z * t + z;
- return dest;
- }
-
- /**
- * Linearly interpolate this
and other
using the given interpolation factor t
- * and store the result in this
.
- * t
is 0.0
then the result is this
. If the interpolation factor is 1.0
- * then the result is other
.
- *
- * @param other
- * the other vector
- * @param t
- * the interpolation factor between 0.0 and 1.0
- * @return this
- */
- public Vector3f lerp(Vector3fc other, float t) {
- return lerp(other, t, this);
- }
-
- public Vector3f lerp(Vector3fc other, float t, Vector3f dest) {
- dest.x = Math.fma(other.x() - x, t, x);
- dest.y = Math.fma(other.y() - y, t, y);
- dest.z = Math.fma(other.z() - z, t, z);
- return dest;
- }
-
- public float get(int component) throws IllegalArgumentException {
- switch (component) {
- case 0:
- return x;
- case 1:
- return y;
- case 2:
- return z;
- default:
- throw new IllegalArgumentException();
- }
- }
-
- public Vector3f get(Vector3f dest) {
- dest.x = this.x();
- dest.y = this.y();
- dest.z = this.z();
- return dest;
- }
-
- public int maxComponent() {
- float absX = Math.abs(x);
- float absY = Math.abs(y);
- float absZ = Math.abs(z);
- if (absX >= absY && absX >= absZ) {
- return 0;
- } else if (absY >= absZ) {
- return 1;
- }
- return 2;
- }
-
- public int minComponent() {
- float absX = Math.abs(x);
- float absY = Math.abs(y);
- float absZ = Math.abs(z);
- if (absX < absY && absX < absZ) {
- return 0;
- } else if (absY < absZ) {
- return 1;
- }
- return 2;
- }
-
- public Vector3f orthogonalize(Vector3fc v, Vector3f dest) {
- /*
- * http://lolengine.net/blog/2013/09/21/picking-orthogonal-vector-combing-coconuts
- */
- float rx, ry, rz;
- if (Math.abs(v.x()) > Math.abs(v.z())) {
- rx = -v.y();
- ry = v.x();
- rz = 0.0f;
- } else {
- rx = 0.0f;
- ry = -v.z();
- rz = v.y();
- }
- float invLen = Math.invsqrt(rx * rx + ry * ry + rz * rz);
- dest.x = rx * invLen;
- dest.y = ry * invLen;
- dest.z = rz * invLen;
- return dest;
- }
-
- /**
- * Transform this
vector so that it is orthogonal to the given vector v
and normalize the result.
- * this
vector so that it is orthogonal to the given unit vector v
and normalize the result.
- * v
is assumed to be a {@link #normalize() unit} vector.
- * x, y, z
order
- * @return the passed in buffer
- * @see #get(int, FloatBuffer)
- */
- FloatBuffer get(FloatBuffer buffer);
-
- /**
- * Store this vector into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- * x, y, z
order
- * @return the passed in buffer
- */
- FloatBuffer get(int index, FloatBuffer buffer);
-
- /**
- * Store this vector into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- * x, y, z
order
- * @return the passed in buffer
- * @see #get(int, ByteBuffer)
- */
- ByteBuffer get(ByteBuffer buffer);
-
- /**
- * Store this vector into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- * x, y, z
order
- * @return the passed in buffer
- */
- ByteBuffer get(int index, ByteBuffer buffer);
-
- /**
- * Store this vector at the given off-heap memory address.
- * dest
.
- *
- * @param v
- * the vector to subtract
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f sub(Vector3fc v, Vector3f dest);
-
- /**
- * Decrement the components of this vector by the given values and store the result in dest
.
- *
- * @param x
- * the x component to subtract
- * @param y
- * the y component to subtract
- * @param z
- * the z component to subtract
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f sub(float x, float y, float z, Vector3f dest);
-
- /**
- * Add the supplied vector to this one and store the result in dest
.
- *
- * @param v
- * the vector to add
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f add(Vector3fc v, Vector3f dest);
-
- /**
- * Increment the components of this vector by the given values and store the result in dest
.
- *
- * @param x
- * the x component to add
- * @param y
- * the y component to add
- * @param z
- * the z component to add
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f add(float x, float y, float z, Vector3f dest);
-
- /**
- * Add the component-wise multiplication of a * b
to this vector
- * and store the result in dest
.
- *
- * @param a
- * the first multiplicand
- * @param b
- * the second multiplicand
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f fma(Vector3fc a, Vector3fc b, Vector3f dest);
-
- /**
- * Add the component-wise multiplication of a * b
to this vector
- * and store the result in dest
.
- *
- * @param a
- * the first multiplicand
- * @param b
- * the second multiplicand
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f fma(float a, Vector3fc b, Vector3f dest);
-
- /**
- * Add the component-wise multiplication of this * a
to b
- * and store the result in dest
.
- *
- * @param a
- * the multiplicand
- * @param b
- * the addend
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulAdd(Vector3fc a, Vector3fc b, Vector3f dest);
-
- /**
- * Add the component-wise multiplication of this * a
to b
- * and store the result in dest
.
- *
- * @param a
- * the multiplicand
- * @param b
- * the addend
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulAdd(float a, Vector3fc b, Vector3f dest);
-
- /**
- * Multiply this Vector3f component-wise by another Vector3f and store the result in dest
.
- *
- * @param v
- * the vector to multiply by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mul(Vector3fc v, Vector3f dest);
-
- /**
- * Divide this Vector3f component-wise by another Vector3f and store the result in dest
.
- *
- * @param v
- * the vector to divide by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f div(Vector3fc v, Vector3f dest);
-
- /**
- * Multiply the given matrix mat
with this Vector3f, perform perspective division
- * and store the result in dest
.
- * w=1.0
as the fourth vector component.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulProject(Matrix4fc mat, Vector3f dest);
-
- /**
- * Multiply the given matrix mat
with this Vector3f, perform perspective division
- * and store the result in dest
.
- * w
as the fourth vector component.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @param w
- * the w component to use
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulProject(Matrix4fc mat, float w, Vector3f dest);
-
- /**
- * Multiply the given matrix with this Vector3f and store the result in dest
.
- *
- * @param mat
- * the matrix
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mul(Matrix3fc mat, Vector3f dest);
-
- /**
- * Multiply the transpose of the given matrix with this Vector3f and store the result in dest
.
- *
- * @param mat
- * the matrix
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulTranspose(Matrix3fc mat, Vector3f dest);
-
- /**
- * Multiply the given 4x4 matrix mat
with this
and store the
- * result in dest
.
- * w
component of this
to be 1.0
.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulPosition(Matrix4fc mat, Vector3f dest);
-
- /**
- * Multiply the transpose of the given 4x4 matrix mat
with this
and store the
- * result in dest
.
- * w
component of this
to be 1.0
.
- *
- * @param mat
- * the matrix whose transpose to multiply this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulTransposePosition(Matrix4fc mat, Vector3f dest);
-
- /**
- * Multiply the given 4x4 matrix mat
with this
, store the
- * result in dest
and return the w component of the resulting 4D vector.
- * w
component of this
to be 1.0
.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @param dest
- * will hold the (x, y, z)
components of the resulting vector
- * @return the w component of the resulting 4D vector after multiplication
- */
- float mulPositionW(Matrix4fc mat, Vector3f dest);
-
- /**
- * Multiply the given 4x4 matrix mat
with this
and store the
- * result in dest
.
- * w
component of this
to be 0.0
.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulDirection(Matrix4fc mat, Vector3f dest);
-
- /**
- * Multiply the transpose of the given 4x4 matrix mat
with this
and store the
- * result in dest
.
- * w
component of this
to be 0.0
.
- *
- * @param mat
- * the matrix whose transpose to multiply this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulTransposeDirection(Matrix4fc mat, Vector3f dest);
-
- /**
- * Multiply all components of this {@link Vector3f} by the given scalar
- * value and store the result in dest
.
- *
- * @param scalar
- * the scalar to multiply this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mul(float scalar, Vector3f dest);
-
- /**
- * Multiply the components of this Vector3f by the given scalar values and store the result in dest
.
- *
- * @param x
- * the x component to multiply this vector by
- * @param y
- * the y component to multiply this vector by
- * @param z
- * the z component to multiply this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mul(float x, float y, float z, Vector3f dest);
-
- /**
- * Divide all components of this {@link Vector3f} by the given scalar
- * value and store the result in dest
.
- *
- * @param scalar
- * the scalar to divide by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f div(float scalar, Vector3f dest);
-
- /**
- * Divide the components of this Vector3f by the given scalar values and store the result in dest
.
- *
- * @param x
- * the x component to divide this vector by
- * @param y
- * the y component to divide this vector by
- * @param z
- * the z component to divide this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f div(float x, float y, float z, Vector3f dest);
-
- /**
- * Rotate this vector by the given quaternion quat
and store the result in dest
.
- *
- * @see Quaternionfc#transform(Vector3f)
- *
- * @param quat
- * the quaternion to rotate this vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f rotate(Quaternionfc quat, Vector3f dest);
-
- /**
- * Compute the quaternion representing a rotation of this
vector to point along toDir
- * and store the result in dest
.
- * this
vector to point along (toDirX, toDirY, toDirZ)
- * and store the result in dest
.
- * dest
.
- *
- * @param angle
- * the angle in radians
- * @param aX
- * the x component of the rotation axis
- * @param aY
- * the y component of the rotation axis
- * @param aZ
- * the z component of the rotation axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f rotateAxis(float angle, float aX, float aY, float aZ, Vector3f dest);
-
- /**
- * Rotate this vector the specified radians around the X axis and store the result
- * into dest
.
- *
- * @param angle
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f rotateX(float angle, Vector3f dest);
-
- /**
- * Rotate this vector the specified radians around the Y axis and store the result
- * into dest
.
- *
- * @param angle
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f rotateY(float angle, Vector3f dest);
-
- /**
- * Rotate this vector the specified radians around the Z axis and store the result
- * into dest
.
- *
- * @param angle
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f rotateZ(float angle, Vector3f dest);
-
- /**
- * Return the length squared of this vector.
- *
- * @return the length squared
- */
- float lengthSquared();
-
- /**
- * Return the length of this vector.
- *
- * @return the length
- */
- float length();
-
- /**
- * Normalize this vector and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f normalize(Vector3f dest);
-
- /**
- * Scale this vector to have the given length and store the result in dest
.
- *
- * @param length
- * the desired length
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f normalize(float length, Vector3f dest);
-
- /**
- * Compute the cross product of this vector and v
and store the result in dest
.
- *
- * @param v
- * the other vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f cross(Vector3fc v, Vector3f dest);
-
- /**
- * Compute the cross product of this vector and (x, y, z)
and store the result in dest
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f cross(float x, float y, float z, Vector3f dest);
-
- /**
- * Return the distance between this Vector and v
.
- *
- * @param v
- * the other vector
- * @return the distance
- */
- float distance(Vector3fc v);
-
- /**
- * Return the distance between this
vector and (x, y, z)
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @return the euclidean distance
- */
- float distance(float x, float y, float z);
-
- /**
- * Return the square of the distance between this vector and v
.
- *
- * @param v
- * the other vector
- * @return the squared of the distance
- */
- float distanceSquared(Vector3fc v);
-
- /**
- * Return the square of the distance between this
vector and (x, y, z)
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @return the square of the distance
- */
- float distanceSquared(float x, float y, float z);
-
- /**
- * Return the dot product of this vector and the supplied vector.
- *
- * @param v
- * the other vector
- * @return the dot product
- */
- float dot(Vector3fc v);
-
- /**
- * Return the dot product of this vector and the vector (x, y, z)
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @return the dot product
- */
- float dot(float x, float y, float z);
-
- /**
- * Return the cosine of the angle between this vector and the supplied vector. Use this instead of Math.cos(this.angle(v)).
- *
- * @see #angle(Vector3fc)
- *
- * @param v
- * the other vector
- * @return the cosine of the angle
- */
- float angleCos(Vector3fc v);
-
- /**
- * Return the angle between this vector and the supplied vector.
- *
- * @see #angleCos(Vector3fc)
- *
- * @param v
- * the other vector
- * @return the angle, in radians
- */
- float angle(Vector3fc v);
-
- /**
- * Return the signed angle between this vector and the supplied vector with
- * respect to the plane with the given normal vector n
.
- *
- * @see #angleCos(Vector3fc)
- *
- * @param v
- * the other vector
- * @param n
- * the plane's normal vector
- * @return the angle, in radians
- */
- float angleSigned(Vector3fc v, Vector3fc n);
-
- /**
- * Return the signed angle between this vector and the supplied vector with
- * respect to the plane with the given normal vector (nx, ny, nz)
.
- *
- * @param x
- * the x coordinate of the other vector
- * @param y
- * the y coordinate of the other vector
- * @param z
- * the z coordinate of the other vector
- * @param nx
- * the x coordinate of the plane's normal vector
- * @param ny
- * the y coordinate of the plane's normal vector
- * @param nz
- * the z coordinate of the plane's normal vector
- * @return the angle, in radians
- */
- float angleSigned(float x, float y, float z, float nx, float ny, float nz);
-
- /**
- * Set the components of dest
to be the component-wise minimum of this and the other vector.
- *
- * @param v
- * the other vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f min(Vector3fc v, Vector3f dest);
-
- /**
- * Set the components of dest
to be the component-wise maximum of this and the other vector.
- *
- * @param v
- * the other vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f max(Vector3fc v, Vector3f dest);
-
- /**
- * Negate this vector and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f negate(Vector3f dest);
-
- /**
- * Compute the absolute values of the individual components of this
and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f absolute(Vector3f dest);
-
- /**
- * Reflect this vector about the given normal
vector and store the result in dest
.
- *
- * @param normal
- * the vector to reflect about
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f reflect(Vector3fc normal, Vector3f dest);
-
- /**
- * Reflect this vector about the given normal vector and store the result in dest
.
- *
- * @param x
- * the x component of the normal
- * @param y
- * the y component of the normal
- * @param z
- * the z component of the normal
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f reflect(float x, float y, float z, Vector3f dest);
-
- /**
- * Compute the half vector between this and the other vector and store the result in dest
.
- *
- * @param other
- * the other vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f half(Vector3fc other, Vector3f dest);
-
- /**
- * Compute the half vector between this and the vector (x, y, z)
- * and store the result in dest
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f half(float x, float y, float z, Vector3f dest);
-
- /**
- * Compute a smooth-step (i.e. hermite with zero tangents) interpolation
- * between this
vector and the given vector v
and
- * store the result in dest
.
- *
- * @param v
- * the other vector
- * @param t
- * the interpolation factor, within [0..1]
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f smoothStep(Vector3fc v, float t, Vector3f dest);
-
- /**
- * Compute a hermite interpolation between this
vector with its
- * associated tangent t0
and the given vector v
- * with its tangent t1
and store the result in
- * dest
.
- *
- * @param t0
- * the tangent of this
vector
- * @param v1
- * the other vector
- * @param t1
- * the tangent of the other vector
- * @param t
- * the interpolation factor, within [0..1]
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f hermite(Vector3fc t0, Vector3fc v1, Vector3fc t1, float t, Vector3f dest);
-
- /**
- * Linearly interpolate this
and other
using the given interpolation factor t
- * and store the result in dest
.
- * t
is 0.0
then the result is this
. If the interpolation factor is 1.0
- * then the result is other
.
- *
- * @param other
- * the other vector
- * @param t
- * the interpolation factor between 0.0 and 1.0
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f lerp(Vector3fc other, float t, Vector3f dest);
-
- /**
- * Get the value of the specified component of this vector.
- *
- * @param component
- * the component, within [0..2]
- * @return the value
- * @throws IllegalArgumentException if component
is not within [0..2]
- */
- float get(int component) throws IllegalArgumentException;
-
- /**
- * Set the components of the given vector dest
to those of this
vector.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f get(Vector3f dest);
-
- /**
- * Determine the component with the biggest absolute value.
- *
- * @return the component index, within [0..2]
- */
- int maxComponent();
-
- /**
- * Determine the component with the smallest (towards zero) absolute value.
- *
- * @return the component index, within [0..2]
- */
- int minComponent();
-
- /**
- * Transform this
vector so that it is orthogonal to the given vector v
, normalize the result and store it into dest
.
- * this
vector so that it is orthogonal to the given unit vector v
, normalize the result and store it into dest
.
- * v
is assumed to be a {@link #normalize(Vector3f) unit} vector.
- * dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f floor(Vector3f dest);
-
- /**
- * Compute for each component of this vector the smallest (closest to negative
- * infinity) {@code float} value that is greater than or equal to that
- * component and is equal to a mathematical integer and store the result in
- * dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f ceil(Vector3f dest);
-
- /**
- * Compute for each component of this vector the closest float that is equal to
- * a mathematical integer, with ties rounding to positive infinity and store
- * the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f round(Vector3f dest);
-
- /**
- * Determine whether all components are finite floating-point values, that
- * is, they are not {@link Float#isNaN() NaN} and not
- * {@link Float#isInfinite() infinity}.
- *
- * @return {@code true} if all components are finite floating-point values;
- * {@code false} otherwise
- */
- boolean isFinite();
-
- /**
- * Compare the vector components of this
vector with the given vector using the given delta
- * and return whether all of them are equal within a maximum difference of delta
.
- * true
whether all of the vector components are equal; false
otherwise
- */
- boolean equals(Vector3fc v, float delta);
-
- /**
- * Compare the vector components of this
vector with the given (x, y, z)
- * and return whether all of them are equal.
- *
- * @param x
- * the x component to compare to
- * @param y
- * the y component to compare to
- * @param z
- * the z component to compare to
- * @return true
if all the vector components are equal
- */
- boolean equals(float x, float y, float z);
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Vector4f.java b/src/main/java/com/jozufozu/flywheel/util/joml/Vector4f.java
deleted file mode 100644
index 3c7650e9a..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Vector4f.java
+++ /dev/null
@@ -1,1741 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2015-2021 Richard Greenlees
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.io.Externalizable;
-import java.io.IOException;
-import java.io.ObjectInput;
-import java.io.ObjectOutput;
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.text.DecimalFormat;
-import java.text.NumberFormat;
-
-/**
- * Contains the definition of a Vector comprising 4 floats and associated
- * transformations.
- *
- * @author Richard Greenlees
- * @author Kai Burjack
- * @author F. Neurath
- */
-public class Vector4f implements Externalizable, Cloneable, Vector4fc {
-
- private static final long serialVersionUID = 1L;
-
- /**
- * The x component of the vector.
- */
- public float x;
- /**
- * The y component of the vector.
- */
- public float y;
- /**
- * The z component of the vector.
- */
- public float z;
- /**
- * The w component of the vector.
- */
- public float w;
-
- /**
- * Create a new {@link Vector4f} of (0, 0, 0, 1)
.
- */
- public Vector4f() {
- this.w = 1.0f;
- }
-
- /**
- * Create a new {@link Vector4f} with the same values as v
.
- *
- * @param v
- * the {@link Vector4fc} to copy the values from
- */
- public Vector4f(Vector4fc v) {
- this.x = v.x();
- this.y = v.y();
- this.z = v.z();
- this.w = v.w();
- }
-
- /**
- * Create a new {@link Vector4f} with the first three components from the
- * given v
and the given w
.
- *
- * @param v
- * the {@link Vector3fc}
- * @param w
- * the w component
- */
- public Vector4f(Vector3fc v, float w) {
- this.x = v.x();
- this.y = v.y();
- this.z = v.z();
- this.w = w;
- }
-
- /**
- * Create a new {@link Vector4f} and initialize all four components with the given value.
- *
- * @param d
- * the value of all four components
- */
- public Vector4f(float d) {
- this.x = d;
- this.y = d;
- this.z = d;
- this.w = d;
- }
-
- /**
- * Create a new {@link Vector4f} with the given component values.
- *
- * @param x
- * the x component
- * @param y
- * the y component
- * @param z
- * the z component
- * @param w
- * the w component
- */
- public Vector4f(float x, float y, float z, float w) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.w = w;
- }
-
- /**
- * Create a new {@link Vector4f} and initialize its four components from the first
- * four elements of the given array.
- *
- * @param xyzw
- * the array containing at least four elements
- */
- public Vector4f(float[] xyzw) {
- this.x = xyzw[0];
- this.y = xyzw[1];
- this.z = xyzw[2];
- this.w = xyzw[3];
- }
-
- /**
- * Create a new {@link Vector4f} and read this vector from the supplied {@link ByteBuffer}
- * at the current buffer {@link ByteBuffer#position() position}.
- * x, y, z, w
order
- * @see #Vector4f(int, ByteBuffer)
- */
- public Vector4f(ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- }
-
- /**
- * Create a new {@link Vector4f} and read this vector from the supplied {@link ByteBuffer}
- * starting at the specified absolute buffer position/index.
- * x, y, z, w
order
- */
- public Vector4f(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- }
-
- /**
- * Create a new {@link Vector4f} and read this vector from the supplied {@link FloatBuffer}
- * at the current buffer {@link FloatBuffer#position() position}.
- * x, y, z, w
order
- * @see #Vector4f(int, FloatBuffer)
- */
- public Vector4f(FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- }
-
- /**
- * Create a new {@link Vector4f} and read this vector from the supplied {@link FloatBuffer}
- * starting at the specified absolute buffer position/index.
- * x, y, z, w
order
- */
- public Vector4f(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- }
-
- public float x() {
- return this.x;
- }
-
- public float y() {
- return this.y;
- }
-
- public float z() {
- return this.z;
- }
-
- public float w() {
- return this.w;
- }
-
- /**
- * Set this {@link Vector4f} to the values of the given v
.
- *
- * @param v
- * the vector whose values will be copied into this
- * @return this
- */
- public Vector4f set(Vector4fc v) {
- this.x = v.x();
- this.y = v.y();
- this.z = v.z();
- this.w = v.w();
- return this;
- }
-
- /**
- * Set the first three components of this to the components of
- * v
and the last component to w
.
- *
- * @param v
- * the {@link Vector3fc} to copy
- * @param w
- * the w component
- * @return this
- */
- public Vector4f set(Vector3fc v, float w) {
- this.x = v.x();
- this.y = v.y();
- this.z = v.z();
- this.w = w;
- return this;
- }
-
- /**
- * Set the x, y, z, and w components to the supplied value.
- *
- * @param d
- * the value of all four components
- * @return this
- */
- public Vector4f set(float d) {
- this.x = d;
- this.y = d;
- this.z = d;
- this.w = d;
- return this;
- }
-
- /**
- * Set the x, y, z, and w components to the supplied values.
- *
- * @param x
- * the x component
- * @param y
- * the y component
- * @param z
- * the z component
- * @param w
- * the w component
- * @return this
- */
- public Vector4f set(float x, float y, float z, float w) {
- this.x = x;
- this.y = y;
- this.z = z;
- this.w = w;
- return this;
- }
-
- /**
- * Set the x, y, z components to the supplied values.
- *
- * @param x
- * the x component
- * @param y
- * the y component
- * @param z
- * the z component
- * @return this
- */
- public Vector4f set(float x, float y, float z) {
- this.x = x;
- this.y = y;
- this.z = z;
- return this;
- }
-
- /**
- * Set the x, y, z, and w components to the supplied value.
- *
- * @param d
- * the value of all four components
- * @return this
- */
- public Vector4f set(double d) {
- this.x = (float) d;
- this.y = (float) d;
- this.z = (float) d;
- this.w = (float) d;
- return this;
- }
-
- /**
- * Set the x, y, z, and w components to the supplied values.
- *
- * @param x
- * the x component
- * @param y
- * the y component
- * @param z
- * the z component
- * @param w
- * the w component
- * @return this
- */
- public Vector4f set(double x, double y, double z, double w) {
- this.x = (float) x;
- this.y = (float) y;
- this.z = (float) z;
- this.w = (float) w;
- return this;
- }
-
- /**
- * Set the four components of this vector to the first four elements of the given array.
- *
- * @param xyzw
- * the array containing at least four elements
- * @return this
- */
- public Vector4f set(float[] xyzw) {
- this.x = xyzw[0];
- this.y = xyzw[1];
- this.z = xyzw[2];
- this.w = xyzw[3];
- return this;
- }
-
- /**
- * Read this vector from the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- * x, y, z, w
order
- * @return this
- * @see #set(int, ByteBuffer)
- */
- public Vector4f set(ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- return this;
- }
-
- /**
- * Read this vector from the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- * x, y, z, w
order
- * @return this
- */
- public Vector4f set(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- return this;
- }
-
- /**
- * Read this vector from the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- * x, y, z, w
order
- * @return this
- * @see #set(int, FloatBuffer)
- */
- public Vector4f set(FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, buffer.position(), buffer);
- return this;
- }
-
- /**
- * Read this vector from the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- * x, y, z, w
order
- * @return this
- */
- public Vector4f set(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.get(this, index, buffer);
- return this;
- }
-
- /**
- * Set the values of this vector by reading 4 float values from off-heap memory,
- * starting at the given address.
- * [0..3]
- * @param value
- * the value to set
- * @return this
- * @throws IllegalArgumentException if component
is not within [0..3]
- */
- public Vector4f setComponent(int component, float value) throws IllegalArgumentException {
- switch (component) {
- case 0:
- x = value;
- break;
- case 1:
- y = value;
- break;
- case 2:
- z = value;
- break;
- case 3:
- w = value;
- break;
- default:
- throw new IllegalArgumentException();
- }
- return this;
- }
-
- public FloatBuffer get(FloatBuffer buffer) {
- MemUtil.INSTANCE.put(this, buffer.position(), buffer);
- return buffer;
- }
-
- public FloatBuffer get(int index, FloatBuffer buffer) {
- MemUtil.INSTANCE.put(this, index, buffer);
- return buffer;
- }
-
- public ByteBuffer get(ByteBuffer buffer) {
- MemUtil.INSTANCE.put(this, buffer.position(), buffer);
- return buffer;
- }
-
- public ByteBuffer get(int index, ByteBuffer buffer) {
- MemUtil.INSTANCE.put(this, index, buffer);
- return buffer;
- }
-
- public Vector4fc getToAddress(long address) {
- if (Options.NO_UNSAFE)
- throw new UnsupportedOperationException("Not supported when using joml.nounsafe");
- MemUtil.MemUtilUnsafe.put(this, address);
- return this;
- }
-
- /**
- * Subtract the supplied vector from this one.
- *
- * @param v
- * the vector to subtract
- * @return this
- */
- public Vector4f sub(Vector4fc v) {
- this.x = this.x - v.x();
- this.y = this.y - v.y();
- this.z = this.z - v.z();
- this.w = this.w - v.w();
- return this;
- }
-
- /**
- * Subtract (x, y, z, w)
from this.
- *
- * @param x
- * the x component to subtract
- * @param y
- * the y component to subtract
- * @param z
- * the z component to subtract
- * @param w
- * the w component to subtract
- * @return this
- */
- public Vector4f sub(float x, float y, float z, float w) {
- this.x = this.x - x;
- this.y = this.y - y;
- this.z = this.z - z;
- this.w = this.w - w;
- return this;
- }
-
- public Vector4f sub(Vector4fc v, Vector4f dest) {
- dest.x = this.x - v.x();
- dest.y = this.y - v.y();
- dest.z = this.z - v.z();
- dest.w = this.w - v.w();
- return dest;
- }
-
- public Vector4f sub(float x, float y, float z, float w, Vector4f dest) {
- dest.x = this.x - x;
- dest.y = this.y - y;
- dest.z = this.z - z;
- dest.w = this.w - w;
- return dest;
- }
-
- /**
- * Add the supplied vector to this one.
- *
- * @param v
- * the vector to add
- * @return this
- */
- public Vector4f add(Vector4fc v) {
- this.x = x + v.x();
- this.y = y + v.y();
- this.z = z + v.z();
- this.w = w + v.w();
- return this;
- }
-
- public Vector4f add(Vector4fc v, Vector4f dest) {
- dest.x = x + v.x();
- dest.y = y + v.y();
- dest.z = z + v.z();
- dest.w = w + v.w();
- return dest;
- }
-
- /**
- * Increment the components of this vector by the given values.
- *
- * @param x
- * the x component to add
- * @param y
- * the y component to add
- * @param z
- * the z component to add
- * @param w
- * the w component to add
- * @return this
- */
- public Vector4f add(float x, float y, float z, float w) {
- this.x = this.x + x;
- this.y = this.y + y;
- this.z = this.z + z;
- this.w = this.w + w;
- return this;
- }
-
- public Vector4f add(float x, float y, float z, float w, Vector4f dest) {
- dest.x = this.x + x;
- dest.y = this.y + y;
- dest.z = this.z + z;
- dest.w = this.w + w;
- return dest;
- }
-
- /**
- * Add the component-wise multiplication of a * b
to this vector.
- *
- * @param a
- * the first multiplicand
- * @param b
- * the second multiplicand
- * @return this
- */
- public Vector4f fma(Vector4fc a, Vector4fc b) {
- this.x = Math.fma(a.x(), b.x(), x);
- this.y = Math.fma(a.y(), b.y(), y);
- this.z = Math.fma(a.z(), b.z(), z);
- this.w = Math.fma(a.w(), b.w(), w);
- return this;
- }
-
- /**
- * Add the component-wise multiplication of a * b
to this vector.
- *
- * @param a
- * the first multiplicand
- * @param b
- * the second multiplicand
- * @return this
- */
- public Vector4f fma(float a, Vector4fc b) {
- this.x = Math.fma(a, b.x(), x);
- this.y = Math.fma(a, b.y(), y);
- this.z = Math.fma(a, b.z(), z);
- this.w = Math.fma(a, b.w(), w);
- return this;
- }
-
- public Vector4f fma(Vector4fc a, Vector4fc b, Vector4f dest) {
- dest.x = Math.fma(a.x(), b.x(), x);
- dest.y = Math.fma(a.y(), b.y(), y);
- dest.z = Math.fma(a.z(), b.z(), z);
- dest.w = Math.fma(a.w(), b.w(), w);
- return dest;
- }
-
- public Vector4f fma(float a, Vector4fc b, Vector4f dest) {
- dest.x = Math.fma(a, b.x(), x);
- dest.y = Math.fma(a, b.y(), y);
- dest.z = Math.fma(a, b.z(), z);
- dest.w = Math.fma(a, b.w(), w);
- return dest;
- }
-
- /**
- * Add the component-wise multiplication of this * a
to b
- * and store the result in this
.
- *
- * @param a
- * the multiplicand
- * @param b
- * the addend
- * @return this
- */
- public Vector4f mulAdd(Vector4fc a, Vector4fc b) {
- this.x = Math.fma(x, a.x(), b.x());
- this.y = Math.fma(y, a.y(), b.y());
- this.z = Math.fma(z, a.z(), b.z());
- return this;
- }
-
- /**
- * Add the component-wise multiplication of this * a
to b
- * and store the result in this
.
- *
- * @param a
- * the multiplicand
- * @param b
- * the addend
- * @return this
- */
- public Vector4f mulAdd(float a, Vector4fc b) {
- this.x = Math.fma(x, a, b.x());
- this.y = Math.fma(y, a, b.y());
- this.z = Math.fma(z, a, b.z());
- return this;
- }
-
- public Vector4f mulAdd(Vector4fc a, Vector4fc b, Vector4f dest) {
- dest.x = Math.fma(x, a.x(), b.x());
- dest.y = Math.fma(y, a.y(), b.y());
- dest.z = Math.fma(z, a.z(), b.z());
- return dest;
- }
-
- public Vector4f mulAdd(float a, Vector4fc b, Vector4f dest) {
- dest.x = Math.fma(x, a, b.x());
- dest.y = Math.fma(y, a, b.y());
- dest.z = Math.fma(z, a, b.z());
- return dest;
- }
-
- /**
- * Multiply this Vector4f component-wise by another Vector4f.
- *
- * @param v
- * the other vector
- * @return this
- */
- public Vector4f mul(Vector4fc v) {
- this.x = x * v.x();
- this.y = y * v.y();
- this.z = z * v.z();
- this.w = w * v.w();
- return this;
- }
-
- public Vector4f mul(Vector4fc v, Vector4f dest) {
- dest.x = x * v.x();
- dest.y = y * v.y();
- dest.z = z * v.z();
- dest.w = w * v.w();
- return dest;
- }
-
- /**
- * Divide this Vector4f component-wise by another Vector4f.
- *
- * @param v
- * the vector to divide by
- * @return this
- */
- public Vector4f div(Vector4fc v) {
- this.x = x / v.x();
- this.y = y / v.y();
- this.z = z / v.z();
- this.w = w / v.w();
- return this;
- }
-
- public Vector4f div(Vector4fc v, Vector4f dest) {
- dest.x = x / v.x();
- dest.y = y / v.y();
- dest.z = z / v.z();
- dest.w = w / v.w();
- return dest;
- }
-
- /**
- * Multiply the given matrix mat with this Vector4f and store the result in
- * this
.
- *
- * @param mat
- * the matrix to multiply the vector with
- * @return this
- */
- public Vector4f mul(Matrix4fc mat) {
- if ((mat.properties() & Matrix4fc.PROPERTY_AFFINE) != 0)
- return mulAffine(mat, this);
- return mulGeneric(mat, this);
- }
- public Vector4f mul(Matrix4fc mat, Vector4f dest) {
- if ((mat.properties() & Matrix4fc.PROPERTY_AFFINE) != 0)
- return mulAffine(mat, dest);
- return mulGeneric(mat, dest);
- }
-
- /**
- * Multiply the transpose of the given matrix mat
with this Vector4f and store the result in
- * this
.
- *
- * @param mat
- * the matrix whose transpose to multiply the vector with
- * @return this
- */
- public Vector4f mulTranspose(Matrix4fc mat) {
- if ((mat.properties() & Matrix4fc.PROPERTY_AFFINE) != 0)
- return mulAffineTranspose(mat, this);
- return mulGenericTranspose(mat, this);
- }
- public Vector4f mulTranspose(Matrix4fc mat, Vector4f dest) {
- if ((mat.properties() & Matrix4fc.PROPERTY_AFFINE) != 0)
- return mulAffineTranspose(mat, dest);
- return mulGenericTranspose(mat, dest);
- }
-
- public Vector4f mulAffine(Matrix4fc mat, Vector4f dest) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30() * w)));
- dest.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31() * w)));
- dest.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32() * w)));
- dest.w = w;
- return dest;
- }
-
- private Vector4f mulGeneric(Matrix4fc mat, Vector4f dest) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30() * w)));
- dest.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31() * w)));
- dest.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32() * w)));
- dest.w = Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33() * w)));
- return dest;
- }
-
- public Vector4f mulAffineTranspose(Matrix4fc mat, Vector4f dest) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m01(), y, mat.m02() * z));
- dest.y = Math.fma(mat.m10(), x, Math.fma(mat.m11(), y, mat.m12() * z));
- dest.z = Math.fma(mat.m20(), x, Math.fma(mat.m21(), y, mat.m22() * z));
- dest.w = Math.fma(mat.m30(), x, Math.fma(mat.m31(), y, mat.m32() * z + w));
- return dest;
- }
- private Vector4f mulGenericTranspose(Matrix4fc mat, Vector4f dest) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m01(), y, Math.fma(mat.m02(), z, mat.m03() * w)));
- dest.y = Math.fma(mat.m10(), x, Math.fma(mat.m11(), y, Math.fma(mat.m12(), z, mat.m13() * w)));
- dest.z = Math.fma(mat.m20(), x, Math.fma(mat.m21(), y, Math.fma(mat.m22(), z, mat.m23() * w)));
- dest.w = Math.fma(mat.m30(), x, Math.fma(mat.m31(), y, Math.fma(mat.m32(), z, mat.m33() * w)));
- return dest;
- }
-
- public Vector4f mulProject(Matrix4fc mat, Vector4f dest) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- float invW = 1.0f / Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33() * w)));
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30() * w))) * invW;
- dest.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31() * w))) * invW;
- dest.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32() * w))) * invW;
- dest.w = 1.0f;
- return dest;
- }
-
- /**
- * Multiply the given matrix mat
with this Vector4f, perform perspective division.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @return this
- */
- public Vector4f mulProject(Matrix4fc mat) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- float invW = 1.0f / Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33() * w)));
- this.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30() * w))) * invW;
- this.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31() * w))) * invW;
- this.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32() * w))) * invW;
- this.w = 1.0f;
- return this;
- }
-
- public Vector3f mulProject(Matrix4fc mat, Vector3f dest) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- float invW = 1.0f / Math.fma(mat.m03(), x, Math.fma(mat.m13(), y, Math.fma(mat.m23(), z, mat.m33() * w)));
- dest.x = Math.fma(mat.m00(), x, Math.fma(mat.m10(), y, Math.fma(mat.m20(), z, mat.m30() * w))) * invW;
- dest.y = Math.fma(mat.m01(), x, Math.fma(mat.m11(), y, Math.fma(mat.m21(), z, mat.m31() * w))) * invW;
- dest.z = Math.fma(mat.m02(), x, Math.fma(mat.m12(), y, Math.fma(mat.m22(), z, mat.m32() * w))) * invW;
- return dest;
- }
-
- /**
- * Multiply all components of this {@link Vector4f} by the given scalar
- * value.
- *
- * @param scalar
- * the scalar to multiply by
- * @return this
- */
- public Vector4f mul(float scalar) {
- this.x = x * scalar;
- this.y = y * scalar;
- this.z = z * scalar;
- this.w = w * scalar;
- return this;
- }
-
- public Vector4f mul(float scalar, Vector4f dest) {
- dest.x = x * scalar;
- dest.y = y * scalar;
- dest.z = z * scalar;
- dest.w = w * scalar;
- return dest;
- }
-
- /**
- * Multiply the components of this Vector4f by the given scalar values and store the result in this
.
- *
- * @param x
- * the x component to multiply by
- * @param y
- * the y component to multiply by
- * @param z
- * the z component to multiply by
- * @param w
- * the w component to multiply by
- * @return this
- */
- public Vector4f mul(float x, float y, float z, float w) {
- this.x = this.x * x;
- this.y = this.y * y;
- this.z = this.z * z;
- this.w = this.w * w;
- return this;
- }
-
- public Vector4f mul(float x, float y, float z, float w, Vector4f dest) {
- dest.x = this.x * x;
- dest.y = this.y * y;
- dest.z = this.z * z;
- dest.w = this.w * w;
- return dest;
- }
-
- /**
- * Divide all components of this {@link Vector4f} by the given scalar
- * value.
- *
- * @param scalar
- * the scalar to divide by
- * @return this
- */
- public Vector4f div(float scalar) {
- float inv = 1.0f / scalar;
- this.x = x * inv;
- this.y = y * inv;
- this.z = z * inv;
- this.w = w * inv;
- return this;
- }
-
- public Vector4f div(float scalar, Vector4f dest) {
- float inv = 1.0f / scalar;
- dest.x = x * inv;
- dest.y = y * inv;
- dest.z = z * inv;
- dest.w = w * inv;
- return dest;
- }
-
- /**
- * Divide the components of this Vector4f by the given scalar values and store the result in this
.
- *
- * @param x
- * the x component to divide by
- * @param y
- * the y component to divide by
- * @param z
- * the z component to divide by
- * @param w
- * the w component to divide by
- * @return this
- */
- public Vector4f div(float x, float y, float z, float w) {
- this.x = this.x / x;
- this.y = this.y / y;
- this.z = this.z / z;
- this.w = this.w / w;
- return this;
- }
-
- public Vector4f div(float x, float y, float z, float w, Vector4f dest) {
- dest.x = this.x / x;
- dest.y = this.y / y;
- dest.z = this.z / z;
- dest.w = this.w / w;
- return dest;
- }
-
- /**
- * Rotate this vector by the given quaternion quat
and store the result in this
.
- *
- * @see Quaternionf#transform(Vector4f)
- *
- * @param quat
- * the quaternion to rotate this vector
- * @return this
- */
- public Vector4f rotate(Quaternionfc quat) {
- return quat.transform(this, this);
- }
-
- public Vector4f rotate(Quaternionfc quat, Vector4f dest) {
- return quat.transform(this, dest);
- }
-
- /**
- * Rotate this vector the specified radians around the given rotation axis.
- *
- * @param angle
- * the angle in radians
- * @param x
- * the x component of the rotation axis
- * @param y
- * the y component of the rotation axis
- * @param z
- * the z component of the rotation axis
- * @return this
- */
- public Vector4f rotateAbout(float angle, float x, float y, float z) {
- if (y == 0.0f && z == 0.0f && Math.absEqualsOne(x))
- return rotateX(x * angle, this);
- else if (x == 0.0f && z == 0.0f && Math.absEqualsOne(y))
- return rotateY(y * angle, this);
- else if (x == 0.0f && y == 0.0f && Math.absEqualsOne(z))
- return rotateZ(z * angle, this);
- return rotateAxisInternal(angle, x, y, z, this);
- }
-
- public Vector4f rotateAxis(float angle, float aX, float aY, float aZ, Vector4f dest) {
- if (aY == 0.0f && aZ == 0.0f && Math.absEqualsOne(aX))
- return rotateX(aX * angle, dest);
- else if (aX == 0.0f && aZ == 0.0f && Math.absEqualsOne(aY))
- return rotateY(aY * angle, dest);
- else if (aX == 0.0f && aY == 0.0f && Math.absEqualsOne(aZ))
- return rotateZ(aZ * angle, dest);
- return rotateAxisInternal(angle, aX, aY, aZ, dest);
- }
- private Vector4f rotateAxisInternal(float angle, float aX, float aY, float aZ, Vector4f dest) {
- float hangle = angle * 0.5f;
- float sinAngle = Math.sin(hangle);
- float qx = aX * sinAngle, qy = aY * sinAngle, qz = aZ * sinAngle;
- float qw = Math.cosFromSin(sinAngle, hangle);
- float w2 = qw * qw, x2 = qx * qx, y2 = qy * qy, z2 = qz * qz, zw = qz * qw;
- float xy = qx * qy, xz = qx * qz, yw = qy * qw, yz = qy * qz, xw = qx * qw;
- float x = this.x, y = this.y, z = this.z;
- dest.x = (w2 + x2 - z2 - y2) * x + (-zw + xy - zw + xy) * y + (yw + xz + xz + yw) * z;
- dest.y = (xy + zw + zw + xy) * x + ( y2 - z2 + w2 - x2) * y + (yz + yz - xw - xw) * z;
- dest.z = (xz - yw + xz - yw) * x + ( yz + yz + xw + xw) * y + (z2 - y2 - x2 + w2) * z;
- return dest;
- }
-
- /**
- * Rotate this vector the specified radians around the X axis.
- *
- * @param angle
- * the angle in radians
- * @return this
- */
- public Vector4f rotateX(float angle) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float y = this.y * cos - this.z * sin;
- float z = this.y * sin + this.z * cos;
- this.y = y;
- this.z = z;
- return this;
- }
-
- public Vector4f rotateX(float angle, Vector4f dest) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float y = this.y * cos - this.z * sin;
- float z = this.y * sin + this.z * cos;
- dest.x = this.x;
- dest.y = y;
- dest.z = z;
- dest.w = this.w;
- return dest;
- }
-
- /**
- * Rotate this vector the specified radians around the Y axis.
- *
- * @param angle
- * the angle in radians
- * @return this
- */
- public Vector4f rotateY(float angle) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float x = this.x * cos + this.z * sin;
- float z = -this.x * sin + this.z * cos;
- this.x = x;
- this.z = z;
- return this;
- }
-
- public Vector4f rotateY(float angle, Vector4f dest) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float x = this.x * cos + this.z * sin;
- float z = -this.x * sin + this.z * cos;
- dest.x = x;
- dest.y = this.y;
- dest.z = z;
- dest.w = this.w;
- return dest;
- }
-
- /**
- * Rotate this vector the specified radians around the Z axis.
- *
- * @param angle
- * the angle in radians
- * @return this
- */
- public Vector4f rotateZ(float angle) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float x = this.x * cos - this.y * sin;
- float y = this.x * sin + this.y * cos;
- this.x = x;
- this.y = y;
- return this;
- }
-
- public Vector4f rotateZ(float angle, Vector4f dest) {
- float sin = Math.sin(angle), cos = Math.cosFromSin(sin, angle);
- float x = this.x * cos - this.y * sin;
- float y = this.x * sin + this.y * cos;
- dest.x = x;
- dest.y = y;
- dest.z = this.z;
- dest.w = this.w;
- return dest;
- }
-
- public float lengthSquared() {
- return Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w)));
- }
-
- /**
- * Get the length squared of a 4-dimensional single-precision vector.
- *
- * @param x the vector's x component
- * @param y the vector's y component
- * @param z the vector's z component
- * @param w the vector's w component
- *
- * @return the length squared of the given vector
- *
- * @author F. Neurath
- */
- public static float lengthSquared(float x, float y, float z, float w) {
- return Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w)));
- }
-
- /**
- * Get the length squared of a 4-dimensional int vector.
- *
- * @param x the vector's x component
- * @param y the vector's y component
- * @param z the vector's z component
- * @param w the vector's w component
- *
- * @return the length squared of the given vector
- */
- public static float lengthSquared(int x, int y, int z, int w) {
- return Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w)));
- }
-
- public float length() {
- return Math.sqrt(Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w))));
- }
-
- /**
- * Get the length of a 4-dimensional single-precision vector.
- *
- * @param x The vector's x component
- * @param y The vector's y component
- * @param z The vector's z component
- * @param w The vector's w component
- *
- * @return the length of the given vector
- *
- * @author F. Neurath
- */
- public static float length(float x, float y, float z, float w) {
- return Math.sqrt(Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w))));
- }
-
- /**
- * Normalizes this vector.
- *
- * @return this
- */
- public Vector4f normalize() {
- float invLength = 1.0f / length();
- this.x = x * invLength;
- this.y = y * invLength;
- this.z = z * invLength;
- this.w = w * invLength;
- return this;
- }
-
- public Vector4f normalize(Vector4f dest) {
- float invLength = 1.0f / length();
- dest.x = x * invLength;
- dest.y = y * invLength;
- dest.z = z * invLength;
- dest.w = w * invLength;
- return dest;
- }
-
- /**
- * Scale this vector to have the given length.
- *
- * @param length
- * the desired length
- * @return this
- */
- public Vector4f normalize(float length) {
- float invLength = 1.0f / length() * length;
- this.x = x * invLength;
- this.y = y * invLength;
- this.z = z * invLength;
- this.w = w * invLength;
- return this;
- }
-
- public Vector4f normalize(float length, Vector4f dest) {
- float invLength = 1.0f / length() * length;
- dest.x = x * invLength;
- dest.y = y * invLength;
- dest.z = z * invLength;
- dest.w = w * invLength;
- return dest;
- }
-
- /**
- * Normalize this vector by computing only the norm of (x, y, z)
.
- *
- * @return this
- */
- public Vector4f normalize3() {
- float invLength = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, z * z)));
- this.x = x * invLength;
- this.y = y * invLength;
- this.z = z * invLength;
- this.w = w * invLength;
- return this;
- }
-
- public Vector4f normalize3(Vector4f dest) {
- float invLength = Math.invsqrt(Math.fma(x, x, Math.fma(y, y, z * z)));
- dest.x = x * invLength;
- dest.y = y * invLength;
- dest.z = z * invLength;
- dest.w = w * invLength;
- return dest;
- }
-
- public float distance(Vector4fc v) {
- float dx = this.x - v.x();
- float dy = this.y - v.y();
- float dz = this.z - v.z();
- float dw = this.w - v.w();
- return Math.sqrt(Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw))));
- }
-
- public float distance(float x, float y, float z, float w) {
- float dx = this.x - x;
- float dy = this.y - y;
- float dz = this.z - z;
- float dw = this.w - w;
- return Math.sqrt(Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw))));
- }
-
- public float distanceSquared(Vector4fc v) {
- float dx = this.x - v.x();
- float dy = this.y - v.y();
- float dz = this.z - v.z();
- float dw = this.w - v.w();
- return Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw)));
- }
-
- public float distanceSquared(float x, float y, float z, float w) {
- float dx = this.x - x;
- float dy = this.y - y;
- float dz = this.z - z;
- float dw = this.w - w;
- return Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw)));
- }
-
- /**
- * Return the distance between (x1, y1, z1, w1)
and (x2, y2, z2, w2)
.
- *
- * @param x1
- * the x component of the first vector
- * @param y1
- * the y component of the first vector
- * @param z1
- * the z component of the first vector
- * @param w1
- * the w component of the first vector
- * @param x2
- * the x component of the second vector
- * @param y2
- * the y component of the second vector
- * @param z2
- * the z component of the second vector
- * @param w2
- * the 2 component of the second vector
- * @return the euclidean distance
- */
- public static float distance(float x1, float y1, float z1, float w1, float x2, float y2, float z2, float w2) {
- float dx = x1 - x2;
- float dy = y1 - y2;
- float dz = z1 - z2;
- float dw = w1 - w2;
- return Math.sqrt(Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw))));
- }
-
- /**
- * Return the squared distance between (x1, y1, z1, w1)
and (x2, y2, z2, w2)
.
- *
- * @param x1
- * the x component of the first vector
- * @param y1
- * the y component of the first vector
- * @param z1
- * the z component of the first vector
- * @param w1
- * the w component of the first vector
- * @param x2
- * the x component of the second vector
- * @param y2
- * the y component of the second vector
- * @param z2
- * the z component of the second vector
- * @param w2
- * the w component of the second vector
- * @return the euclidean distance squared
- */
- public static float distanceSquared(float x1, float y1, float z1, float w1, float x2, float y2, float z2, float w2) {
- float dx = x1 - x2;
- float dy = y1 - y2;
- float dz = z1 - z2;
- float dw = w1 - w2;
- return Math.fma(dx, dx, Math.fma(dy, dy, Math.fma(dz, dz, dw * dw)));
- }
-
- public float dot(Vector4fc v) {
- return Math.fma(this.x, v.x(), Math.fma(this.y, v.y(), Math.fma(this.z, v.z(), this.w * v.w())));
- }
-
- public float dot(float x, float y, float z, float w) {
- return Math.fma(this.x, x, Math.fma(this.y, y, Math.fma(this.z, z, this.w * w)));
- }
-
- public float angleCos(Vector4fc v) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- float length1Squared = Math.fma(x, x, Math.fma(y, y, Math.fma(z, z, w * w)));
- float length2Squared = Math.fma(v.x(), v.x(), Math.fma(v.y(), v.y(), Math.fma(v.z(), v.z(), v.w() * v.w())));
- float dot = Math.fma(x, v.x(), Math.fma(y, v.y(), Math.fma(z, v.z(), w * v.w())));
- return dot / Math.sqrt(length1Squared * length2Squared);
- }
-
- public float angle(Vector4fc v) {
- float cos = angleCos(v);
- // This is because sometimes cos goes above 1 or below -1 because of lost precision
- cos = cos < 1 ? cos : 1;
- cos = cos > -1 ? cos : -1;
- return Math.acos(cos);
- }
-
- /**
- * Set all components to zero.
- *
- * @return this
- */
- public Vector4f zero() {
- this.x = 0;
- this.y = 0;
- this.z = 0;
- this.w = 0;
- return this;
- }
-
- /**
- * Negate this vector.
- *
- * @return this
- */
- public Vector4f negate() {
- this.x = -x;
- this.y = -y;
- this.z = -z;
- this.w = -w;
- return this;
- }
-
- public Vector4f negate(Vector4f dest) {
- dest.x = -x;
- dest.y = -y;
- dest.z = -z;
- dest.w = -w;
- return dest;
- }
-
- /**
- * Return a string representation of this vector.
- * 0.000E0;-
".
- *
- * @return the string representation
- */
- public String toString() {
- return Runtime.formatNumbers(toString(Options.NUMBER_FORMAT));
- }
-
- /**
- * Return a string representation of this vector by formatting the vector components with the given {@link NumberFormat}.
- *
- * @param formatter
- * the {@link NumberFormat} used to format the vector components with
- * @return the string representation
- */
- public String toString(NumberFormat formatter) {
- return "(" + Runtime.format(x, formatter) + " " + Runtime.format(y, formatter) + " " + Runtime.format(z, formatter) + " " + Runtime.format(w, formatter) + ")";
- }
-
- public void writeExternal(ObjectOutput out) throws IOException {
- out.writeFloat(x);
- out.writeFloat(y);
- out.writeFloat(z);
- out.writeFloat(w);
- }
-
- public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
- this.set(in.readFloat(), in.readFloat(), in.readFloat(), in.readFloat());
- }
-
- /**
- * Set the components of this vector to be the component-wise minimum of this and the other vector.
- *
- * @param v
- * the other vector
- * @return this
- */
- public Vector4f min(Vector4fc v) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- this.x = x < v.x() ? x : v.x();
- this.y = y < v.y() ? y : v.y();
- this.z = z < v.z() ? z : v.z();
- this.w = w < v.w() ? w : v.w();
- return this;
- }
-
- public Vector4f min(Vector4fc v, Vector4f dest) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- dest.x = x < v.x() ? x : v.x();
- dest.y = y < v.y() ? y : v.y();
- dest.z = z < v.z() ? z : v.z();
- dest.w = w < v.w() ? w : v.w();
- return dest;
- }
-
- /**
- * Set the components of this vector to be the component-wise maximum of this and the other vector.
- *
- * @param v
- * the other vector
- * @return this
- */
- public Vector4f max(Vector4fc v) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- this.x = x > v.x() ? x : v.x();
- this.y = y > v.y() ? y : v.y();
- this.z = z > v.z() ? z : v.z();
- this.w = w > v.w() ? w : v.w();
- return this;
- }
-
- public Vector4f max(Vector4fc v, Vector4f dest) {
- float x = this.x, y = this.y, z = this.z, w = this.w;
- dest.x = x > v.x() ? x : v.x();
- dest.y = y > v.y() ? y : v.y();
- dest.z = z > v.z() ? z : v.z();
- dest.w = w > v.w() ? w : v.w();
- return dest;
- }
-
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + Float.floatToIntBits(w);
- result = prime * result + Float.floatToIntBits(x);
- result = prime * result + Float.floatToIntBits(y);
- result = prime * result + Float.floatToIntBits(z);
- return result;
- }
-
- public boolean equals(Object obj) {
- if (this == obj)
- return true;
- if (obj == null)
- return false;
- if (getClass() != obj.getClass())
- return false;
- Vector4f other = (Vector4f) obj;
- if (Float.floatToIntBits(w) != Float.floatToIntBits(other.w))
- return false;
- if (Float.floatToIntBits(x) != Float.floatToIntBits(other.x))
- return false;
- if (Float.floatToIntBits(y) != Float.floatToIntBits(other.y))
- return false;
- if (Float.floatToIntBits(z) != Float.floatToIntBits(other.z))
- return false;
- return true;
- }
-
- public boolean equals(Vector4fc v, float delta) {
- if (this == v)
- return true;
- if (v == null)
- return false;
- if (!(v instanceof Vector4fc))
- return false;
- if (!Runtime.equals(x, v.x(), delta))
- return false;
- if (!Runtime.equals(y, v.y(), delta))
- return false;
- if (!Runtime.equals(z, v.z(), delta))
- return false;
- if (!Runtime.equals(w, v.w(), delta))
- return false;
- return true;
- }
-
- public boolean equals(float x, float y, float z, float w) {
- if (Float.floatToIntBits(this.x) != Float.floatToIntBits(x))
- return false;
- if (Float.floatToIntBits(this.y) != Float.floatToIntBits(y))
- return false;
- if (Float.floatToIntBits(this.z) != Float.floatToIntBits(z))
- return false;
- if (Float.floatToIntBits(this.w) != Float.floatToIntBits(w))
- return false;
- return true;
- }
-
- public Vector4f smoothStep(Vector4fc v, float t, Vector4f dest) {
- float t2 = t * t;
- float t3 = t2 * t;
- float x = this.x, y = this.y, z = this.z, w = this.w;
- dest.x = (x + x - v.x() - v.x()) * t3 + (3.0f * v.x() - 3.0f * x) * t2 + x * t + x;
- dest.y = (y + y - v.y() - v.y()) * t3 + (3.0f * v.y() - 3.0f * y) * t2 + y * t + y;
- dest.z = (z + z - v.z() - v.z()) * t3 + (3.0f * v.z() - 3.0f * z) * t2 + z * t + z;
- dest.w = (w + w - v.w() - v.w()) * t3 + (3.0f * v.w() - 3.0f * w) * t2 + w * t + w;
- return dest;
- }
-
- public Vector4f hermite(Vector4fc t0, Vector4fc v1, Vector4fc t1, float t, Vector4f dest) {
- float t2 = t * t;
- float t3 = t2 * t;
- float x = this.x, y = this.y, z = this.z, w = this.w;
- dest.x = (x + x - v1.x() - v1.x() + t1.x() + t0.x()) * t3 + (3.0f * v1.x() - 3.0f * x - t0.x() - t0.x() - t1.x()) * t2 + x * t + x;
- dest.y = (y + y - v1.y() - v1.y() + t1.y() + t0.y()) * t3 + (3.0f * v1.y() - 3.0f * y - t0.y() - t0.y() - t1.y()) * t2 + y * t + y;
- dest.z = (z + z - v1.z() - v1.z() + t1.z() + t0.z()) * t3 + (3.0f * v1.z() - 3.0f * z - t0.z() - t0.z() - t1.z()) * t2 + z * t + z;
- dest.w = (w + w - v1.w() - v1.w() + t1.w() + t0.w()) * t3 + (3.0f * v1.w() - 3.0f * w - t0.w() - t0.w() - t1.w()) * t2 + w * t + w;
- return dest;
- }
-
- /**
- * Linearly interpolate this
and other
using the given interpolation factor t
- * and store the result in this
.
- * t
is 0.0
then the result is this
. If the interpolation factor is 1.0
- * then the result is other
.
- *
- * @param other
- * the other vector
- * @param t
- * the interpolation factor between 0.0 and 1.0
- * @return this
- */
- public Vector4f lerp(Vector4fc other, float t) {
- this.x = Math.fma(other.x() - x, t, x);
- this.y = Math.fma(other.y() - y, t, y);
- this.z = Math.fma(other.z() - z, t, z);
- this.w = Math.fma(other.w() - w, t, w);
- return this;
- }
-
- public Vector4f lerp(Vector4fc other, float t, Vector4f dest) {
- dest.x = Math.fma(other.x() - x, t, x);
- dest.y = Math.fma(other.y() - y, t, y);
- dest.z = Math.fma(other.z() - z, t, z);
- dest.w = Math.fma(other.w() - w, t, w);
- return dest;
- }
-
- public float get(int component) throws IllegalArgumentException {
- switch (component) {
- case 0:
- return x;
- case 1:
- return y;
- case 2:
- return z;
- case 3:
- return w;
- default:
- throw new IllegalArgumentException();
- }
- }
-
- public Vector4f get(Vector4f dest) {
- dest.x = this.x();
- dest.y = this.y();
- dest.z = this.z();
- dest.w = this.w();
- return dest;
- }
-
- public int maxComponent() {
- float absX = Math.abs(x);
- float absY = Math.abs(y);
- float absZ = Math.abs(z);
- float absW = Math.abs(w);
- if (absX >= absY && absX >= absZ && absX >= absW) {
- return 0;
- } else if (absY >= absZ && absY >= absW) {
- return 1;
- } else if (absZ >= absW) {
- return 2;
- }
- return 3;
- }
-
- public int minComponent() {
- float absX = Math.abs(x);
- float absY = Math.abs(y);
- float absZ = Math.abs(z);
- float absW = Math.abs(w);
- if (absX < absY && absX < absZ && absX < absW) {
- return 0;
- } else if (absY < absZ && absY < absW) {
- return 1;
- } else if (absZ < absW) {
- return 2;
- }
- return 3;
- }
-
- /**
- * Set each component of this vector to the largest (closest to positive
- * infinity) {@code float} value that is less than or equal to that
- * component and is equal to a mathematical integer.
- *
- * @return this
- */
- public Vector4f floor() {
- this.x = Math.floor(x);
- this.y = Math.floor(y);
- this.z = Math.floor(z);
- this.w = Math.floor(w);
- return this;
- }
-
- public Vector4f floor(Vector4f dest) {
- dest.x = Math.floor(x);
- dest.y = Math.floor(y);
- dest.z = Math.floor(z);
- dest.w = Math.floor(w);
- return dest;
- }
-
- /**
- * Set each component of this vector to the smallest (closest to negative
- * infinity) {@code float} value that is greater than or equal to that
- * component and is equal to a mathematical integer.
- *
- * @return this
- */
- public Vector4f ceil() {
- this.x = Math.ceil(x);
- this.y = Math.ceil(y);
- this.z = Math.ceil(z);
- this.w = Math.ceil(w);
- return this;
- }
-
- public Vector4f ceil(Vector4f dest) {
- dest.x = Math.ceil(x);
- dest.y = Math.ceil(y);
- dest.z = Math.ceil(z);
- dest.w = Math.ceil(w);
- return dest;
- }
-
- /**
- * Set each component of this vector to the closest float that is equal to
- * a mathematical integer, with ties rounding to positive infinity.
- *
- * @return this
- */
- public Vector4f round() {
- this.x = Math.round(x);
- this.y = Math.round(y);
- this.z = Math.round(z);
- this.w = Math.round(w);
- return this;
- }
-
- public Vector4f round(Vector4f dest) {
- dest.x = Math.round(x);
- dest.y = Math.round(y);
- dest.z = Math.round(z);
- dest.w = Math.round(w);
- return dest;
- }
-
- public boolean isFinite() {
- return Math.isFinite(x) && Math.isFinite(y) && Math.isFinite(z) && Math.isFinite(w);
- }
-
- /**
- * Compute the absolute of each of this vector's components.
- *
- * @return this
- */
- public Vector4f absolute() {
- this.x = Math.abs(x);
- this.y = Math.abs(y);
- this.z = Math.abs(z);
- this.w = Math.abs(w);
- return this;
- }
-
- public Vector4f absolute(Vector4f dest) {
- dest.x = Math.abs(x);
- dest.y = Math.abs(y);
- dest.z = Math.abs(z);
- dest.w = Math.abs(w);
- return dest;
- }
-
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/util/joml/Vector4fc.java b/src/main/java/com/jozufozu/flywheel/util/joml/Vector4fc.java
deleted file mode 100644
index 6242c01a1..000000000
--- a/src/main/java/com/jozufozu/flywheel/util/joml/Vector4fc.java
+++ /dev/null
@@ -1,805 +0,0 @@
-/*
- * The MIT License
- *
- * Copyright (c) 2016-2021 JOML
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-package com.jozufozu.flywheel.util.joml;
-
-import java.nio.ByteBuffer;
-import java.nio.FloatBuffer;
-import java.util.*;
-
-/**
- * Interface to a read-only view of a 4-dimensional vector of single-precision floats.
- *
- * @author Kai Burjack
- */
-public interface Vector4fc {
-
- /**
- * @return the value of the x component
- */
- float x();
-
- /**
- * @return the value of the y component
- */
- float y();
-
- /**
- * @return the value of the z component
- */
- float z();
-
- /**
- * @return the value of the w component
- */
- float w();
-
- /**
- * Store this vector into the supplied {@link FloatBuffer} at the current
- * buffer {@link FloatBuffer#position() position}.
- * x, y, z, w
order
- * @return the passed in buffer
- * @see #get(int, FloatBuffer)
- */
- FloatBuffer get(FloatBuffer buffer);
-
- /**
- * Store this vector into the supplied {@link FloatBuffer} starting at the specified
- * absolute buffer position/index.
- * x, y, z, w
order
- * @return the passed in buffer
- */
- FloatBuffer get(int index, FloatBuffer buffer);
-
- /**
- * Store this vector into the supplied {@link ByteBuffer} at the current
- * buffer {@link ByteBuffer#position() position}.
- * x, y, z, w
order
- * @return the passed in buffer
- * @see #get(int, ByteBuffer)
- */
- ByteBuffer get(ByteBuffer buffer);
-
- /**
- * Store this vector into the supplied {@link ByteBuffer} starting at the specified
- * absolute buffer position/index.
- * x, y, z, w
order
- * @return the passed in buffer
- */
- ByteBuffer get(int index, ByteBuffer buffer);
-
- /**
- * Store this vector at the given off-heap memory address.
- * dest
.
- *
- * @param v
- * the vector to subtract from this
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f sub(Vector4fc v, Vector4f dest);
-
- /**
- * Subtract (x, y, z, w)
from this and store the result in dest
.
- *
- * @param x
- * the x component to subtract
- * @param y
- * the y component to subtract
- * @param z
- * the z component to subtract
- * @param w
- * the w component to subtract
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f sub(float x, float y, float z, float w, Vector4f dest);
-
- /**
- * Add the supplied vector to this one and store the result in dest
.
- *
- * @param v
- * the vector to add
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f add(Vector4fc v, Vector4f dest);
-
- /**
- * Increment the components of this vector by the given values and store the result in dest
.
- *
- * @param x
- * the x component to add
- * @param y
- * the y component to add
- * @param z
- * the z component to add
- * @param w
- * the w component to add
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f add(float x, float y, float z, float w, Vector4f dest);
-
- /**
- * Add the component-wise multiplication of a * b
to this vector
- * and store the result in dest
.
- *
- * @param a
- * the first multiplicand
- * @param b
- * the second multiplicand
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f fma(Vector4fc a, Vector4fc b, Vector4f dest);
-
- /**
- * Add the component-wise multiplication of a * b
to this vector
- * and store the result in dest
.
- *
- * @param a
- * the first multiplicand
- * @param b
- * the second multiplicand
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f fma(float a, Vector4fc b, Vector4f dest);
-
- /**
- * Add the component-wise multiplication of this * a
to b
- * and store the result in dest
.
- *
- * @param a
- * the multiplicand
- * @param b
- * the addend
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f mulAdd(Vector4fc a, Vector4fc b, Vector4f dest);
-
- /**
- * Add the component-wise multiplication of this * a
to b
- * and store the result in dest
.
- *
- * @param a
- * the multiplicand
- * @param b
- * the addend
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f mulAdd(float a, Vector4fc b, Vector4f dest);
-
- /**
- * Multiply this Vector4f component-wise by another Vector4f and store the result in dest
.
- *
- * @param v
- * the other vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f mul(Vector4fc v, Vector4f dest);
-
- /**
- * Divide this Vector4f component-wise by another Vector4f and store the result in dest
.
- *
- * @param v
- * the vector to divide by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f div(Vector4fc v, Vector4f dest);
-
- /**
- * Multiply the given matrix mat with this Vector4f and store the result in
- * dest
.
- *
- * @param mat
- * the matrix to multiply the vector with
- * @param dest
- * the destination vector to hold the result
- * @return dest
- */
- Vector4f mul(Matrix4fc mat, Vector4f dest);
-
- /**
- * Multiply the transpose of the given matrix mat
with this Vector4f and store the result in
- * dest
.
- *
- * @param mat
- * the matrix whose transpose to multiply the vector with
- * @param dest
- * the destination vector to hold the result
- * @return dest
- */
- Vector4f mulTranspose(Matrix4fc mat, Vector4f dest);
-
- /**
- * Multiply the given affine matrix mat with this Vector4f and store the result in
- * dest
.
- *
- * @param mat
- * the affine matrix to multiply the vector with
- * @param dest
- * the destination vector to hold the result
- * @return dest
- */
- Vector4f mulAffine(Matrix4fc mat, Vector4f dest);
-
- /**
- * Multiply the transpose of the given affine matrix mat
with this Vector4f and store the result in
- * dest
.
- *
- * @param mat
- * the affine matrix whose transpose to multiply the vector with
- * @param dest
- * the destination vector to hold the result
- * @return dest
- */
- Vector4f mulAffineTranspose(Matrix4fc mat, Vector4f dest);
-
- /**
- * Multiply the given matrix mat
with this Vector4f, perform perspective division
- * and store the result in dest
.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f mulProject(Matrix4fc mat, Vector4f dest);
-
- /**
- * Multiply the given matrix mat
with this Vector4f, perform perspective division
- * and store the (x, y, z)
result in dest
.
- *
- * @param mat
- * the matrix to multiply this vector by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector3f mulProject(Matrix4fc mat, Vector3f dest);
-
- /**
- * Multiply all components of this {@link Vector4f} by the given scalar
- * value and store the result in dest
.
- *
- * @param scalar
- * the scalar to multiply by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f mul(float scalar, Vector4f dest);
-
- /**
- * Multiply the components of this Vector4f by the given scalar values and store the result in dest
.
- *
- * @param x
- * the x component to multiply by
- * @param y
- * the y component to multiply by
- * @param z
- * the z component to multiply by
- * @param w
- * the w component to multiply by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f mul(float x, float y, float z, float w, Vector4f dest);
-
- /**
- * Divide all components of this {@link Vector4f} by the given scalar
- * value and store the result in dest
.
- *
- * @param scalar
- * the scalar to divide by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f div(float scalar, Vector4f dest);
-
- /**
- * Divide the components of this Vector4f by the given scalar values and store the result in dest
.
- *
- * @param x
- * the x component to divide by
- * @param y
- * the y component to divide by
- * @param z
- * the z component to divide by
- * @param w
- * the w component to divide by
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f div(float x, float y, float z, float w, Vector4f dest);
-
- /**
- * Rotate this vector by the given quaternion quat
and store the result in dest
.
- *
- * @see Quaternionf#transform(Vector4f)
- *
- * @param quat
- * the quaternion to rotate this vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f rotate(Quaternionfc quat, Vector4f dest);
-
- /**
- * Rotate this vector the specified radians around the given rotation axis and store the result
- * into dest
.
- *
- * @param angle
- * the angle in radians
- * @param aX
- * the x component of the rotation axis
- * @param aY
- * the y component of the rotation axis
- * @param aZ
- * the z component of the rotation axis
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f rotateAxis(float angle, float aX, float aY, float aZ, Vector4f dest);
-
- /**
- * Rotate this vector the specified radians around the X axis and store the result
- * into dest
.
- *
- * @param angle
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f rotateX(float angle, Vector4f dest);
-
- /**
- * Rotate this vector the specified radians around the Y axis and store the result
- * into dest
.
- *
- * @param angle
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f rotateY(float angle, Vector4f dest);
-
- /**
- * Rotate this vector the specified radians around the Z axis and store the result
- * into dest
.
- *
- * @param angle
- * the angle in radians
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f rotateZ(float angle, Vector4f dest);
-
- /**
- * Return the length squared of this vector.
- *
- * @return the length squared
- */
- float lengthSquared();
-
- /**
- * Return the length of this vector.
- *
- * @return the length
- */
- float length();
-
- /**
- * Normalizes this vector and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f normalize(Vector4f dest);
-
- /**
- * Scale this vector to have the given length and store the result in dest
.
- *
- * @param length
- * the desired length
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f normalize(float length, Vector4f dest);
-
- /**
- * Normalize this vector by computing only the norm of (x, y, z)
and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f normalize3(Vector4f dest);
-
- /**
- * Return the distance between this Vector and v
.
- *
- * @param v
- * the other vector
- * @return the distance
- */
- float distance(Vector4fc v);
-
- /**
- * Return the distance between this
vector and (x, y, z, w)
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @param w
- * the w component of the other vector
- * @return the euclidean distance
- */
- float distance(float x, float y, float z, float w);
-
- /**
- * Return the square of the distance between this vector and v
.
- *
- * @param v
- * the other vector
- * @return the squared of the distance
- */
- float distanceSquared(Vector4fc v);
-
- /**
- * Return the square of the distance between this
vector and
- * (x, y, z, w)
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @param w
- * the w component of the other vector
- * @return the square of the distance
- */
- float distanceSquared(float x, float y, float z, float w);
-
- /**
- * Compute the dot product (inner product) of this vector and v
- * .
- *
- * @param v
- * the other vector
- * @return the dot product
- */
- float dot(Vector4fc v);
-
- /**
- * Compute the dot product (inner product) of this vector and (x, y, z, w)
.
- *
- * @param x
- * the x component of the other vector
- * @param y
- * the y component of the other vector
- * @param z
- * the z component of the other vector
- * @param w
- * the w component of the other vector
- * @return the dot product
- */
- float dot(float x, float y, float z, float w);
-
- /**
- * Return the cosine of the angle between this vector and the supplied vector. Use this instead of Math.cos(angle(v))
.
- *
- * @see #angle(Vector4fc)
- *
- * @param v
- * the other vector
- * @return the cosine of the angle
- */
- float angleCos(Vector4fc v);
-
- /**
- * Return the angle between this vector and the supplied vector.
- *
- * @see #angleCos(Vector4fc)
- *
- * @param v
- * the other vector
- * @return the angle, in radians
- */
- float angle(Vector4fc v);
-
- /**
- * Negate this vector and store the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f negate(Vector4f dest);
-
- /**
- * Set the components of dest
to be the component-wise minimum of this and the other vector.
- *
- * @param v
- * the other vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f min(Vector4fc v, Vector4f dest);
-
- /**
- * Set the components of dest
to be the component-wise maximum of this and the other vector.
- *
- * @param v
- * the other vector
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f max(Vector4fc v, Vector4f dest);
-
- /**
- * Linearly interpolate this
and other
using the given interpolation factor t
- * and store the result in dest
.
- * t
is 0.0
then the result is this
. If the interpolation factor is 1.0
- * then the result is other
.
- *
- * @param other
- * the other vector
- * @param t
- * the interpolation factor between 0.0 and 1.0
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f lerp(Vector4fc other, float t, Vector4f dest);
-
- /**
- * Compute a smooth-step (i.e. hermite with zero tangents) interpolation
- * between this
vector and the given vector v
and
- * store the result in dest
.
- *
- * @param v
- * the other vector
- * @param t
- * the interpolation factor, within [0..1]
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f smoothStep(Vector4fc v, float t, Vector4f dest);
-
- /**
- * Compute a hermite interpolation between this
vector and its
- * associated tangent t0
and the given vector v
- * with its tangent t1
and store the result in
- * dest
.
- *
- * @param t0
- * the tangent of this
vector
- * @param v1
- * the other vector
- * @param t1
- * the tangent of the other vector
- * @param t
- * the interpolation factor, within [0..1]
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f hermite(Vector4fc t0, Vector4fc v1, Vector4fc t1, float t, Vector4f dest);
-
- /**
- * Get the value of the specified component of this vector.
- *
- * @param component
- * the component, within [0..3]
- * @return the value
- * @throws IllegalArgumentException if component
is not within [0..3]
- */
- float get(int component) throws IllegalArgumentException;
-
- /**
- * Set the components of the given vector dest
to those of this
vector.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f get(Vector4f dest);
-
- /**
- * Determine the component with the biggest absolute value.
- *
- * @return the component index, within [0..3]
- */
- int maxComponent();
-
- /**
- * Determine the component with the smallest (towards zero) absolute value.
- *
- * @return the component index, within [0..3]
- */
- int minComponent();
-
- /**
- * Compute for each component of this vector the largest (closest to positive
- * infinity) {@code float} value that is less than or equal to that
- * component and is equal to a mathematical integer and store the result in
- * dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f floor(Vector4f dest);
-
- /**
- * Compute for each component of this vector the smallest (closest to negative
- * infinity) {@code float} value that is greater than or equal to that
- * component and is equal to a mathematical integer and store the result in
- * dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f ceil(Vector4f dest);
-
- /**
- * Compute for each component of this vector the closest float that is equal to
- * a mathematical integer, with ties rounding to positive infinity and store
- * the result in dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f round(Vector4f dest);
-
- /**
- * Determine whether all components are finite floating-point values, that
- * is, they are not {@link Float#isNaN() NaN} and not
- * {@link Float#isInfinite() infinity}.
- *
- * @return {@code true} if all components are finite floating-point values;
- * {@code false} otherwise
- */
- boolean isFinite();
-
- /**
- * Compute the absolute of each of this vector's components
- * and store the result into dest
.
- *
- * @param dest
- * will hold the result
- * @return dest
- */
- Vector4f absolute(Vector4f dest);
-
- /**
- * Compare the vector components of this
vector with the given vector using the given delta
- * and return whether all of them are equal within a maximum difference of delta
.
- * true
whether all of the vector components are equal; false
otherwise
- */
- boolean equals(Vector4fc v, float delta);
-
- /**
- * Compare the vector components of this
vector with the given (x, y, z, w)
- * and return whether all of them are equal.
- *
- * @param x
- * the x component to compare to
- * @param y
- * the y component to compare to
- * @param z
- * the z component to compare to
- * @param w
- * the w component to compare to
- * @return true
if all the vector components are equal
- */
- boolean equals(float x, float y, float z, float w);
-
-}
diff --git a/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java b/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java
index abd583d14..d90edc46d 100644
--- a/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java
+++ b/src/main/java/com/jozufozu/flywheel/vanilla/effect/ExampleEffect.java
@@ -5,6 +5,9 @@ import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import org.joml.FrustumIntersection;
+import org.joml.Vector3f;
+
import com.jozufozu.flywheel.api.RenderStage;
import com.jozufozu.flywheel.api.instance.DynamicInstance;
import com.jozufozu.flywheel.api.instance.TickableInstance;
@@ -19,8 +22,6 @@ import com.jozufozu.flywheel.event.ReloadRenderersEvent;
import com.jozufozu.flywheel.util.AnimationTickHolder;
import com.jozufozu.flywheel.util.box.GridAlignedBB;
import com.jozufozu.flywheel.util.box.ImmutableBox;
-import com.jozufozu.flywheel.util.joml.FrustumIntersection;
-import com.jozufozu.flywheel.util.joml.Vector3f;
import net.minecraft.client.Minecraft;
import net.minecraft.core.BlockPos;