From 17bb15de753a77c1030daae56fc2a78bae373efc Mon Sep 17 00:00:00 2001 From: MJ Date: Mon, 24 Jul 2023 00:24:00 +0200 Subject: [PATCH 1/6] KTX version changed to 1.12.0-SNAPSHOT. #463 --- CHANGELOG.md | 2 ++ version.txt | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 76b0b802..cf8fedd2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ _See also: [the official libGDX changelog](https://github.com/libgdx/libgdx/blob/master/CHANGES)._ +#### 1.12.0-SNAPSHOT + #### 1.12.0-rc1 - **[UPDATE]** Updated to libGDX 1.12.0. diff --git a/version.txt b/version.txt index 1f488021..79cd2d3b 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.12.0-rc1 +1.12.0-SNAPSHOT From f45df779a180ed2dd153c6178b9210b8ecf44f94 Mon Sep 17 00:00:00 2001 From: MJ Date: Sat, 4 Nov 2023 07:35:24 +0100 Subject: [PATCH 2/6] libGDX updated to 1.12.1. #470 --- CHANGELOG.md | 4 +++- README.md | 6 +++--- buildSrc/src/main/kotlin/ktx/Versions.kt | 2 +- version.txt | 2 +- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cf8fedd2..a1cfa118 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ _See also: [the official libGDX changelog](https://github.com/libgdx/libgdx/blob/master/CHANGES)._ -#### 1.12.0-SNAPSHOT +#### 1.12.1-SNAPSHOT + +- **[UPDATE]** Updated to libGDX 1.12.1. #### 1.12.0-rc1 diff --git a/README.md b/README.md index 9a2bc319..d015d434 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![GitHub Build](https://github.com/libktx/ktx/workflows/build/badge.svg)](https://github.com/libktx/ktx/actions?query=workflow%3Abuild) [![Kotlin](https://img.shields.io/badge/kotlin-1.9.0-orange.svg)](http://kotlinlang.org/) -[![libGDX](https://img.shields.io/badge/libgdx-1.12.0-red.svg)](https://libgdx.com/) +[![libGDX](https://img.shields.io/badge/libgdx-1.12.1-red.svg)](https://libgdx.com/) [![Maven Central](https://img.shields.io/maven-central/v/io.github.libktx/ktx-async.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22io.github.libktx%22) [![KTX](.github/ktx-logo.png "KTX")](http://libktx.github.io) @@ -305,7 +305,7 @@ repositories { ext { // Update this version to match the latest libGDX release: - ktxVersion = '1.12.0-SNAPSHOT' + ktxVersion = '1.12.1-SNAPSHOT' } ``` @@ -320,7 +320,7 @@ repositories { } // Update this version to match the latest libGDX release: -val ktxVersion = "1.12.0-SNAPSHOT" +val ktxVersion = "1.12.1-SNAPSHOT" ``` diff --git a/buildSrc/src/main/kotlin/ktx/Versions.kt b/buildSrc/src/main/kotlin/ktx/Versions.kt index 3267b97d..7b017352 100644 --- a/buildSrc/src/main/kotlin/ktx/Versions.kt +++ b/buildSrc/src/main/kotlin/ktx/Versions.kt @@ -1,6 +1,6 @@ package ktx -const val gdxVersion = "1.12.0" +const val gdxVersion = "1.12.1" const val kotlinCoroutinesVersion = "1.7.2" const val artemisOdbVersion = "2.3.0" diff --git a/version.txt b/version.txt index 79cd2d3b..8f34f8f2 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.12.0-SNAPSHOT +1.12.1-SNAPSHOT From 6f02c8a1be55c797a5c2ab3f034fa4a8f5b7d894 Mon Sep 17 00:00:00 2001 From: MJ Date: Sat, 4 Nov 2023 07:51:16 +0100 Subject: [PATCH 3/6] Kotlin updated to 1.9.20. #470 --- CHANGELOG.md | 3 +++ README.md | 2 +- async/README.md | 2 +- buildSrc/src/main/kotlin/ktx/Versions.kt | 2 +- gradle.properties | 4 ++-- 5 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1cfa118..b6aad4ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,9 @@ _See also: [the official libGDX changelog](https://github.com/libgdx/libgdx/blob #### 1.12.1-SNAPSHOT - **[UPDATE]** Updated to libGDX 1.12.1. +- **[UPDATE]** Updated to Kotlin 1.9.20. +- **[UPDATE]** Updated to Kotlin Coroutines 1.7.3. +- **[UPDATE]** Updated to Dokka 1.9.10. #### 1.12.0-rc1 diff --git a/README.md b/README.md index d015d434..854c1d07 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ [![GitHub Build](https://github.com/libktx/ktx/workflows/build/badge.svg)](https://github.com/libktx/ktx/actions?query=workflow%3Abuild) -[![Kotlin](https://img.shields.io/badge/kotlin-1.9.0-orange.svg)](http://kotlinlang.org/) +[![Kotlin](https://img.shields.io/badge/kotlin-1.9.20-orange.svg)](http://kotlinlang.org/) [![libGDX](https://img.shields.io/badge/libgdx-1.12.1-red.svg)](https://libgdx.com/) [![Maven Central](https://img.shields.io/maven-central/v/io.github.libktx/ktx-async.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22io.github.libktx%22) diff --git a/async/README.md b/async/README.md index e348fc9c..608f7b17 100644 --- a/async/README.md +++ b/async/README.md @@ -1,4 +1,4 @@ -[![Kotlin Coroutines](https://img.shields.io/badge/kotlin--coroutines-1.7.2-orange.svg)](http://kotlinlang.org/) +[![Kotlin Coroutines](https://img.shields.io/badge/kotlin--coroutines-1.7.3-orange.svg)](http://kotlinlang.org/) [![Maven Central](https://img.shields.io/maven-central/v/io.github.libktx/ktx-async.svg)](https://search.maven.org/artifact/io.github.libktx/ktx-async) # KTX: Coroutines support and parallelization utilities diff --git a/buildSrc/src/main/kotlin/ktx/Versions.kt b/buildSrc/src/main/kotlin/ktx/Versions.kt index 7b017352..5a6ea559 100644 --- a/buildSrc/src/main/kotlin/ktx/Versions.kt +++ b/buildSrc/src/main/kotlin/ktx/Versions.kt @@ -1,7 +1,7 @@ package ktx const val gdxVersion = "1.12.1" -const val kotlinCoroutinesVersion = "1.7.2" +const val kotlinCoroutinesVersion = "1.7.3" const val artemisOdbVersion = "2.3.0" const val ashleyVersion = "1.7.4" diff --git a/gradle.properties b/gradle.properties index d3aa9fed..635031f7 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,8 +1,8 @@ libGroup=io.github.libktx -kotlinVersion=1.9.0 +kotlinVersion=1.9.20 -dokkaVersion=1.8.20 +dokkaVersion=1.9.10 junitPlatformVersion=1.2.0 configurationsPluginVersion=3.0.3 From 2adc950404c4347ce2c69cc86cbe6a20a741e030 Mon Sep 17 00:00:00 2001 From: MJ Date: Sat, 4 Nov 2023 10:29:42 +0100 Subject: [PATCH 4/6] VisUI updated to 1.5.3. #472 --- CHANGELOG.md | 1 + buildSrc/src/main/kotlin/ktx/Versions.kt | 2 +- vis/README.md | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b6aad4ca..abe754e5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ _See also: [the official libGDX changelog](https://github.com/libgdx/libgdx/blob - **[UPDATE]** Updated to libGDX 1.12.1. - **[UPDATE]** Updated to Kotlin 1.9.20. - **[UPDATE]** Updated to Kotlin Coroutines 1.7.3. +- **[UPDATE]** Updated to VisUI 1.5.3. - **[UPDATE]** Updated to Dokka 1.9.10. #### 1.12.0-rc1 diff --git a/buildSrc/src/main/kotlin/ktx/Versions.kt b/buildSrc/src/main/kotlin/ktx/Versions.kt index 5a6ea559..401152de 100644 --- a/buildSrc/src/main/kotlin/ktx/Versions.kt +++ b/buildSrc/src/main/kotlin/ktx/Versions.kt @@ -6,7 +6,7 @@ const val kotlinCoroutinesVersion = "1.7.3" const val artemisOdbVersion = "2.3.0" const val ashleyVersion = "1.7.4" const val gdxAiVersion = "1.8.2" -const val visUiVersion = "1.5.2" +const val visUiVersion = "1.5.3" const val spekVersion = "1.1.5" const val kotlinTestVersion = "2.0.7" diff --git a/vis/README.md b/vis/README.md index f9756079..59c38078 100644 --- a/vis/README.md +++ b/vis/README.md @@ -1,4 +1,4 @@ -[![VisUI](https://img.shields.io/badge/vis--ui-1.5.2-blue.svg)](https://github.com/kotcrab/vis-ui) +[![VisUI](https://img.shields.io/badge/vis--ui-1.5.3-blue.svg)](https://github.com/kotcrab/vis-ui) [![Maven Central](https://img.shields.io/maven-central/v/io.github.libktx/ktx-vis.svg)](https://search.maven.org/artifact/io.github.libktx/ktx-vis) # KTX: VisUI type-safe builders From 7a4444cfc7929b4c92510c02028c156b6b41e5d5 Mon Sep 17 00:00:00 2001 From: MJ Date: Sat, 4 Nov 2023 11:21:17 +0100 Subject: [PATCH 5/6] Vector4 utilities. #473 --- CHANGELOG.md | 7 + math/README.md | 27 +- math/src/main/kotlin/ktx/math/vector4.kt | 333 +++++++++++ math/src/test/kotlin/ktx/math/Vector4Test.kt | 558 +++++++++++++++++++ 4 files changed, 920 insertions(+), 5 deletions(-) create mode 100644 math/src/main/kotlin/ktx/math/vector4.kt create mode 100644 math/src/test/kotlin/ktx/math/Vector4Test.kt diff --git a/CHANGELOG.md b/CHANGELOG.md index abe754e5..954c9e39 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ _See also: [the official libGDX changelog](https://github.com/libgdx/libgdx/blob - **[UPDATE]** Updated to Kotlin Coroutines 1.7.3. - **[UPDATE]** Updated to VisUI 1.5.3. - **[UPDATE]** Updated to Dokka 1.9.10. +- **[FEATURE]** (`ktx-math`) New extension and factory function were introduced to `Vector4`, offering similar utilities to other vectors. + - `vec4` factory methods allow creating new `Vector4` instances with default and named parameters. + - `+=`, `-=`, `*=`, `/=` mutating operators are now supported. + - `+`, `-` (including unary `-`), `++`, `--`, `*`, `/` operators are now supported, returning new instances of vectors as a result. + - Vectors are now comparable by length, adding support for `<`, `>`, `<=`, `>=` operators. + - `Vector4` instances can now be deconstructed into 4 four values (X, Y, Z, W) using extension component methods. + - `dot` infix function allows calculating the dot product of 2 vectors. #### 1.12.0-rc1 diff --git a/math/README.md b/math/README.md index 43af8e80..7980c06b 100644 --- a/math/README.md +++ b/math/README.md @@ -19,9 +19,9 @@ numbers. #### `Vector2` - `vec2` is a global factory function that can create `Vector2` instances with named parameters for extra readability. -- `+=`, `-=`, `*=` and `/=` can be used to add, subtract, multiply or divide current values according to the second +- `+=`, `-=`, `*=` and `/=` can be used to add, subtract, multiply (`scl`) or divide current values according to the second vector or number. Use these operators to _mutate_ existing vectors. -- `+`, `-`, `*` and `/` can be used to add, subtract, multiply or divide vectors according to the second vector or +- `+`, `-`, `*` and `/` can be used to add, subtract, multiply (`scl`) or divide vectors according to the second vector or number, resulting in a new vector. Use these operators to _create_ new instances of vectors. - Unary `-` operator (a single minus before the vector) allows to negate both vector values, creating a new vector. - `++` and `--` operators can be used to increment and decrement both x and y values of the vector, resulting in a new @@ -123,20 +123,37 @@ var v2 = Vec2(1f, 2f).withLength(3f) - `vec3` is a global factory function that can create `Vector3` instances with named parameters for extra readability. It is also overloaded with a second variant that allows to convert `Vector2` instances to `Vector3`. -- `+=`, `-=`, `*=` and `/=` can be used to add, subtract, multiply or divide current values according to the second +- `+=`, `-=`, `*=` and `/=` can be used to add, subtract, multiply (`scl`) or divide current values according to the second vector or number. Use these operators to _mutate_ existing vectors. -- `+`, `-`, `*` and `/` can be used to add, subtract, multiply or divide vectors according to the second vector or +- `+`, `-`, `*` and `/` can be used to add, subtract, multiply (`scl`) or divide vectors according to the second vector or number, resulting in a new vector. Use these operators to _create_ new instances of vectors. - Unary `-` operator (a single minus before the vector) allows to negate both vector values, creating a new vector. - `++` and `--` operators can be used to increment and decrement x, y and z values of the vector, resulting in a new vector. To avoid creating new vectors, prefer `+= 1` and `-= 1` instead. -- `Vector3` instances can be destructed to tree float variables in one step with `val (x, y, z) = vector3` syntax thanks +- `Vector3` instances can be destructed to three float variables in one step with `val (x, y, z) = vector3` syntax thanks to `component1()`, `component2()` and `component3` operator methods. - `Vector3` instances are now comparable - `<`, `>`, `<=`, `>=` operators can be used to determine which vector has greater (or equal) overall length, similarly to how `Vector2` now works. - `dot` infix function allows to calculate the dot product of 2 vectors. - `x` infix function allows to calculate the cross product of 2 vectors. +#### `Vector4` + +- `vec4` is a global factory function that can create `Vector4` instances with named parameters for extra readability. + It is also overloaded with a second variant that allows to convert `Vector2` and `Vector3` instances to `Vector4`. +- `+=`, `-=`, `*=` and `/=` can be used to add, subtract, multiply (`scl`) or divide current values according to the second + vector or number. Use these operators to _mutate_ existing vectors. +- `+`, `-`, `*` and `/` can be used to add, subtract, multiply (`scl`) or divide vectors according to the second vector or + number, resulting in a new vector. Use these operators to _create_ new instances of vectors. +- Unary `-` operator (a single minus before the vector) allows to negate both vector values, creating a new vector. +- `++` and `--` operators can be used to increment and decrement x, y, z, and w values of the vector, resulting in a new + vector. To avoid creating new vectors, prefer `+= 1` and `-= 1` instead. +- `Vector4` instances can be destructed to four float variables in one step with `val (x, y, z, w) = vector4` syntax thanks + to `component1()`, `component2()` and `component3` operator methods. +- `Vector3` instances are now comparable - `<`, `>`, `<=`, `>=` operators can be used to determine which vector has greater + (or equal) overall length. +- `dot` infix function allows to calculate the dot product of 2 vectors. + #### `Matrix3` - `mat3` is a human-readable global factory function that allows to easily create `Matrix3` instances. diff --git a/math/src/main/kotlin/ktx/math/vector4.kt b/math/src/main/kotlin/ktx/math/vector4.kt new file mode 100644 index 00000000..be6f9abe --- /dev/null +++ b/math/src/main/kotlin/ktx/math/vector4.kt @@ -0,0 +1,333 @@ +package ktx.math + +import com.badlogic.gdx.math.Vector2 +import com.badlogic.gdx.math.Vector3 +import com.badlogic.gdx.math.Vector4 + +/** + * Constructs a new [Vector4] instance. An equivalent of [Vector4] constructor that supports Kotlin syntax features: + * named parameters with default values. + * @param x the X component. Defaults to 0f. + * @param y the Y component. Defaults to 0f. + * @param z the Z component. Defaults to 0f. + * @param w the W component. Defaults to 0f. + * @return a new [Vector4] instance storing the passed values. + */ +fun vec4(x: Float = 0f, y: Float = 0f, z: Float = 0f, w: Float = 0f): Vector4 = Vector4(x, y, z, w) + +/** + * Constructs a new [Vector4] instance. An equivalent of [Vector4] constructor that supports Kotlin syntax features: + * named parameters with default values. + * @param xy stores the X and Y components. Will be copied. + * @param z the Z component. Defaults to 0f. + * @param w the W component. Defaults to 0f. + * @return a new [Vector4] instance storing the passed values. + */ +fun vec4(xy: Vector2, z: Float = 0f, w: Float = 0f): Vector4 = Vector4(xy, z, w) + +/** + * Constructs a new [Vector4] instance copying values from the passed [Vector2] instances. + * @param xy stores the X and Y components. Will be copied. + * @param zw its X component will be used as Z, while the Y component will be copied as W. + * @return a new [Vector4] instance storing the passed values. + */ +fun vec4(xy: Vector2, zw: Vector2): Vector4 = Vector4(xy, zw.x, zw.y) + +/** + * Constructs a new [Vector4] instance copying values from the passed [Vector3] instance. An equivalent of [Vector4] + * constructor that supports Kotlin syntax features: named parameters with default values. + * @param xyz stores the X, Y, and Z components. Will be copied. + * @param w the W component. Defaults to 0f. + * @return a new [Vector4] instance storing the passed values. + */ +fun vec4(xyz: Vector3, w: Float = 0f): Vector4 = Vector4(xyz, w) + +/** + * Inverts stored X, Y, Z, and W values. + * @return a new [Vector4] with negated values. + */ +operator fun Vector4.unaryMinus(): Vector4 = Vector4(-x, -y, -z, -w) + +/** + * @param vector4 values from this vector will be added to this vector. + */ +operator fun Vector4.plusAssign(vector4: Vector4) { + add(vector4) +} + +/** + * Modifies X and Y components of this vector. + * @param vector2 values from this vector will be added to this vector. + */ +operator fun Vector4.plusAssign(vector2: Vector2) { + x += vector2.x + y += vector2.y +} + +/** + * Modifies X, Y, and Z components of this vector. + * @param vector3 values from this vector will be added to this vector. + */ +operator fun Vector4.plusAssign(vector3: Vector3) { + x += vector3.x + y += vector3.y + z += vector3.z +} + +/** + * @param addend this value will be added to X, Y, Z and W components of this vector. + */ +operator fun Vector4.plusAssign(addend: Float) { + add(addend) +} + +/** + * @param addend this value will be added to X, Y, Z and W components of this vector. + */ +operator fun Vector4.plusAssign(addend: Int) { + add(addend.toFloat()) +} + +/** + * @param vector4 values from this vector will be subtracted from this vector. + */ +operator fun Vector4.minusAssign(vector4: Vector4) { + sub(vector4) +} + +/** + * Modifies X and Y components of this vector. + * @param vector2 values from this vector will be subtracted from this vector. + */ +operator fun Vector4.minusAssign(vector2: Vector2) { + x -= vector2.x + y -= vector2.y +} + +/** + * Modifies X, Y, and Z components of this vector. + * @param vector3 values from this vector will be subtracted from this vector. + */ +operator fun Vector4.minusAssign(vector3: Vector3) { + x -= vector3.x + y -= vector3.y + z -= vector3.z +} + +/** + * @param subtrahend this value will be subtracted from X, Y, Z and W components of this vector. + */ +operator fun Vector4.minusAssign(subtrahend: Float) { + sub(subtrahend) +} + +/** + * @param subtrahend this value will be subtracted from X, Y, Z and W components of this vector. + */ +operator fun Vector4.minusAssign(subtrahend: Int) { + sub(subtrahend.toFloat()) +} + +/** + * @param vector4 values from this vector will multiply this vector using [Vector4.scl]. + */ +operator fun Vector4.timesAssign(vector4: Vector4) { + scl(vector4) +} + +/** + * @param scalar will be used to multiply all vector values using [Vector4.scl]. + */ +operator fun Vector4.timesAssign(scalar: Float) { + scl(scalar) +} + +/** + * @param scalar will be used to multiply all vector values using [Vector4.scl]. + */ +operator fun Vector4.timesAssign(scalar: Int) { + scl(scalar.toFloat()) +} + +/** + * @param vector4 these values will be used to individually divide this vector. + */ +operator fun Vector4.divAssign(vector4: Vector4) { + x /= vector4.x + y /= vector4.y + z /= vector4.z + w /= vector4.w +} + +/** + * @param scalar will be used to divide all vector values. + */ +operator fun Vector4.divAssign(scalar: Float) { + x /= scalar + y /= scalar + z /= scalar + w /= scalar +} + +/** + * @param scalar will be used to divide all vector values. + */ +operator fun Vector4.divAssign(scalar: Int) { + x /= scalar + y /= scalar + z /= scalar + w /= scalar +} + +/** + * @param vector4 values from this vector will be added to this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.plus(vector4: Vector4): Vector4 = + Vector4(x + vector4.x, y + vector4.y, z + vector4.z, w + vector4.w) + +/** + * @param vector2 values from this vector will be added to this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.plus(vector2: Vector2): Vector4 = Vector4(x + vector2.x, y + vector2.y, z, w) + +/** + * @param vector3 values from this vector will be added to this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.plus(vector3: Vector3): Vector4 = Vector4(x + vector3.x, y + vector3.y, z + vector3.z, w) + +/** + * @param addend will be added to X, Y, Z and W components of this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.plus(addend: Float): Vector4 = Vector4(x + addend, y + addend, z + addend, w + addend) + +/** + * @param addend will be added to X, Y, Z and W components of this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.plus(addend: Int): Vector4 = plus(addend.toFloat()) + +/** + * @param vector4 values from this vector will be subtracted from this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.minus(vector4: Vector4): Vector4 = + Vector4(x - vector4.x, y - vector4.y, z - vector4.z, w - vector4.w) + +/** + * @param vector2 values from this vector will be subtracted from this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.minus(vector2: Vector2): Vector4 = Vector4(x - vector2.x, y - vector2.y, z, w) + +/** + * @param vector3 values from this vector will be subtracted from this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.minus(vector3: Vector3): Vector4 = Vector4(x - vector3.x, y - vector3.y, z - vector3.z, w) + +/** + * @param subtrahend will be subtracted from to X, Y, Z and W componentsof this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.minus(subtrahend: Float): Vector4 = + Vector4(x - subtrahend, y - subtrahend, z - subtrahend, w - subtrahend) + +/** + * @param subtrahend will be subtracted from to X, Y, Z and W components of this vector. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.minus(subtrahend: Int): Vector4 = minus(subtrahend.toFloat()) + +/** + * @param vector4 values from this vector will multiply this vector element-wise similarly to [Vector4.scl]. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.times(vector4: Vector4): Vector4 = + Vector4(x * vector4.x, y * vector4.y, z * vector4.z, w * vector4.w) + +/** + * @param scalar will be used to multiply all vector values. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.times(scalar: Float): Vector4 = Vector4(x * scalar, y * scalar, z * scalar, w * scalar) + +/** + * @param scalar will be used to multiply all vector values. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.times(scalar: Int): Vector4 = Vector4(x * scalar, y * scalar, z * scalar, w * scalar) + +/** + * @param vector4 values from this vector will divide this vector element-wise. + * @return a new [vector4] instance with the operation result. + */ +operator fun Vector4.div(vector4: Vector4): Vector4 = + Vector4(x / vector4.x, y / vector4.y, z / vector4.z, w / vector4.w) + +/** + * @param scalar will be used to divide all vector values. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.div(scalar: Float): Vector4 = Vector4(x / scalar, y / scalar, z / scalar, w / scalar) + +/** + * @param scalar will be used to divide all vector values. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.div(scalar: Int): Vector4 = Vector4(x / scalar, y / scalar, z / scalar, w / scalar) + +/** + * Increments all vector values - adds 1 to X, Y, Z and W components. + * To avoid creating a new vector instance, use [Vector4.plusAssign] instead. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.inc(): Vector4 = Vector4(x + 1f, y + 1f, z + 1f, w + 1f) + +/** + * Decrements all vector values - subtracts 1 from X, Y, Z and W components. + * To avoid creating a new vector instance, use [Vector4.minusAssign] instead. + * @return a new [Vector4] instance with the operation result. + */ +operator fun Vector4.dec(): Vector4 = Vector4(x - 1f, y - 1f, z - 1f, w - 1f) + +/** + * Operator function that allows to deconstruct this vector. + * @return X component. + */ +operator fun Vector4.component1(): Float = x + +/** + * Operator function that allows to deconstruct this vector. + * @return Y component. + */ +operator fun Vector4.component2(): Float = y + +/** + * Operator function that allows to deconstruct this vector. + * @return Z component. + */ +operator fun Vector4.component3(): Float = z + +/** + * Operator function that allows to deconstruct this vector. + * @return W component. + */ +operator fun Vector4.component4(): Float = w + +/** + * Allows to compare which [Vector4] has greater overall length. + * @param vector4 will be compared to this vector. + * @return 1 if this vector has greater length. 0 if vectors are equal. -1 if the other vector is greater. + */ +operator fun Vector4.compareTo(vector4: Vector4): Int = len2().compareTo(vector4.len2()) + +/** + * Custom operator to apply dot multiplication. + * @param vector4 will be used to calculate the dot product of this vector. + * @return the dot product. + */ +infix fun Vector4.dot(vector4: Vector4): Float = dot(vector4) diff --git a/math/src/test/kotlin/ktx/math/Vector4Test.kt b/math/src/test/kotlin/ktx/math/Vector4Test.kt new file mode 100644 index 00000000..620c4b1f --- /dev/null +++ b/math/src/test/kotlin/ktx/math/Vector4Test.kt @@ -0,0 +1,558 @@ +package ktx.math + +import com.badlogic.gdx.math.Vector2 +import com.badlogic.gdx.math.Vector3 +import com.badlogic.gdx.math.Vector4 +import org.junit.Assert.assertEquals +import org.junit.Assert.assertFalse +import org.junit.Assert.assertTrue +import org.junit.Test + +/** + * Tests [Vector4]-related utilities. + */ +class Vector4Test { + private val floatTolerance = 0.00001f + + @Test + fun `should create vector with default values`() { + val zero = vec4() + + assertEquals(0f, zero.x, floatTolerance) + assertEquals(0f, zero.y, floatTolerance) + assertEquals(0f, zero.z, floatTolerance) + assertEquals(0f, zero.w, floatTolerance) + } + + @Test + fun `should create vector`() { + val vector = vec4(x = 10f, y = -10f, z = 5f, w = -5f) + + assertEquals(10f, vector.x, floatTolerance) + assertEquals(-10f, vector.y, floatTolerance) + assertEquals(5f, vector.z, floatTolerance) + assertEquals(-5f, vector.w, floatTolerance) + } + + @Test + fun `should create Vector4 with Vector2 instance`() { + val vector = vec4(Vector2(10f, 5f)) + + assertEquals(10f, vector.x, floatTolerance) + assertEquals(5f, vector.y, floatTolerance) + assertEquals(0f, vector.z, floatTolerance) + assertEquals(0f, vector.w, floatTolerance) + } + + @Test + fun `should create Vector4 with Vector2 instance and ZW components`() { + val vector = vec4(Vector2(10f, 5f), z = -15f, w = -5f) + + assertEquals(10f, vector.x, floatTolerance) + assertEquals(5f, vector.y, floatTolerance) + assertEquals(-15f, vector.z, floatTolerance) + assertEquals(-5f, vector.w, floatTolerance) + } + + @Test + fun `should create Vector4 with two Vector2 instances`() { + val vector = vec4(xy = Vector2(10f, 5f), zw = Vector2(20f, 30f)) + + assertEquals(10f, vector.x, floatTolerance) + assertEquals(5f, vector.y, floatTolerance) + assertEquals(20f, vector.z, floatTolerance) + assertEquals(30f, vector.w, floatTolerance) + } + + @Test + fun `should create Vector4 with Vector3 instance`() { + val vector = vec4(Vector3(10f, 5f, -5f)) + + assertEquals(10f, vector.x, floatTolerance) + assertEquals(5f, vector.y, floatTolerance) + assertEquals(-5f, vector.z, floatTolerance) + assertEquals(0f, vector.w, floatTolerance) + } + + @Test + fun `should create Vector4 with Vector3 instance and W component`() { + val vector = vec4(Vector3(10f, 5f, -15f), w = -5f) + + assertEquals(10f, vector.x, floatTolerance) + assertEquals(5f, vector.y, floatTolerance) + assertEquals(-15f, vector.z, floatTolerance) + assertEquals(-5f, vector.w, floatTolerance) + } + + @Test + fun `should invert values with unary - operator`() { + val originalVector = Vector4(10f, 15f, -10f, -5f) + + val vector = -originalVector + + assertEquals(-10f, vector.x, floatTolerance) + assertEquals(-15f, vector.y, floatTolerance) + assertEquals(10f, vector.z, floatTolerance) + assertEquals(5f, vector.w, floatTolerance) + assertEquals(10f, originalVector.x, floatTolerance) + assertEquals(15f, originalVector.y, floatTolerance) + assertEquals(-10f, originalVector.z, floatTolerance) + assertEquals(-5f, originalVector.w, floatTolerance) + } + + @Test + fun `should add vectors with += operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector += Vector4(20f, -20f, -10f, -5f) + + assertEquals(30f, vector.x, floatTolerance) + assertEquals(-10f, vector.y, floatTolerance) + assertEquals(0f, vector.z, floatTolerance) + assertEquals(5f, vector.w, floatTolerance) + } + + @Test + fun `should add Vector2 with += operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector += Vector2(20f, -20f) + + assertEquals(30f, vector.x, floatTolerance) + assertEquals(-10f, vector.y, floatTolerance) + assertEquals(10f, vector.z, floatTolerance) + assertEquals(10f, vector.w, floatTolerance) + } + + @Test + fun `should add Vector3 with += operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector += Vector3(20f, -20f, 5f) + + assertEquals(30f, vector.x, floatTolerance) + assertEquals(-10f, vector.y, floatTolerance) + assertEquals(15f, vector.z, floatTolerance) + assertEquals(10f, vector.w, floatTolerance) + } + + @Test + fun `should add floats to vectors with += operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector += 10f + + assertEquals(20f, vector.x, floatTolerance) + assertEquals(20f, vector.y, floatTolerance) + assertEquals(20f, vector.z, floatTolerance) + assertEquals(20f, vector.w, floatTolerance) + } + + @Test + fun `should add ints to vectors with += operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector += 10 + + assertEquals(20f, vector.x, floatTolerance) + assertEquals(20f, vector.y, floatTolerance) + assertEquals(20f, vector.z, floatTolerance) + assertEquals(20f, vector.w, floatTolerance) + } + + @Test + fun `should subtract vectors with -= operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector -= Vector4(20f, -20f, -10f, 5f) + + assertEquals(-10f, vector.x, floatTolerance) + assertEquals(30f, vector.y, floatTolerance) + assertEquals(20f, vector.z, floatTolerance) + assertEquals(5f, vector.w, floatTolerance) + } + + @Test + fun `should subtract Vector2 with -= operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector -= Vector2(20f, -20f) + + assertEquals(-10f, vector.x, floatTolerance) + assertEquals(30f, vector.y, floatTolerance) + assertEquals(10f, vector.z, floatTolerance) + assertEquals(10f, vector.w, floatTolerance) + } + + @Test + fun `should subtract Vector3 with -= operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector -= Vector3(20f, -20f, 5f) + + assertEquals(-10f, vector.x, floatTolerance) + assertEquals(30f, vector.y, floatTolerance) + assertEquals(5f, vector.z, floatTolerance) + assertEquals(10f, vector.w, floatTolerance) + } + + @Test + fun `should subtract floats from vectors with += operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector -= 20f + + assertEquals(-10f, vector.x, floatTolerance) + assertEquals(-10f, vector.y, floatTolerance) + assertEquals(-10f, vector.z, floatTolerance) + assertEquals(-10f, vector.w, floatTolerance) + } + + @Test + fun `should subtract ints from vectors with += operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector -= 20f + + assertEquals(-10f, vector.x, floatTolerance) + assertEquals(-10f, vector.y, floatTolerance) + assertEquals(-10f, vector.z, floatTolerance) + assertEquals(-10f, vector.w, floatTolerance) + } + + @Test + fun `should multiply vectors with timesAssign operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector *= Vector4(3f, -1f, 0.5f, 2f) + + assertEquals(30f, vector.x, floatTolerance) + assertEquals(-10f, vector.y, floatTolerance) + assertEquals(5f, vector.z, floatTolerance) + assertEquals(20f, vector.w, floatTolerance) + } + + @Test + fun `should multiply vectors by float scalars with timesAssign operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector *= 2.5f + + assertEquals(25f, vector.x, floatTolerance) + assertEquals(25f, vector.y, floatTolerance) + assertEquals(25f, vector.z, floatTolerance) + assertEquals(25f, vector.w, floatTolerance) + } + + @Test + fun `should multiply vectors by int scalars with timesAssign operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector *= 2 + + assertEquals(20f, vector.x, floatTolerance) + assertEquals(20f, vector.y, floatTolerance) + assertEquals(20f, vector.z, floatTolerance) + assertEquals(20f, vector.w, floatTolerance) + } + + @Test + fun `should divide vectors with divAssign operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector /= Vector4(2f, -5f, 0.5f, 0.25f) + + assertEquals(5f, vector.x, floatTolerance) + assertEquals(-2f, vector.y, floatTolerance) + assertEquals(20f, vector.z, floatTolerance) + assertEquals(40f, vector.w, floatTolerance) + } + + @Test + fun `should divide vectors by float scalars with divAssign operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector /= 2.5f + + assertEquals(4f, vector.x, floatTolerance) + assertEquals(4f, vector.y, floatTolerance) + assertEquals(4f, vector.z, floatTolerance) + assertEquals(4f, vector.w, floatTolerance) + } + + @Test + fun `should divide vectors by int scalars with divAssign operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + vector /= 2 + + assertEquals(5f, vector.x, floatTolerance) + assertEquals(5f, vector.y, floatTolerance) + assertEquals(5f, vector.z, floatTolerance) + assertEquals(5f, vector.w, floatTolerance) + } + + @Test + fun `should add vectors with + operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector + Vector4(20f, -20f, -10f, 5f) + + assertEquals(30f, result.x, floatTolerance) + assertEquals(-10f, result.y, floatTolerance) + assertEquals(0f, result.z, floatTolerance) + assertEquals(15f, result.w, floatTolerance) + } + + @Test + fun `should add Vector2 with + operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector + Vector2(20f, -20f) + + assertEquals(30f, result.x, floatTolerance) + assertEquals(-10f, result.y, floatTolerance) + assertEquals(10f, result.z, floatTolerance) + assertEquals(10f, result.w, floatTolerance) + } + + @Test + fun `should add Vector3 with + operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector + Vector3(20f, -20f, 5f) + + assertEquals(30f, result.x, floatTolerance) + assertEquals(-10f, result.y, floatTolerance) + assertEquals(15f, result.z, floatTolerance) + assertEquals(10f, result.w, floatTolerance) + } + + @Test + fun `should add vectors and floats with + operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector + 10f + + assertEquals(20f, result.x, floatTolerance) + assertEquals(20f, result.y, floatTolerance) + assertEquals(20f, result.z, floatTolerance) + assertEquals(20f, result.w, floatTolerance) + } + + @Test + fun `should add vectors and ints with + operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector + 10 + + assertEquals(20f, result.x, floatTolerance) + assertEquals(20f, result.y, floatTolerance) + assertEquals(20f, result.z, floatTolerance) + assertEquals(20f, result.w, floatTolerance) + } + + @Test + fun `should subtract vectors with - operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector - Vector4(20f, -20f, -10f, 5f) + + assertEquals(-10f, result.x, floatTolerance) + assertEquals(30f, result.y, floatTolerance) + assertEquals(20f, result.z, floatTolerance) + assertEquals(5f, result.w, floatTolerance) + } + + @Test + fun `should subtract Vector2 with - operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector - Vector2(20f, -20f) + + assertEquals(-10f, result.x, floatTolerance) + assertEquals(30f, result.y, floatTolerance) + assertEquals(10f, result.z, floatTolerance) + assertEquals(10f, result.w, floatTolerance) + } + + @Test + fun `should subtract Vector3 with - operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector - Vector3(20f, -20f, 5f) + + assertEquals(-10f, result.x, floatTolerance) + assertEquals(30f, result.y, floatTolerance) + assertEquals(5f, result.z, floatTolerance) + assertEquals(10f, result.w, floatTolerance) + } + + @Test + fun `should subtract vectors and floats with - operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector - 20f + + assertEquals(-10f, result.x, floatTolerance) + assertEquals(-10f, result.y, floatTolerance) + assertEquals(-10f, result.z, floatTolerance) + assertEquals(-10f, result.w, floatTolerance) + } + + @Test + fun `should subtract vectors and ints with - operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector - 20 + + assertEquals(-10f, result.x, floatTolerance) + assertEquals(-10f, result.y, floatTolerance) + assertEquals(-10f, result.z, floatTolerance) + assertEquals(-10f, result.w, floatTolerance) + } + + @Test + fun `should multiply vectors with times operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector * Vector4(3f, -1f, 0.5f, 2f) + + assertEquals(30f, result.x, floatTolerance) + assertEquals(-10f, result.y, floatTolerance) + assertEquals(5f, result.z, floatTolerance) + assertEquals(20f, result.w, floatTolerance) + } + + @Test + fun `should divide vectors with div operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector / Vector4(2f, -5f, 0.5f, 2.5f) + + assertEquals(5f, result.x, floatTolerance) + assertEquals(-2f, result.y, floatTolerance) + assertEquals(20f, result.z, floatTolerance) + assertEquals(4f, result.w, floatTolerance) + } + + @Test + fun `should multiply vectors by int scalars with times operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector * 2 + + assertEquals(20f, result.x, floatTolerance) + assertEquals(20f, result.y, floatTolerance) + assertEquals(20f, result.z, floatTolerance) + assertEquals(20f, result.w, floatTolerance) + } + + @Test + fun `should divide vectors by int scalars with div operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector / 2 + + assertEquals(5f, result.x, floatTolerance) + assertEquals(5f, result.y, floatTolerance) + assertEquals(5f, result.z, floatTolerance) + assertEquals(5f, result.w, floatTolerance) + } + + @Test + fun `should multiply vectors by float scalars with times operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector * 2.5f + + assertEquals(25f, result.x, floatTolerance) + assertEquals(25f, result.y, floatTolerance) + assertEquals(25f, result.z, floatTolerance) + assertEquals(25f, result.w, floatTolerance) + } + + @Test + fun `should divide vectors by float scalars with div operator`() { + val vector = Vector4(10f, 10f, 10f, 10f) + + val result = vector / 2.5f + + assertEquals(4f, result.x, floatTolerance) + assertEquals(4f, result.y, floatTolerance) + assertEquals(4f, result.z, floatTolerance) + assertEquals(4f, result.w, floatTolerance) + } + + @Test + fun `should increment vector values with ++ operator`() { + val originalVector = Vector4(10f, 10f, 10f, 10f) + var vector = originalVector + + vector++ + + assertEquals(11f, vector.x, floatTolerance) + assertEquals(11f, vector.y, floatTolerance) + assertEquals(11f, vector.z, floatTolerance) + assertEquals(11f, vector.w, floatTolerance) + assertEquals(10f, originalVector.x, floatTolerance) + assertEquals(10f, originalVector.y, floatTolerance) + assertEquals(10f, originalVector.z, floatTolerance) + assertEquals(10f, originalVector.w, floatTolerance) + } + + @Test + fun `should decrement vector values with -- operator`() { + val originalVector = Vector4(10f, 10f, 10f, 10f) + var vector = originalVector + + vector-- + + assertEquals(9f, vector.x, floatTolerance) + assertEquals(9f, vector.y, floatTolerance) + assertEquals(9f, vector.z, floatTolerance) + assertEquals(9f, vector.w, floatTolerance) + assertEquals(10f, originalVector.x, floatTolerance) + assertEquals(10f, originalVector.y, floatTolerance) + assertEquals(10f, originalVector.z, floatTolerance) + assertEquals(10f, originalVector.w, floatTolerance) + } + + @Test + fun `should destruct vector into three floats`() { + val (x, y, z, w) = Vector4(10f, 20f, 30f, 40f) + + assertEquals(10f, x, floatTolerance) + assertEquals(20f, y, floatTolerance) + assertEquals(30f, z, floatTolerance) + assertEquals(40f, w, floatTolerance) + } + + @Test + fun `should compare vectors by length`() { + val vec1 = Vector4(10f, 10f, 10f, 10f) + val vec2 = Vector4(10f, -20f, 10f, -10f) // This vector has the greatest overall length. + val vec3 = Vector4(10f, 10f, 10f, -10f) + + assertTrue(vec1 < vec2) + assertTrue(vec1 <= vec2) + assertFalse(vec1 > vec2) + assertFalse(vec1 >= vec2) + + assertTrue(vec1 >= vec3) + assertTrue(vec1 <= vec3) + assertFalse(vec1 < vec3) + assertFalse(vec1 > vec3) + assertTrue(vec1 == vec3.apply { w = -w }) + } + + @Test + fun `should calculate the dot product of two vectors`() { + val vec1 = Vector4(2f, 1f, 3f, 4f) + val vec2 = Vector4(3f, -4f, -3f, 2f) + + val result = vec1 dot vec2 + + assertEquals(1f, result, floatTolerance) + } +} From 91dfa69086ad07e61a914b8daa18c4aaa605a629 Mon Sep 17 00:00:00 2001 From: MJ Date: Sat, 4 Nov 2023 11:25:50 +0100 Subject: [PATCH 6/6] KTX version changed to 1.12.1-rc1. #474 --- CHANGELOG.md | 2 +- README.md | 4 ++-- version.txt | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 954c9e39..c15b086d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ _See also: [the official libGDX changelog](https://github.com/libgdx/libgdx/blob/master/CHANGES)._ -#### 1.12.1-SNAPSHOT +#### 1.12.1-rc1 - **[UPDATE]** Updated to libGDX 1.12.1. - **[UPDATE]** Updated to Kotlin 1.9.20. diff --git a/README.md b/README.md index 854c1d07..f85b3056 100644 --- a/README.md +++ b/README.md @@ -221,7 +221,7 @@ with the `ktx-app` identifier would require the following changes in your `build // Groovy DSL: ext { // Update this version to match the latest KTX release: - ktxVersion = '1.12.0-rc1' + ktxVersion = '1.12.1-rc1' } dependencies { @@ -235,7 +235,7 @@ dependencies { ```kotlin // Update this version to match the latest KTX release: -val ktxVersion = "1.12.0-rc1" +val ktxVersion = "1.12.1-rc1" dependencies { api(group = "io.github.libktx", name = "ktx-app", version = ktxVersion) diff --git a/version.txt b/version.txt index 8f34f8f2..e8e560f2 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.12.1-SNAPSHOT +1.12.1-rc1