Skip to content
Merged
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
2 changes: 1 addition & 1 deletion .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

14 changes: 14 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,11 +1,25 @@
import org.jlleitschuh.gradle.ktlint.reporter.ReporterType

// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath libs.ktlint.gradle
}
}
plugins {
alias(libs.plugins.ktlint)
}
ktlint {
android.set(true) // set true for Android projects
outputToConsole.set(true)
ignoreFailures.set(false)
enableExperimentalRules.set(false)
reporters {
reporter(ReporterType.PLAIN)
reporter(ReporterType.CHECKSTYLE)
}
}
5 changes: 4 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ work_version = "2.10.3"
junit_version = "4.13.2"
androidx_test_ext_junit_version = "1.3.0"
espresso_core_version = "3.7.0"
agpVersion = "8.13.1"
agpVersion = "8.13.2"
kotlinVersion = "2.2.10"
pytorchAndroidTorchCisionLite = "2.1.0"
kotlinGradlePluginVersion = "2.2.0"
Expand All @@ -27,6 +27,7 @@ gson = "2.13.1"
activityComposeVersion = "1.10.1"
composeBomVersion = "2024.09.00"
navigationComposeVersion = "2.9.3"
ktlint = "14.0.1"

[libraries]
androidx-constraintlayout = { module = "androidx.constraintlayout:constraintlayout", version.ref = "constraintlayoutVersion" }
Expand All @@ -48,6 +49,7 @@ jsoup = { module = "org.jsoup:jsoup", version.ref = "jsoupVersion" }
junit = { group = "junit", name = "junit", version.ref = "junit_version" }
androidx-test-ext-junit = { group = "androidx.test.ext", name = "junit", version.ref = "androidx_test_ext_junit_version" }
androidx-test-espresso-core = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espresso_core_version" }
ktlint-gradle = { module = "org.jlleitschuh.gradle:ktlint-gradle", version.ref = "ktlint" }
ktor-client-cio = { module = "io.ktor:ktor-client-cio", version.ref = "ktorClientCoreVersion" }
ktor-client-content-negotiation = { module = "io.ktor:ktor-client-content-negotiation", version.ref = "ktorClientCoreVersion" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktorClientCoreVersion" }
Expand Down Expand Up @@ -81,6 +83,7 @@ kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlinVer
kotlin-serialization = { id = "org.jetbrains.kotlin.plugin.serialization", version.ref = "kotlinVersion" }
kotlin-parcelize = { id = "org.jetbrains.kotlin.plugin.parcelize", version.ref = "kotlinVersion" }
kotlin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlinVersion" }
ktlint = { id = "org.jlleitschuh.gradle.ktlint", version.ref = "ktlint" }

[bundles]
androidx = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,9 @@ class Filament3dView(
private val modelAssetPath: String,
override val startFrame: Int,
override val endFrame: Int,
override val loop: Pair<Int, Int> = Pair(0, 0)
) : FrameLayout(context), MotionView {

override val loop: Pair<Int, Int> = Pair(0, 0),
) : FrameLayout(context),
MotionView {
override val effects: List<MotionEffect> = emptyList()

companion object {
Expand All @@ -50,9 +50,10 @@ class Filament3dView(
private lateinit var surfaceTexture: SurfaceTexture
private lateinit var surface: Surface

private val imageView = ImageView(context).apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
}
private val imageView =
ImageView(context).apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
}

init {
initializeFilament()
Expand All @@ -67,7 +68,7 @@ class Filament3dView(
surfaceTexture = SurfaceTexture(0)
surfaceTexture.setDefaultBufferSize(
MotionConfig.aspectRatio.width,
MotionConfig.aspectRatio.height
MotionConfig.aspectRatio.height,
)
surface = Surface(surfaceTexture)
engine = Engine.create()
Expand Down Expand Up @@ -109,12 +110,18 @@ class Filament3dView(
(MotionConfig.aspectRatio.width / MotionConfig.aspectRatio.height).toDouble(),
0.1,
1000.0,
Camera.Fov.VERTICAL
Camera.Fov.VERTICAL,
)
camera.lookAt(
0.0, 0.0, 5.0, // eyeX, eyeY, eyeZ
0.0, 0.0, 0.0, // centerX, centerY, centerZ
0.0, 1.0, 0.0 // upX, upY, upZ
0.0,
0.0,
5.0, // eyeX, eyeY, eyeZ
0.0,
0.0,
0.0, // centerX, centerY, centerZ
0.0,
1.0,
0.0, // upX, upY, upZ
)
view.camera = camera
}
Expand All @@ -136,9 +143,15 @@ class Filament3dView(
val height = view.viewport.height
val buffer = ByteBuffer.allocateDirect(width * height * 4)
renderer.readPixels(
0, 0, width, height, Texture.PixelBufferDescriptor(
buffer, Texture.Format.RGBA, Texture.Type.UBYTE
)
0,
0,
width,
height,
Texture.PixelBufferDescriptor(
buffer,
Texture.Format.RGBA,
Texture.Type.UBYTE,
),
)
buffer.rewind()
renderer.endFrame()
Expand Down Expand Up @@ -190,4 +203,4 @@ class Filament3dView(
fun destroy() {
cleanupFilament()
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ import java.nio.ByteOrder
import kotlin.math.cos
import kotlin.math.sin

class FilamentOffscreenCapturer(private val context: Context) {
class FilamentOffscreenCapturer(
private val context: Context,
) {
private lateinit var engine: Engine
private var renderer: Renderer? = null
private var scene: Scene? = null
Expand All @@ -39,10 +41,15 @@ class FilamentOffscreenCapturer(private val context: Context) {
private var asset: FilamentAsset? = null

enum class RotationAxis {
X, Y, Z
X,
Y,
Z,
}

fun init(width: Int, height: Int) {
fun init(
width: Int,
height: Int,
) {
engine = Engine.create()
renderer = engine.createRenderer()

Expand All @@ -65,12 +72,18 @@ class FilamentOffscreenCapturer(private val context: Context) {
width.toDouble() / height.toDouble(),
0.1,
100.0,
Camera.Fov.VERTICAL
Camera.Fov.VERTICAL,
)
camera?.lookAt(
0.0, 0.0, 3.0, // eye
0.0, 0.0, 0.0, // center
0.0, 1.0, 0.0 // up
0.0,
0.0,
3.0, // eye
0.0,
0.0,
0.0, // center
0.0,
1.0,
0.0, // up
)

val materialProvider = UbershaderProvider(engine)
Expand Down Expand Up @@ -108,7 +121,10 @@ class FilamentOffscreenCapturer(private val context: Context) {
scene?.addEntities(asset!!.entities)
}

fun setRotation(axis: RotationAxis, degrees: Float) {
fun setRotation(
axis: RotationAxis,
degrees: Float,
) {
asset?.let {
val radians = Math.toRadians(degrees.toDouble())
val cos = cos(radians).toFloat()
Expand All @@ -118,26 +134,62 @@ class FilamentOffscreenCapturer(private val context: Context) {
when (axis) {
RotationAxis.X -> {
// Rotate around X-axis
transform[0] = 1f; transform[4] = 0f; transform[8] = 0f; transform[12] = 0f
transform[1] = 0f; transform[5] = cos; transform[9] = -sin; transform[13] = 0f
transform[2] = 0f; transform[6] = sin; transform[10] = cos; transform[14] = 0f
transform[3] = 0f; transform[7] = 0f; transform[11] = 0f; transform[15] = 1f
transform[0] = 1f
transform[4] = 0f
transform[8] = 0f
transform[12] = 0f
transform[1] = 0f
transform[5] = cos
transform[9] = -sin
transform[13] = 0f
transform[2] = 0f
transform[6] = sin
transform[10] = cos
transform[14] = 0f
transform[3] = 0f
transform[7] = 0f
transform[11] = 0f
transform[15] = 1f
}

RotationAxis.Y -> {
// Rotate around Y-axis
transform[0] = cos; transform[4] = 0f; transform[8] = sin; transform[12] = 0f
transform[1] = 0f; transform[5] = 1f; transform[9] = 0f; transform[13] = 0f
transform[2] = -sin; transform[6] = 0f; transform[10] = cos; transform[14] = 0f
transform[3] = 0f; transform[7] = 0f; transform[11] = 0f; transform[15] = 1f
transform[0] = cos
transform[4] = 0f
transform[8] = sin
transform[12] = 0f
transform[1] = 0f
transform[5] = 1f
transform[9] = 0f
transform[13] = 0f
transform[2] = -sin
transform[6] = 0f
transform[10] = cos
transform[14] = 0f
transform[3] = 0f
transform[7] = 0f
transform[11] = 0f
transform[15] = 1f
}

RotationAxis.Z -> {
// Rotate around Z-axis
transform[0] = cos; transform[4] = -sin; transform[8] = 0f; transform[12] = 0f
transform[1] = sin; transform[5] = cos; transform[9] = 0f; transform[13] = 0f
transform[2] = 0f; transform[6] = 0f; transform[10] = 1f; transform[14] = 0f
transform[3] = 0f; transform[7] = 0f; transform[11] = 0f; transform[15] = 1f
transform[0] = cos
transform[4] = -sin
transform[8] = 0f
transform[12] = 0f
transform[1] = sin
transform[5] = cos
transform[9] = 0f
transform[13] = 0f
transform[2] = 0f
transform[6] = 0f
transform[10] = 1f
transform[14] = 0f
transform[3] = 0f
transform[7] = 0f
transform[11] = 0f
transform[15] = 1f
}
}

Expand All @@ -161,7 +213,10 @@ class FilamentOffscreenCapturer(private val context: Context) {
setRotation(RotationAxis.Z, degrees)
}

fun capture(width: Int, height: Int): Bitmap? {
fun capture(
width: Int,
height: Int,
): Bitmap? {
try {
if (renderer?.beginFrame(swapChain!!, 0L) == true) {
renderer?.render(view!!)
Expand All @@ -170,11 +225,12 @@ class FilamentOffscreenCapturer(private val context: Context) {

val pixelCount = width * height
val buf = ByteBuffer.allocateDirect(pixelCount * 4).order(ByteOrder.nativeOrder())
val descriptor = Texture.PixelBufferDescriptor(
buf,
Texture.Format.RGBA,
Texture.Type.UBYTE
)
val descriptor =
Texture.PixelBufferDescriptor(
buf,
Texture.Format.RGBA,
Texture.Type.UBYTE,
)
renderer?.readPixels(0, 0, width, height, descriptor)

buf.rewind()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,4 @@ class ExampleUnitTest {
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,24 +13,26 @@ class MotionOpenGlView(
modelAssetPath: String,
override val startFrame: Int,
override val endFrame: Int,
override val loop: Pair<Int, Int> = Pair(0, 0)
) : FrameLayout(context), MotionView {

override val loop: Pair<Int, Int> = Pair(0, 0),
) : FrameLayout(context),
MotionView {
override val effects: List<MotionEffect> = emptyList()

private val imageView = ImageView(context).apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
}
private val imageView =
ImageView(context).apply {
layoutParams = LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT)
}

// private val offscreenRenderer: OffscreenRenderer

val offscreenRenderer = Object3DToBitmapRenderer(
context = context,
assetFileName = modelAssetPath,
width = MotionConfig.aspectRatio.width,
height = MotionConfig.aspectRatio.height,
objectColor = floatArrayOf(0.7f, 0.3f, 0.3f, 1.0f)
)
val offscreenRenderer =
Object3DToBitmapRenderer(
context = context,
assetFileName = modelAssetPath,
width = MotionConfig.aspectRatio.width,
height = MotionConfig.aspectRatio.height,
objectColor = floatArrayOf(0.7f, 0.3f, 0.3f, 1.0f),
)

init {
// Initialize OpenGL renderer with the model asset path
Expand All @@ -53,4 +55,4 @@ class MotionOpenGlView(
}

override fun getViewBitmap(): Bitmap = offscreenRenderer.generateBitmap()!!
}
}
Loading
Loading