Skip to content

Commit

Permalink
feat: the last commit before the refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Cdm2883 committed Oct 5, 2024
1 parent 45318c5 commit 7fa8811
Show file tree
Hide file tree
Showing 36 changed files with 1,307 additions and 81 deletions.
1 change: 0 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ plugins {
alias(libs.plugins.kotlin.jvm) apply false
alias(libs.plugins.kotlin.multiplatform) apply false
alias(libs.plugins.jetbrains.dokka) apply false
alias(libs.plugins.vanniktech.maven.publish) apply false
}
1 change: 1 addition & 0 deletions example/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@ kotlin {
implementation(libs.chrisbanes.material3.window.size)

implementation(project(":oreui"))
implementation(project(":oreui-panorama"))
}
desktopMain.dependencies {
implementation(compose.desktop.currentOs)
Expand Down
22 changes: 11 additions & 11 deletions example/src/commonMain/kotlin/vip/cdms/orecompose/example/Theme.kt
Original file line number Diff line number Diff line change
Expand Up @@ -34,17 +34,17 @@ fun PanoramaBackground(content: @Composable BoxScope.() -> Unit) {
@OptIn(ExperimentalPanoramaApi::class)
@Composable
fun PanoramaBackground() {
val yaw by if (getPlatform() !is Platform.Desktop)
remember { mutableFloatStateOf((8..55).random() * 0.1f) } // TODO wait for three.js support
else tickFloat(
begin = 0.8f,
end = 5.5f,
step = 0.01f,
ticker = { tickerFlow(500.milliseconds) },
repeatMode = RepeatMode.Reverse
)
// val yaw by if (getPlatform() !is Platform.Desktop)
// remember { mutableFloatStateOf((8..55).random() * 0.1f) } // TODO wait for three.js support
// else tickFloat(
// begin = 0.8f,
// end = 5.5f,
// step = 0.01f,
// ticker = { tickerFlow(500.milliseconds) },
// repeatMode = RepeatMode.Reverse
// )
PanoramaViewer(
yaw = yaw,
modifier = Modifier.fillMaxSize().background(0xff161616.argb)
// yaw = yaw,
// modifier = Modifier.fillMaxSize().background(0xff161616.argb)
)
}
2 changes: 0 additions & 2 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ android-sdk-target = "34"
kotlin = "2.0.0"
compose-plugin = "1.6.11"
jetbrains-dokka = "1.9.20"
vanniktech-maven-publish = "0.28.0"

androidx-activity-compose = "1.9.0"
jetbrains-androidx-navigation-compose = "2.7.0-alpha07"
Expand All @@ -25,4 +24,3 @@ compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
kotlin-multiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
jetbrains-dokka = { id = "org.jetbrains.dokka", version.ref = "jetbrains-dokka" }
vanniktech-maven-publish = { id = "com.vanniktech.maven.publish", version.ref = "vanniktech-maven-publish" }
84 changes: 84 additions & 0 deletions oreui-panorama/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.dsl.JvmTarget
import org.jetbrains.kotlin.gradle.targets.js.dsl.ExperimentalWasmDsl

plugins {
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.android.library)
alias(libs.plugins.jetbrains.compose)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.jetbrains.dokka)
}

kotlin {
@OptIn(ExperimentalWasmDsl::class)
wasmJs {
browser {}
generateTypeScriptDefinitions()
}

androidTarget {
@OptIn(ExperimentalKotlinGradlePluginApi::class)
compilerOptions {
jvmTarget.set(JvmTarget.JVM_11)
}
}

jvm("desktop")

sourceSets {
val desktopMain by getting

androidMain.dependencies {
implementation(compose.preview)
implementation(libs.androidx.activity.compose)
}
commonMain.dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
implementation(project(":oreui"))
}
desktopMain.dependencies {
implementation(compose.desktop.currentOs)
}
wasmJsMain.dependencies {
implementation(npm("three", "0.167.0"))
}
}
}

