Skip to content
This repository has been archived by the owner on Jul 25, 2024. It is now read-only.

KGL-Math #19

Open
wants to merge 63 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
1d6115d
add implementation for FloatVector2
nlbuescher Feb 7, 2020
2de935c
reindent with tabs
nlbuescher Feb 7, 2020
96b56b1
Add documentation, and FloatVector3 implementation and helper functions.
nlbuescher Feb 12, 2020
cb1bd79
Convert initial implementation to code generation and remove generics
nlbuescher Feb 22, 2020
8349a53
add single value constructor for vectors
nlbuescher Feb 22, 2020
8fb028d
fix test dependency
nlbuescher Feb 23, 2020
effc8c5
list all targets
nlbuescher Feb 24, 2020
a72d815
make component function extensions
nlbuescher Feb 24, 2020
2de0b1f
implement all number types
nlbuescher Feb 25, 2020
a3db960
don't build outer FunSpec in controlFlow builder
nlbuescher Mar 2, 2020
013c278
code organization fixes and make dot and cross product extensions
nlbuescher Mar 2, 2020
f7b4dfa
add parentheses around result for dot product
nlbuescher Mar 2, 2020
cfb0220
refactor component handling (no need to specify component number, use…
nlbuescher Mar 2, 2020
5a8e180
better formatting in generated code
nlbuescher Mar 2, 2020
2d0c6c2
implement most common functions
nlbuescher Mar 3, 2020
8d02a27
refactor generation
nlbuescher Mar 4, 2020
edee669
include Boolean vector classes for relational return types
nlbuescher Mar 5, 2020
5460339
remove byte and short types (not actually in GLM) and add more common…
nlbuescher Mar 6, 2020
5eb436b
have `get` actually return the proper value
nlbuescher Mar 9, 2020
10b5839
implement preallocated commonly-used vectors
nlbuescher Mar 9, 2020
0ebe22b
implement frexp (toFractionAndExponent) for Float and Double based on…
nlbuescher Mar 9, 2020
048c9ba
finish up common functions with frexp and ldexp
nlbuescher Mar 10, 2020
0203337
enable CI?
nlbuescher Mar 10, 2020
e198e77
add implementation for FloatVector2
nlbuescher Feb 7, 2020
53eb5e0
reindent with tabs
nlbuescher Feb 7, 2020
647bb76
Add documentation, and FloatVector3 implementation and helper functions.
nlbuescher Feb 12, 2020
e3216cd
Convert initial implementation to code generation and remove generics
nlbuescher Feb 22, 2020
424dced
add single value constructor for vectors
nlbuescher Feb 22, 2020
5bc6f8f
fix test dependency
nlbuescher Feb 23, 2020
86c08aa
list all targets
nlbuescher Feb 24, 2020
e82d4ce
make component function extensions
nlbuescher Feb 24, 2020
25dd098
implement all number types
nlbuescher Feb 25, 2020
6e053e6
don't build outer FunSpec in controlFlow builder
nlbuescher Mar 2, 2020
e449687
code organization fixes and make dot and cross product extensions
nlbuescher Mar 2, 2020
9fabc65
add parentheses around result for dot product
nlbuescher Mar 2, 2020
5e745f4
refactor component handling (no need to specify component number, use…
nlbuescher Mar 2, 2020
a56947c
better formatting in generated code
nlbuescher Mar 2, 2020
469a7ec
implement most common functions
nlbuescher Mar 3, 2020
59714eb
refactor generation
nlbuescher Mar 4, 2020
83c4a05
include Boolean vector classes for relational return types
nlbuescher Mar 5, 2020
5d50ef2
remove byte and short types (not actually in GLM) and add more common…
nlbuescher Mar 6, 2020
bfb826a
have `get` actually return the proper value
nlbuescher Mar 9, 2020
327038e
implement preallocated commonly-used vectors
nlbuescher Mar 9, 2020
9248275
implement frexp (toFractionAndExponent) for Float and Double based on…
nlbuescher Mar 9, 2020
4f0eec7
finish up common functions with frexp and ldexp
nlbuescher Mar 10, 2020
70d6f20
enable CI?
nlbuescher Mar 10, 2020
9e5ccaa
Merge remote-tracking branch 'origin/math' into math
nlbuescher Mar 26, 2020
6a065bc
start implementing a few unit tests
nlbuescher Mar 31, 2020
f4011a0
finish up common functions tests
nlbuescher Mar 31, 2020
054f83b
refactor common functions to be consistent with stdlib
nlbuescher Apr 1, 2020
6de46f8
implement exponential functions
nlbuescher Apr 2, 2020
980ddee
restructure tests a bit and implement geometric functions
nlbuescher Apr 6, 2020
08afe2c
remove nodejs from js target
nlbuescher Apr 6, 2020
e059fc6
separate source set config from target declarations
nlbuescher Apr 8, 2020
343205e
change nomenclature to that used in GLM
nlbuescher May 7, 2020
ff6976b
start over and implement FloatVector2 and some missing Float math
nlbuescher May 19, 2020
096d75e
implement FloatVector3
nlbuescher May 20, 2020
b18f7eb
implement FloatVector3 project
nlbuescher May 21, 2020
e7437cb
Merge remote-tracking branch 'origin/math' into math
nlbuescher May 21, 2020
51d119a
implement FloatVector4
nlbuescher May 21, 2020
162587f
implement FloatMatrix4x4
nlbuescher May 23, 2020
a52cbf1
expand API with conversion functions, add array storage to all types …
nlbuescher May 29, 2020
1dc7d75
shorten type names
nlbuescher May 29, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
249 changes: 249 additions & 0 deletions buildSrc/src/main/kotlin/codegen/math/GenerateMath.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,249 @@
package codegen.math

import com.squareup.kotlinpoet.*
import com.squareup.kotlinpoet.KModifier.*
import org.gradle.api.DefaultTask
import org.gradle.api.tasks.OutputDirectory
import org.gradle.api.tasks.TaskAction

@Suppress("UnstableApiUsage")
open class GenerateMath : DefaultTask() {
@OutputDirectory
val outputDir = project.objects.directoryProperty()

@get:OutputDirectory
val commonDir = outputDir.file("common")


private val packageName = "com.kgl.math"

private val typeList = listOf(
BYTE to "0",
SHORT to "0",
INT to "0",
LONG to "0L",
U_BYTE to "0U",
U_SHORT to "0U",
U_INT to "0U",
U_LONG to "0UL",
FLOAT to "0f",
DOUBLE to "0.0"
)


@TaskAction
fun generate() {
vectorTypes()
}

private val allComponents = listOf(1 to "x", 2 to "y", 3 to "z", 4 to "w")
private val arithmetics = listOf("plus" to "+", "minus" to "-", "times" to "*", "div" to "/")

private fun vectorTypes() {
for (componentCount in 2..4) {
val components = allComponents.take(componentCount)

buildFile(packageName, "Vector$componentCount") {
nlbuescher marked this conversation as resolved.
Show resolved Hide resolved
import("kotlin.math", "sqrt")

typeList.forEach { (type, zero) ->
val vectorType = ClassName(packageName, "${type.simpleName}Vector$componentCount")
val mutableVectorType = ClassName(packageName, "Mutable${vectorType.simpleName}")

buildClass(vectorType) {
modifiers(SEALED)

components.forEach { (_, name) ->
property(name, type, ABSTRACT)
}

function("get") {
modifiers(OPERATOR)
parameter("index", INT)
controlFlow("when (index)") {
components.forEach { (i, name) ->
statement("${i - 1} -> $name")
}
statement("else -> throw IndexOutOfBoundsException()")
}
}

property("length", type) {
getter {
val code = when (type) {
BYTE, SHORT, INT, LONG ->
"return sqrt((this dot this).toDouble()).to${type.simpleName}()"
U_BYTE, U_SHORT, U_INT, U_LONG ->
"return sqrt((this dot this).toDouble()).to${type.simpleName.drop(1)}().to${type.simpleName}()"
else ->
"return sqrt(this dot this)"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be sqrt(lengthSquared).

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was intending to save a function call (of the lengthSquared getter). Should I not?

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmm. I trust the JVM to inline it but I'm not sure about LLVM. We can leave it until we start bench-marking.

}
statement(code)
}
}

property("lengthSquared", type) {
getter {
statement("return this dot this")
}
}

function("normalized") {
returns(vectorType)
statement("val length = length")
val args = components.joinToString { (_, name) ->
when (type) {
BYTE, SHORT,
U_BYTE, U_SHORT -> "($name / length).to${type.simpleName}()"
else -> "$name / length"
}
}
statement("return %T($args)", vectorType)
}

function("dot") {
nlbuescher marked this conversation as resolved.
Show resolved Hide resolved
modifiers(INFIX)
parameter("other", vectorType)
returns(type)
val result = components.joinToString(" + ") { (_, name) -> "$name * other.$name" }
.let {
when (type) {
BYTE, SHORT,
U_BYTE, U_SHORT -> "($it).to${type.simpleName}()"
else -> it
}
}
statement("return $result")
}

if (componentCount == 3) {
function("cross") {
nlbuescher marked this conversation as resolved.
Show resolved Hide resolved
modifiers(INFIX)
parameter("other", vectorType)
returns(vectorType)
val args =
components
.drop(1)
.plus(components.take(2))
.zipWithNext()
.joinToString { (c1, c2) ->
val name1 = c1.second
val name2 = c2.second
when (type) {
BYTE, SHORT,
U_BYTE, U_SHORT -> "($name1 * other.$name2 - other.$name1 * $name2).to${type.simpleName}()"
else -> "$name1 * other.$name2 - other.$name1 * $name2"
}
}
statement("return %T($args)", vectorType)
}
}

for ((name, op) in arithmetics) {
function(name) {
modifiers(OPERATOR)
parameter("other", vectorType)
returns(vectorType)
val args = components.joinToString { (_, name) ->
when (type) {
BYTE, SHORT,
U_BYTE, U_SHORT -> "($name $op other.$name).to${type.simpleName}()"
else -> "$name $op other.$name"
}
}
statement("return %T($args)", vectorType)
}
}
}

function(vectorType.simpleName) {
components.forEach { (_, name) ->
parameter(name, type)
}
returns(vectorType)
statement("return %T(${components.joinToString { it.second }})", mutableVectorType)
}

function(vectorType.simpleName) {
parameter("scalar", type)
returns(vectorType)
statement("return %T(scalar)", mutableVectorType)
}

buildClass(mutableVectorType) {
superclass(vectorType)

primaryConstructor {
components.forEach { (_, name) ->
parameter(name, type)
}
callSuperConstructor()
}

secondaryConstructor {
parameter("scalar", type)
callThisConstructor(*components.map { "scalar" }.toTypedArray())
}

secondaryConstructor {
callThisConstructor(*components.map { zero }.toTypedArray())
}

components.forEach { (_, name) ->
mutableProperty(name, type, OVERRIDE) {
initializer(name)
}
}

function("set") {
modifiers(OPERATOR)
parameter("index", INT)
parameter("value", type)
controlFlow("when(index)") {
components.forEach { (i, name) ->
statement("${i - 1} -> $name = value")
}
statement("else -> throw IndexOutOfBoundsException()")
}
}

function("normalize") {
statement("val length = length")
components.forEach { (_, name) ->
val code = when (type) {
BYTE, SHORT,
U_BYTE, U_SHORT -> "$name = ($name / length).to${type.simpleName}()"
else -> "$name /= length"
}
statement(code)
}
}

for ((funName, op) in arithmetics) {
function("${funName}Assign") {
modifiers(OPERATOR)
parameter("other", vectorType)
components.forEach { (_, name) ->
val code = when (type) {
BYTE, SHORT,
U_BYTE, U_SHORT -> "$name = ($name $op other.$name).to${type.simpleName}()"
else -> "$name $op= other.$name"
}
statement(code)
}
}
}
}

components.forEach { (i, name) ->
extensionFunction(vectorType, "component$i") {
modifiers(OPERATOR)
returns(type)
statement("return $name")
}
}
}
}.apply { writeTo(commonDir.get().asFile) }
}
}
}
Loading