2019-01-15 19:50:43 +00:00
|
|
|
/*
|
|
|
|
* Copyright (c) 2019, norangebit
|
|
|
|
*
|
|
|
|
* This file is part of cloud-anchors.
|
|
|
|
*
|
|
|
|
* cloud-anchors is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* cloud-anchors is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with cloud-anchors. If not, see <http://www.gnu.org/licenses/>
|
|
|
|
*
|
|
|
|
*/
|
|
|
|
|
|
|
|
package it.norangeb.cloudanchors
|
|
|
|
|
|
|
|
import android.net.Uri
|
|
|
|
import android.os.Bundle
|
|
|
|
import android.support.v7.app.AppCompatActivity
|
|
|
|
import android.util.Log
|
|
|
|
import android.view.MotionEvent
|
|
|
|
import android.view.View
|
|
|
|
import android.widget.Toast
|
|
|
|
import com.google.ar.core.*
|
|
|
|
import com.google.ar.sceneform.FrameTime
|
|
|
|
import com.google.ar.core.Anchor
|
|
|
|
|
|
|
|
|
|
|
|
class MainActivity : AppCompatActivity() {
|
|
|
|
private val TAG = MainActivity::class.java.canonicalName
|
|
|
|
|
|
|
|
private lateinit var arFragment: CloudArFragment
|
2019-01-21 17:23:12 +00:00
|
|
|
private val cloudAnchorsHelper = CloudAnchorsHelper()
|
|
|
|
private var cloudAnchorState = CloudAnchorState.NONE
|
2019-01-15 19:50:43 +00:00
|
|
|
private var cloudAnchor: Anchor? = null
|
|
|
|
set(value) {
|
|
|
|
field?.detach()
|
|
|
|
field = value
|
|
|
|
}
|
|
|
|
|
|
|
|
override fun onCreate(savedInstanceState: Bundle?) {
|
|
|
|
super.onCreate(savedInstanceState)
|
|
|
|
|
|
|
|
if (!checkIsSupportedDeviceOrFinish(this, TAG))
|
|
|
|
return
|
|
|
|
|
|
|
|
setContentView(R.layout.activity_main)
|
|
|
|
|
|
|
|
arFragment = supportFragmentManager.findFragmentById(R.id.ar_fragment) as CloudArFragment
|
|
|
|
|
|
|
|
arFragment.setOnTapArPlaneListener(this::addModel)
|
|
|
|
|
|
|
|
arFragment.arSceneView.scene
|
|
|
|
.addOnUpdateListener(this::checkCloudAnchor)
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun addModel(hitResult: HitResult, plane: Plane, motionEvent: MotionEvent) {
|
2019-01-21 17:23:12 +00:00
|
|
|
if (cloudAnchorState != CloudAnchorState.NONE)
|
2019-01-15 19:50:43 +00:00
|
|
|
return
|
|
|
|
|
|
|
|
cloudAnchor = arFragment.arSceneView.session
|
|
|
|
.hostCloudAnchor(hitResult.createAnchor())
|
|
|
|
|
|
|
|
cloudAnchorState = CloudAnchorState.HOSTING
|
|
|
|
|
|
|
|
buildRenderable(this, Uri.parse("model.sfb")) {
|
|
|
|
addTransformableNodeToScene(
|
|
|
|
arFragment,
|
|
|
|
cloudAnchor ?: return@buildRenderable,
|
|
|
|
it
|
|
|
|
)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun checkCloudAnchor(frameTime: FrameTime) {
|
|
|
|
if (cloudAnchorState != CloudAnchorState.HOSTING
|
|
|
|
&& cloudAnchorState != CloudAnchorState.RESOLVING
|
|
|
|
)
|
|
|
|
return
|
|
|
|
|
|
|
|
val cloudState = cloudAnchor?.cloudAnchorState ?: return
|
|
|
|
|
|
|
|
if (cloudState.isError) {
|
|
|
|
toastError()
|
2019-01-21 17:23:12 +00:00
|
|
|
cloudAnchorState = CloudAnchorState.NONE
|
2019-01-15 19:50:43 +00:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
if (cloudState != Anchor.CloudAnchorState.SUCCESS)
|
|
|
|
return
|
|
|
|
|
|
|
|
if (cloudAnchorState == CloudAnchorState.HOSTING)
|
2019-01-21 17:23:12 +00:00
|
|
|
checkHosting()
|
2019-01-15 19:50:43 +00:00
|
|
|
else
|
2019-01-21 17:23:12 +00:00
|
|
|
checkResolving()
|
2019-01-15 19:50:43 +00:00
|
|
|
}
|
|
|
|
|
2019-01-21 17:23:12 +00:00
|
|
|
private fun checkResolving() {
|
2019-01-15 19:50:43 +00:00
|
|
|
Toast.makeText(this, "Anchor resolved!", Toast.LENGTH_LONG)
|
|
|
|
.show()
|
|
|
|
cloudAnchorState = CloudAnchorState.RESOLVED
|
|
|
|
}
|
|
|
|
|
2019-01-21 17:23:12 +00:00
|
|
|
private fun checkHosting() {
|
|
|
|
val cAnchor = cloudAnchor ?: return
|
2019-01-15 19:50:43 +00:00
|
|
|
|
2019-01-21 17:23:12 +00:00
|
|
|
val shortCode = cloudAnchorsHelper.getShortCode(cAnchor.cloudAnchorId)
|
|
|
|
|
|
|
|
Toast.makeText(this, "Anchor hosted with code $shortCode", Toast.LENGTH_LONG)
|
|
|
|
.show()
|
|
|
|
Log.d("NORANGEBIT", "$shortCode")
|
2019-01-15 19:50:43 +00:00
|
|
|
|
|
|
|
cloudAnchorState = CloudAnchorState.HOSTED
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun toastError() =
|
|
|
|
Toast.makeText(this, "Error", Toast.LENGTH_LONG)
|
|
|
|
.show()
|
|
|
|
|
|
|
|
private fun onResolveOkPressed(dialogValue: String) {
|
2019-01-21 17:23:12 +00:00
|
|
|
val shortCode = dialogValue.toInt()
|
|
|
|
cloudAnchorsHelper.getCloudAnchorId(shortCode) {
|
2019-01-15 19:50:43 +00:00
|
|
|
cloudAnchor = arFragment.arSceneView.session
|
|
|
|
.resolveCloudAnchor(it)
|
|
|
|
|
|
|
|
buildRenderable(this, Uri.parse("model.sfb")) {
|
|
|
|
val anchor = cloudAnchor ?: return@buildRenderable
|
|
|
|
addTransformableNodeToScene(arFragment, anchor, it)
|
|
|
|
cloudAnchorState = CloudAnchorState.RESOLVING
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fun onClearClick(view: View) {
|
2019-01-16 21:02:43 +00:00
|
|
|
cloudAnchor?.detach()
|
2019-01-15 19:50:43 +00:00
|
|
|
cloudAnchor = null
|
2019-01-21 17:23:12 +00:00
|
|
|
cloudAnchorState = CloudAnchorState.NONE
|
2019-01-15 19:50:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
fun onResolveClick(view: View) {
|
|
|
|
if (cloudAnchor != null)
|
|
|
|
return
|
|
|
|
|
|
|
|
val dialog = ResolveDialogFragment()
|
|
|
|
dialog.setOkListener(this::onResolveOkPressed)
|
|
|
|
dialog.show(supportFragmentManager, "Resolve")
|
|
|
|
}
|
|
|
|
}
|