Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Identify panels by name #535

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 2 additions & 1 deletion src/commonMain/kotlin/baaahs/geom/Matrix4F.kt
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,9 @@ expect class Matrix4F(elements: FloatArray? = null) {
fun withTranslation(translation: Vector3F): Matrix4F
fun withRotation(rotation: EulerAngle): Matrix4F
fun withScale(scale: Vector3F): Matrix4F
}

fun inverse(): Matrix4F
}
val Matrix4F.Companion.identity: Matrix4F
get() = Matrix4F()

Expand Down
15 changes: 11 additions & 4 deletions src/commonMain/kotlin/baaahs/gl/glsl/GlslType.kt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package baaahs.gl.glsl
import baaahs.show.mutable.MutableConstPort
import baaahs.show.mutable.MutablePort

sealed class GlslType constructor(
sealed class GlslType(
val glslLiteral: String,
val defaultInitializer: GlslExpr = GlslExpr("$glslLiteral(0.)")
) {
Expand All @@ -15,6 +15,7 @@ sealed class GlslType constructor(
val mutableDefaultInitializer: MutablePort get() = MutableConstPort(defaultInitializer.s, this)

private class OtherGlslType(glslLiteral: String) : GlslType(glslLiteral)

class Struct(
val name: String,
val fields: List<Field>,
Expand Down Expand Up @@ -121,8 +122,10 @@ sealed class GlslType constructor(
val typeStr = if (type is Struct) {
if (publicStructNames.contains(name)) name else namespace?.qualify(name) ?: name
} else type.glslLiteral
val comment = if (deprecated) " // Deprecated. $description" else description ?: ""
buf.append(" $typeStr $name;$comment\n")
buf.append(" $typeStr $name;")
if (deprecated) buf.append(" // Deprecated.")
if (!description.isNullOrBlank()) "// $description"
buf.append("\n")
}

override fun equals(other: Any?): Boolean {
Expand Down Expand Up @@ -152,6 +155,10 @@ sealed class GlslType constructor(
object Sampler2D : GlslType("sampler2D")
object Void : GlslType("void")

class Array(val type: GlslType, length: kotlin.Int) : GlslType("${type.glslLiteral}[$length]")

fun arrayOf(count: kotlin.Int): Array = Array(this, count)

open fun matches(otherType: GlslType): Boolean =
this == otherType

Expand Down Expand Up @@ -179,7 +186,7 @@ sealed class GlslType constructor(
return types.getOrPut(glsl) { OtherGlslType(glsl) }
}

fun Array<Pair<String, GlslType>>.toFields() =
fun kotlin.Array<Pair<String, GlslType>>.toFields() =
map { (name, type) -> Field(name, type) }

fun Collection<Map.Entry<String, GlslType>>.toFields() =
Expand Down
2 changes: 1 addition & 1 deletion src/commonMain/kotlin/baaahs/model/Model.kt
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ class Model(
}

interface Entity : FixtureInfo {
val name: String
val title: String get() = name
val description: String?
val defaultFixtureOptions: FixtureOptions?
Expand Down Expand Up @@ -133,6 +132,7 @@ class Model(
)

interface FixtureInfo {
val name: String
val transformation: Matrix4F
val bounds: Pair<Vector3F, Vector3F>

Expand Down
72 changes: 62 additions & 10 deletions src/commonMain/kotlin/baaahs/plugin/core/FixtureInfo.kt
Original file line number Diff line number Diff line change
Expand Up @@ -28,11 +28,47 @@ import kotlinx.serialization.Transient

val fixtureInfoStruct = GlslType.Struct(
"FixtureInfo",
GlslType.Field("position", GlslType.Vec3),
GlslType.Field("rotation", GlslType.Vec3),
GlslType.Field("transformation", GlslType.Matrix4),
GlslType.Field("boundaryMin", GlslType.Vec3),
GlslType.Field("boundaryMax", GlslType.Vec3)
GlslType.Field(
"position", GlslType.Vec3,
"The fixture entity's position in the scene."
),
GlslType.Field(
"rotation", GlslType.Vec3,
"The fixture entity's rotation in the scene."
),
GlslType.Field(
"transformation", GlslType.Matrix4,
"The fixture entity's transformation in the scene."
),
GlslType.Field(
"boundaryMin", GlslType.Vec3,
"The near-lower-leftmost coordinate of the fixture entity, after translation, in scene coordinates."
),
GlslType.Field(
"boundaryMax", GlslType.Vec3,
"The far-upper-rightmost coordinate of the fixture entity, after translation, in scene coordinates."
),
GlslType.Field(
"normalizer", GlslType.Matrix4,
"A transformation which normalizes the fixture entity's pixels to roughly face the camera " +
"and fit in [(0,0,0)..(1,1,1)]."
),

// TODO: Switch to `int[] name` when Kgl supports `uniform1iv`.
// See: https://github.com/gergelydaniel/kgl/pull/15
GlslType.Field("name", GlslType.Int.arrayOf(8), "ASCII values in the fixture entity's name, or 0's."),
// GlslType.Field("name0", GlslType.Int, "The first ASCII value in the fixture entity's name, or 0."),
// GlslType.Field("name1", GlslType.Int),
// GlslType.Field("name2", GlslType.Int),
// GlslType.Field("name3", GlslType.Int),
// GlslType.Field("name4", GlslType.Int),
// GlslType.Field("name5", GlslType.Int),
// GlslType.Field("name6", GlslType.Int),
// GlslType.Field("name7", GlslType.Int),
GlslType.Field(
"nameLength", GlslType.Int,
"The length of the fixture entity's name."
)
)

val fixtureInfoContentType = ContentType("fixture-info", "Fixture Info", fixtureInfoStruct)
Expand All @@ -52,8 +88,9 @@ data class FixtureInfoFeed(@Transient val `_`: Boolean = true) : Feed {

companion object : FeedBuilder<FixtureInfoFeed> {
override val title: String get() = "Fixture Info"
override val description: String get() =
"Information about the fixture's position and orientation in the model."
override val description: String
get() =
"Information about the fixture's position and orientation in the model."
override val resourceName: String get() = "FixtureInfo"
override val contentType: ContentType get() = fixtureInfoContentType
override val serializerRegistrar get() = classSerializer(serializer())
Expand All @@ -76,10 +113,15 @@ class FixtureInfoFeedContext(
private val transformationUniform = glslProgram.getUniform("$id.transformation")
private val boundaryMinUniform = glslProgram.getUniform("$id.boundaryMin")
private val boundaryMaxUniform = glslProgram.getUniform("$id.boundaryMax")
private val normalizerUniform = glslProgram.getUniform("$id.normalizer")
private val nameUniforms = (0 until 16).map { glslProgram.getUniform("$id.name$it") }
private val nameLengthUniform = glslProgram.getUniform("$id.nameLength")
private val anyNameUniforms = nameUniforms.any { it != null } || nameLengthUniform != null

override val isValid: Boolean get() =
positionUniform != null || rotationUniform != null || transformationUniform != null ||
boundaryMinUniform != null || boundaryMaxUniform != null
override val isValid: Boolean
get() =
positionUniform != null || rotationUniform != null || transformationUniform != null ||
boundaryMinUniform != null || boundaryMaxUniform != null

override fun setOnProgram(renderTarget: RenderTarget) {
val fixtureInfo = renderTarget.fixture.modelEntity as? Model.FixtureInfo
Expand All @@ -89,6 +131,16 @@ class FixtureInfoFeedContext(
val bounds = fixtureInfo?.bounds
boundaryMinUniform?.set(bounds?.first ?: Vector3F.origin)
boundaryMaxUniform?.set(bounds?.second ?: Vector3F.origin)
normalizerUniform?.set(fixtureInfo?.transformation?.inverse() ?: Matrix4F.identity)

if (fixtureInfo?.name != null && anyNameUniforms) {
val chars = fixtureInfo.name.toCharArray()
nameUniforms.forEachIndexed { i, uniform ->
val char = if (chars.size >= i) chars[i] else Char(0)
uniform?.set(char.uppercaseChar().code)
}
nameLengthUniform?.set(chars.size)
}
}
}
}
Expand Down
Loading