Created
September 3, 2019 18:21
Star
You must be signed in to star a gist
Augmented Marble reference code
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
Copyright 2018 Google LLC. | |
Licensed under the Apache License, Version 2.0 (the "License"); | |
you may not use this file except in compliance with the License. | |
You may obtain a copy of the License at | |
http://www.apache.org/licenses/LICENSE-2.0 | |
Unless required by applicable law or agreed to in writing, software | |
distributed under the License is distributed on an "AS IS" BASIS, | |
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
See the License for the specific language governing permissions and | |
limitations under the License. | |
--> | |
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" | |
xmlns:tools="http://schemas.android.com/tools" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" | |
tools:context=".HelloSceneformActivity"> | |
<fragment | |
android:id="@+id/ux_fragment" | |
android:name="com.google.ar.sceneform.ux.ArFragment" | |
android:layout_width="match_parent" | |
android:layout_height="match_parent" /> | |
<LinearLayout | |
android:layout_width="match_parent" | |
android:layout_height="wrap_content" | |
android:gravity="bottom|center_horizontal" | |
android:background="#80000000"> | |
<TextView | |
android:id="@+id/tv_scale" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_gravity="center_vertical" | |
android:layout_margin="8dp" | |
android:layout_weight="0" | |
android:text="Scale" /> | |
<SeekBar | |
android:id="@+id/sb_scale" | |
android:layout_width="0dp" | |
android:layout_height="wrap_content" | |
android:layout_gravity="center_vertical" | |
android:layout_margin="8dp" | |
android:layout_weight="1" | |
android:max="110" /> | |
<TextView | |
android:id="@+id/tv_scale_data" | |
android:layout_width="wrap_content" | |
android:layout_height="wrap_content" | |
android:layout_gravity="center_vertical" | |
android:layout_margin="8dp" | |
android:layout_weight="0" | |
android:text="mm" /> | |
</LinearLayout> | |
</FrameLayout> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* Copyright 2018 Google LLC. All Rights Reserved. | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); | |
* you may not use this file except in compliance with the License. | |
* You may obtain a copy of the License at | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software | |
* distributed under the License is distributed on an "AS IS" BASIS, | |
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
* See the License for the specific language governing permissions and | |
* limitations under the License. | |
*/ | |
package com.google.ar.sceneform.samples.hellosceneform | |
import android.app.Activity | |
import android.app.ActivityManager | |
import android.content.Context | |
import android.os.Bundle | |
import android.support.v7.app.AppCompatActivity | |
import android.util.Log | |
import android.view.Gravity | |
import android.view.MotionEvent | |
import android.widget.SeekBar | |
import android.widget.Toast | |
import com.google.ar.core.HitResult | |
import com.google.ar.core.Plane | |
import com.google.ar.sceneform.AnchorNode | |
import com.google.ar.sceneform.collision.Box | |
import com.google.ar.sceneform.math.Vector3 | |
import com.google.ar.sceneform.rendering.ModelRenderable | |
import com.google.ar.sceneform.ux.ArFragment | |
import com.google.ar.sceneform.ux.TransformableNode | |
import kotlinx.android.synthetic.main.activity_ux.* | |
import java.util.* | |
/** | |
* This is an example activity that uses the Sceneform UX package to make common AR tasks easier. | |
*/ | |
class HelloSceneformActivity : AppCompatActivity() { | |
private lateinit var sbScale: SeekBar | |
private var arFragment: ArFragment? = null | |
private var thinkerRenderable: ModelRenderable? = null | |
private val nodeList = ArrayList<TransformableNode>() | |
// CompletableFuture requires api level 24, FutureReturnValueIgnored is not valid | |
override fun onCreate(savedInstanceState: Bundle?) { | |
super.onCreate(savedInstanceState) | |
if (!checkIsSupportedDeviceOrFinish(this)) { | |
return | |
} | |
setContentView(R.layout.activity_ux) | |
arFragment = supportFragmentManager.findFragmentById(R.id.ux_fragment) as ArFragment | |
sbScale = findViewById(R.id.sb_scale) | |
sbScale.progress = 50 | |
sbScale.setOnSeekBarChangeListener(object : SeekBar.OnSeekBarChangeListener { | |
override fun onProgressChanged(seekBar: SeekBar, i: Int, b: Boolean) { | |
tv_scale_data.text = "${i + 10} mm" | |
for (node in nodeList) { | |
val box = node.renderable.collisionShape as Box | |
val renderableSize = box.size | |
val renderableHeightInMeters = renderableSize.z | |
val desiredHeightInMeters = (i.toFloat() + 10.0f) / 1000.0f | |
val scaleZ = desiredHeightInMeters / renderableHeightInMeters | |
node.parent.worldScale = Vector3(scaleZ, scaleZ, scaleZ) | |
} | |
} | |
override fun onStartTrackingTouch(seekBar: SeekBar) { | |
// do nothing | |
} | |
override fun onStopTrackingTouch(seekBar: SeekBar) { | |
// do nothing | |
} | |
}) | |
tv_scale_data.text = "${sbScale.progress + 10} mm" | |
// When you build a Renderable, Sceneform loads its resources in the background while returning | |
// a CompletableFuture. Call thenAccept(), handle(), or check isDone() before calling get(). | |
ModelRenderable.builder() | |
.setSource(this, R.raw.thinker) | |
.build() | |
.thenAccept { renderable -> thinkerRenderable = renderable } | |
.exceptionally { | |
val toast = Toast.makeText(this, "Unable to load thinker renderable", Toast.LENGTH_LONG) | |
toast.setGravity(Gravity.CENTER, 0, 0) | |
toast.show() | |
null | |
} | |
arFragment!!.setOnTapArPlaneListener { hitResult: HitResult, _: Plane, _: MotionEvent -> | |
if (thinkerRenderable == null) { | |
return@setOnTapArPlaneListener | |
} | |
// Create the Anchor. | |
val anchor = hitResult.createAnchor() | |
val anchorNode = AnchorNode(anchor) | |
anchorNode.setParent(arFragment!!.arSceneView.scene) | |
// Create the transformable thinker and add it to the anchor. | |
val thinker = TransformableNode(arFragment!!.transformationSystem) | |
thinker.setParent(anchorNode) | |
thinker.renderable = thinkerRenderable | |
thinker.select() | |
val box = thinker.renderable.collisionShape as Box | |
val renderableSize = box.size | |
val renderableHeightInMeters = renderableSize.z | |
val desiredHeightInMeters = (sbScale.progress.toFloat() + 10.0f) / 1000.0f | |
val scaleZ = desiredHeightInMeters / renderableHeightInMeters | |
anchorNode.worldScale = Vector3(scaleZ, scaleZ, scaleZ) | |
nodeList.add(thinker) | |
} | |
} | |
companion object { | |
private val TAG = HelloSceneformActivity::class.java.simpleName | |
private const val MIN_OPENGL_VERSION = 3.0 | |
/** | |
* Returns false and displays an error message if Sceneform can not run, true if Sceneform can run | |
* on this device. | |
* | |
* | |
* Sceneform requires Android N on the device as well as OpenGL 3.0 capabilities. | |
* | |
* | |
* Finishes the activity if Sceneform can not run | |
*/ | |
fun checkIsSupportedDeviceOrFinish(activity: Activity): Boolean { | |
val openGlVersionString = (activity.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager) | |
.deviceConfigurationInfo | |
.glEsVersion | |
if (java.lang.Double.parseDouble(openGlVersionString) < MIN_OPENGL_VERSION) { | |
Log.e(TAG, "Sceneform requires OpenGL ES 3.0 later") | |
Toast.makeText(activity, "Sceneform requires OpenGL ES 3.0 or later", Toast.LENGTH_LONG) | |
.show() | |
activity.finish() | |
return false | |
} | |
return true | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment