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

Working on skeleton to support next features #8

Draft
wants to merge 7 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
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.github.sceneview.sceneview_flutter

import com.google.ar.core.Config

class ARSceneViewConfig(
val lightEstimationMode: Config.LightEstimationMode,
val instantPlacementMode: Config.InstantPlacementMode,
val depthMode: Config.DepthMode,
val planeRenderer: PlaneRenderer,
) {
companion object {
fun from(map: Map<String, Any>): ARSceneViewConfig {
return ARSceneViewConfig(
Config.LightEstimationMode.values()[map["lightEstimationMode"] as Int],
Config.InstantPlacementMode.values()[map["instantPlacementMode"] as Int],
Config.DepthMode.values()[map["depthMode"] as Int],
PlaneRenderer.from(map["planeRenderer"] as Map<String, Any>)
)
}
}

override fun toString(): String {
return "PlaneRenderer: ${planeRenderer}\n" +
"instantPlacementMode: $instantPlacementMode\n" +
"lightEstimationMode: $lightEstimationMode\n" +
"depthMode: $depthMode\n"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package io.github.sceneview.sceneview_flutter

import android.content.Context
import android.graphics.BitmapFactory
import android.util.Log

class Convert {

companion object {
fun toAugmentedImages(
context: Context,
list: List<Map<String, Any>>
): List<SceneViewAugmentedImage> {
val output = mutableListOf<SceneViewAugmentedImage>()
try {
list.forEach { map ->
if (map.containsKey("location") && map.containsKey("name")) {
val a = SceneViewAugmentedImage(
map["name"] as String,
context.assets.open(
Utils.getFlutterAssetKey(
context,
map["location"] as String,
)
)
.use(BitmapFactory::decodeStream)
)

output.add(a)
}
}
} catch (ex: Exception) {
Log.e("Convert.toAugmentedImages", ex.toString());
}
return output
}
}

}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package io.github.sceneview.sceneview_flutter

import dev.romainguy.kotlin.math.Float3
import dev.romainguy.kotlin.math.Quaternion

abstract class FlutterSceneViewNode(
val position: Float3 = Float3(0f, 0f, 0f),
val rotation: Float3 = Float3(0f, 0f, 0f),
val rotation: Quaternion = Quaternion(0f, 0f, 0f),
val scale: Float3 = Float3(0f, 0f, 0f),
val scaleUnits: Float = 1.0f,
) {
Expand All @@ -13,9 +14,9 @@ abstract class FlutterSceneViewNode(
fun from(map: Map<String, *>): FlutterSceneViewNode {
val fileLocation = map["fileLocation"] as String?
if (fileLocation != null) {
val p = FlutterPosition.from(map["position"] as Map<String, Float>?)
val r = FlutterRotation.from(map["rotation"] as Map<String, Float>?)
val s = FlutterScale.from(map["scale"] as Map<String, Float>?)
val p = FlutterPosition.from(map["position"] as List<Float>?)
val r = FlutterRotation.from(map["rotation"] as List<Float>?)
val s = FlutterScale.from(map["scale"] as List<Float>?)
val scaleUnits = map["scaleUnits"] as Float?
return FlutterReferenceNode(
fileLocation,
Expand All @@ -34,49 +35,50 @@ abstract class FlutterSceneViewNode(
class FlutterReferenceNode(
val fileLocation: String,
position: Float3,
rotation: Float3,
rotation: Quaternion,
scale: Float3,
scaleUnits: Float
) :
FlutterSceneViewNode(position, rotation, scale, scaleUnits)

class FlutterPosition(val position: Float3) {
companion object {
fun from(map: Map<String, Float>?): FlutterPosition {
if (map == null) {
fun from(list: List<Float>?): FlutterPosition {
if (list == null) {
return FlutterPosition(Float3(0f, 0f, 0f))
}
val x = (map["x"] as Double).toFloat()
val y = (map["y"] as Double).toFloat()
val z = (map["z"] as Double).toFloat()
val x = (list[0] as Double).toFloat()
val y = (list[1] as Double).toFloat()
val z = (list[2] as Double).toFloat()
return FlutterPosition(Float3(x, y, z))
}
}
}

class FlutterRotation(val rotation: Float3) {
class FlutterRotation(val rotation: Quaternion) {
companion object {
fun from(map: Map<String, Float>?): FlutterRotation {
if (map == null) {
return FlutterRotation(Float3(0f, 0f, 0f))
fun from(list: List<Float>?): FlutterRotation {
if (list == null) {
return FlutterRotation(Quaternion(0f, 0f, 0f, 0f))
}
val x = (map["x"] as Double).toFloat()
val y = (map["y"] as Double).toFloat()
val z = (map["z"] as Double).toFloat()
return FlutterRotation(Float3(x, y, z))
val x = (list[0] as Double).toFloat()
val y = (list[1] as Double).toFloat()
val z = (list[2] as Double).toFloat()
val w = (list[3] as Double).toFloat()
return FlutterRotation(Quaternion(x, y, z, w))
}
}
}

class FlutterScale(val scale: Float3) {
companion object {
fun from(map: Map<String, Float>?): FlutterScale {
if (map == null) {
fun from(list: List<Float>?): FlutterScale {
if (list == null) {
return FlutterScale(Float3(0f, 0f, 0f))
}
val x = (map["x"] as Double).toFloat()
val y = (map["y"] as Double).toFloat()
val z = (map["z"] as Double).toFloat()
val x = (list[0] as Double).toFloat()
val y = (list[1] as Double).toFloat()
val z = (list[2] as Double).toFloat()
return FlutterScale(Float3(x, y, z))
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package io.github.sceneview.sceneview_flutter

class PlaneRenderer(val isEnabled: Boolean, val isVisible: Boolean) {

companion object {

fun from(map: Map<String, Any>): PlaneRenderer {
return PlaneRenderer(
map["isEnabled"] as Boolean,
map["isVisible"] as Boolean,
)
}
}


override fun toString(): String {
return "isVisible: $isVisible, isEnabled: $isEnabled"
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package io.github.sceneview.sceneview_flutter

import android.graphics.Bitmap

class SceneViewAugmentedImage(
val name: String,
val bitmap: Bitmap,
)
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.github.sceneview.sceneview_flutter

import android.app.Activity
import android.content.Context
import android.util.Log
import androidx.lifecycle.Lifecycle
import io.flutter.plugin.common.BinaryMessenger

class SceneViewBuilder {

var augmentedImages = listOf<SceneViewAugmentedImage>()
lateinit var config: ARSceneViewConfig

fun build(
context: Context,
activity: Activity,
messenger: BinaryMessenger,
lifecycle: Lifecycle,
viewId: Int
): SceneViewWrapper {
Log.i("SceneViewBuilder", config.toString());
val controller =
SceneViewWrapper(context, activity, lifecycle, messenger, viewId, config, augmentedImages);
//controller.init()
//controller.setMyLocationEnabled(myLocationEnabled)
return controller
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,23 @@ class SceneViewFactory(
private val messenger: BinaryMessenger,
private val lifecycle: Lifecycle,
) : PlatformViewFactory(StandardMessageCodec.INSTANCE) {
override fun create(context: Context, viewId: Int, args: Any?): PlatformView {
override fun create(context: Context, viewId: Int, params: Any?): PlatformView {
Log.d("Factory", "Creating new view instance")
return SceneViewWrapper(context, activity, lifecycle, messenger, viewId);
val p = params as Map<String, Any>
val builder = SceneViewBuilder()
if(p.containsKey("arSceneviewConfig")){
val c = p["arSceneviewConfig"] as Map<String,Any>
builder.config = ARSceneViewConfig.from(c)
}
if (p.containsKey("augmentedImages")) {
builder.augmentedImages =
Convert.toAugmentedImages(
context,
p["augmentedImages"] as List<Map<String, Any>>
)
}

return builder.build(context, activity, messenger, lifecycle, viewId);
//return SceneViewWrapper(context, activity, lifecycle, messenger, viewId);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,19 @@ import android.view.View
import android.widget.FrameLayout
import androidx.lifecycle.Lifecycle
import com.google.ar.core.Config
import dev.romainguy.kotlin.math.Float3
import io.flutter.plugin.common.BinaryMessenger
import io.flutter.plugin.common.MethodCall
import io.flutter.plugin.common.MethodChannel
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
import io.flutter.plugin.platform.PlatformView
import io.github.sceneview.ar.ARSceneView
import io.github.sceneview.ar.arcore.addAugmentedImage
import io.github.sceneview.ar.arcore.getUpdatedPlanes
import io.github.sceneview.ar.node.AugmentedImageNode
import io.github.sceneview.model.ModelInstance
import io.github.sceneview.node.ModelNode
import io.github.sceneview.sceneview_flutter.flutter_models.FlutterPose
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
Expand All @@ -25,11 +30,14 @@ class SceneViewWrapper(
lifecycle: Lifecycle,
messenger: BinaryMessenger,
id: Int,
arConfig: ARSceneViewConfig,
private val augmentedImages: List<SceneViewAugmentedImage>,
) : PlatformView, MethodCallHandler {
private val TAG = "SceneViewWrapper"
private var sceneView: ARSceneView
private val _mainScope = CoroutineScope(Dispatchers.Main)
private val _channel = MethodChannel(messenger, "scene_view_$id")
val _augmentedImageNodes = mutableListOf<AugmentedImageNode>()

override fun getView(): View {
Log.i(TAG, "getView:")
Expand All @@ -42,15 +50,49 @@ class SceneViewWrapper(

init {
Log.i(TAG, "init")
Log.i(TAG, "there are " + augmentedImages.size.toString() + " augmentedImages")

sceneView = ARSceneView(context, sharedLifecycle = lifecycle)
sceneView.apply {

planeRenderer.isEnabled = arConfig.planeRenderer.isEnabled;
planeRenderer.isVisible = arConfig.planeRenderer.isVisible;

configureSession { session, config ->
config.lightEstimationMode = Config.LightEstimationMode.ENVIRONMENTAL_HDR
config.depthMode = when (session.isDepthModeSupported(Config.DepthMode.AUTOMATIC)) {
true -> Config.DepthMode.AUTOMATIC
augmentedImages.forEach {
config.addAugmentedImage(session, it.name, it.bitmap)
}

config.lightEstimationMode = arConfig.lightEstimationMode
config.depthMode = when (session.isDepthModeSupported(arConfig.depthMode)) {
true -> arConfig.depthMode
else -> Config.DepthMode.DISABLED
}
config.instantPlacementMode = Config.InstantPlacementMode.DISABLED
config.instantPlacementMode = arConfig.instantPlacementMode
}
onSessionUpdated = { session, frame ->
val map = HashMap<String, Any>()
val list = ArrayList<HashMap<String, Any>>()
//map["planes"] =
//frame.getUpdatedPlanes()
// .map { p -> hashMapOf<String, Any>("type" to p.type.ordinal) }.toList()

frame.getUpdatedPlanes().forEach { p ->
val m = HashMap<String, Any>()
m["type"] = p.type.ordinal
m["centerPose"] = FlutterPose.fromPose(p.centerPose).toHashMap()
list.add(m)
}

map["planes"] = list;

Log.i(TAG, map.toString());
_channel.invokeMethod("onSessionUpdated", map);
/*frame.getUpdatedPlanes()
.firstOrNull { it.type == Plane.Type.HORIZONTAL_UPWARD_FACING }
?.let { plane ->
addAnchorNode(plane.createAnchor(plane.centerPose))
}*/
}
onSessionResumed = { session ->
Log.i(TAG, "onSessionCreated")
Expand All @@ -63,6 +105,7 @@ class SceneViewWrapper(
}
onTrackingFailureChanged = { reason ->
Log.i(TAG, "onTrackingFailureChanged: $reason");
_channel.invokeMethod("onTrackingFailureChanged", reason?.ordinal);
}
}
sceneView.layoutParams = FrameLayout.LayoutParams(
Expand Down Expand Up @@ -119,7 +162,11 @@ class SceneViewWrapper(
val modelNode = ModelNode(modelInstance = model, scaleToUnits = 1.0f).apply {
transform(
position = flutterNode.position,
rotation = flutterNode.rotation,
rotation = Float3(
flutterNode.rotation.x,
flutterNode.rotation.y,
flutterNode.rotation.z
),
//scale = flutterNode.scale,
)
//scaleToUnitsCube(flutterNode.scaleUnits)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
package io.github.sceneview.sceneview_flutter.flutter_models

import com.google.ar.core.Pose

class FlutterPose(private val translation: FloatArray, private val rotation: FloatArray) {

fun toHashMap(): HashMap<String, Any> {
val map: HashMap<String, Any> = HashMap<String, Any>()
map["translation"] = convertFloatArray(translation)
map["rotation"] = convertFloatArray(rotation)
return map
}

private fun convertFloatArray(array: FloatArray): DoubleArray {
val doubleArray = DoubleArray(array.size)
for ((i, a) in array.withIndex()) {
doubleArray[i] = a.toDouble()
}
return doubleArray
}

companion object{
fun fromPose(pose: Pose): FlutterPose {
return FlutterPose(pose.translation, pose.rotationQuaternion)
}
}

}
Loading