android {
namespace = "vip.cdms.orecompose"
compileSdk = libs.versions.android.sdk.compile.get().toInt()

sourceSets["main"].manifest.srcFile("src/androidMain/AndroidManifest.xml")
sourceSets["main"].res.srcDirs("src/androidMain/res")
sourceSets["main"].resources.srcDirs("src/commonMain/resources")

defaultConfig {
minSdk = libs.versions.android.sdk.min.get().toInt()
testOptions.targetSdk = libs.versions.android.sdk.target.get().toInt()
lint.targetSdk = testOptions.targetSdk
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
buildTypes {
getByName("release") {
isMinifyEnabled = false
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
}
dependencies {
debugImplementation(compose.uiTooling)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package vip.cdms.orecompose.layout

import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ImageBitmap

@Composable
@ExperimentalPanoramaApi
actual fun PanoramaViewer(
equirectangular: ImageBitmap,
modifier: Modifier,
mask: Modifier?
) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ import androidx.compose.ui.graphics.drawscope.DrawScope.Companion.DefaultFilterQ
import androidx.compose.ui.layout.ContentScale
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import orecompose.oreui.generated.resources.Res
import orecompose.oreui.generated.resources.panorama
import orecompose.oreui_panorama.generated.resources.Res
import orecompose.oreui_panorama.generated.resources.panorama
import org.jetbrains.compose.resources.imageResource
import vip.cdms.orecompose.utils.*
import kotlin.math.*
Expand Down Expand Up @@ -62,9 +62,17 @@ val PanoramaCache = mutableMapOf<String, ImageBitmap>()
* print("Panorama image saved at: " + out_path)
* ```
*/
@ExperimentalPanoramaApi
@Composable
expect fun PanoramaViewer(
equirectangular: ImageBitmap = imageResource(Res.drawable.panorama),
modifier: Modifier = Modifier.fillMaxSize().background(0xff161616.argb),
mask: Modifier? = Modifier.fillMaxSize().background(0x01000000.argb),
)

@ExperimentalPanoramaApi // TODO 不同平台使用不同方案以优化性能 (web -> three.js ...)
@Composable
fun PanoramaViewer(
fun PanoramaViewer0(
equirectangular: ImageBitmap = imageResource(Res.drawable.panorama),
yaw: Float = 0f,
pitch: Float = 0f,
Expand Down Expand Up @@ -112,7 +120,7 @@ fun viewPanorama(
): ImageBitmap {
val hash = "${equirectangular.hashCode()},${yaw},${pitch},${fov},${width},${height}"
if (cache.contains(hash)) return cache[hash]!!

val equirectangularPixelMap = equirectangular.toPixelMap()
val perspectiveBitmap = ImageBitmap(width, height)
val canvas = Canvas(perspectiveBitmap)
Expand All @@ -121,7 +129,7 @@ fun viewPanorama(
val halfWidth = width / 2
val halfHeight = height / 2
val focalLength = halfWidth / tan(fov / 2)

for (x in 0 until width) {
for (y in 0 until height) {
val dx = (x - halfWidth).toFloat()
Expand All @@ -142,7 +150,7 @@ fun viewPanorama(
canvas.drawPixel(x.toFloat(), y.toFloat(), paint)
}
}

canvas.save()
cache[hash] = perspectiveBitmap
return perspectiveBitmap
Expand Down Expand Up @@ -171,20 +179,20 @@ fun convertCubemapToEquirectangular(
val output = ImageBitmap(width, height)
val canvas = Canvas(output)
val paint = newPixelPaint()

val frontData = front.toPixelMap()
val backData = back.toPixelMap()
val leftData = left.toPixelMap()
val rightData = right.toPixelMap()
val topData = top.toPixelMap()
val bottomData = bottom.toPixelMap()

fun sampleCubemapFace(data: PixelMap, faceSize: Int, u: Float, v: Float): Color {
val x = ((u + 1) / 2 * (faceSize - 1)).toInt().coerceIn(0, faceSize - 1)
val y = ((v + 1) / 2 * (faceSize - 1)).toInt().coerceIn(0, faceSize - 1)
return data[x, y]
}

fun equirectangularToCubemap(
theta: Float,
phi: Float,
Expand All @@ -193,17 +201,17 @@ fun convertCubemapToEquirectangular(
val x = cos(phi) * cos(theta)
val y = sin(phi)
val z = cos(phi) * sin(theta)

return when {
abs(x) >= abs(y) && abs(x) >= abs(z) -> if (x > 0) sampleCubemapFace(rightData, faceSize, -z / x, y / x)
else sampleCubemapFace(leftData, faceSize, z / x, y / x)
else sampleCubemapFace(leftData, faceSize, z / x, y / x)
abs(y) >= abs(x) && abs(y) >= abs(z) -> if (y > 0) sampleCubemapFace(topData, faceSize, x / y, -z / y)
else sampleCubemapFace(bottomData, faceSize, x / y, z / y)
else sampleCubemapFace(bottomData, faceSize, x / y, z / y)
else -> if (z > 0) sampleCubemapFace(frontData, faceSize, x / z, y / z)
else sampleCubemapFace(backData, faceSize, -x / z, y / z)
else sampleCubemapFace(backData, faceSize, -x / z, y / z)
}
}

for (y in 0 until height) {
val phi = PI * (y.toFloat() / height - 0.5f)
for (x in 0 until width) {
Expand All @@ -213,7 +221,7 @@ fun convertCubemapToEquirectangular(
canvas.drawPixel(x.toFloat(), y.toFloat(), paint)
}
}

canvas.save()
return output
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package vip.cdms.orecompose.layout

import androidx.compose.foundation.Canvas
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.ImageBitmap
import androidx.compose.ui.layout.onGloballyPositioned
import androidx.compose.ui.layout.positionInRoot
import vip.cdms.orecompose.utils.warpRect

@Composable
@ExperimentalPanoramaApi
actual fun PanoramaViewer(
equirectangular: ImageBitmap,
modifier: Modifier,
mask: Modifier?
) {
var boundingBox by remember { mutableStateOf(Rect.Zero) }

DisposableEffect(equirectangular, boundingBox) {
onDispose {
}
}

Box(modifier) {
Canvas(Modifier
.fillMaxSize()
.onGloballyPositioned { boundingBox = it.warpRect { positionInRoot() } }
) {
}
mask?.let { Spacer(it) }
}
}
Loading

0 comments on commit 7fa8811

Please sign in to comment.