init cloud anchors

This commit is contained in:
Raffaele Mignone 2019-01-15 20:50:43 +01:00
parent 07326e5e4f
commit 69c6bfdd6e
Signed by: norangebit
GPG Key ID: 4B9DF72AB9508845
52 changed files with 44875 additions and 0 deletions

11
cloud-anchors/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
*.iml
.gradle
/local.properties
/.idea/caches/build_file_checksums.ser
/.idea/libraries
/.idea/modules.xml
/.idea/workspace.xml
.DS_Store
/build
/captures
.externalNativeBuild

View File

@ -0,0 +1,35 @@
<component name="ProjectCodeStyleConfiguration">
<code_scheme name="Project" version="173">
<JetCodeStyleSettings>
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</JetCodeStyleSettings>
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="h" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />
</extensions>
</Objective-C-extensions>
<codeStyleSettings language="kotlin">
<option name="CODE_STYLE_DEFAULTS" value="KOTLIN_OFFICIAL" />
</codeStyleSettings>
</code_scheme>
</component>

View File

@ -0,0 +1,5 @@
<component name="ProjectCodeStyleConfiguration">
<state>
<option name="USE_PER_PROJECT_SETTINGS" value="true" />
</state>
</component>

View File

@ -0,0 +1,6 @@
<component name="CopyrightManager">
<copyright>
<option name="notice" value="Copyright (c) &amp;#36;today.year, norangebit &#10;&#10;This file is part of &amp;#36;project.name.&#10;&#10; &amp;#36;project.name is free software: you can redistribute it and/or modify&#10; it under the terms of the GNU General Public License as published by&#10; the Free Software Foundation, either version 3 of the License, or&#10; (at your option) any later version.&#10;&#10; &amp;#36;project.name is distributed in the hope that it will be useful,&#10; but WITHOUT ANY WARRANTY; without even the implied warranty of&#10; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the&#10; GNU General Public License for more details.&#10;&#10; You should have received a copy of the GNU General Public License&#10; along with &amp;#36;project.name. If not, see &lt;http://www.gnu.org/licenses/&gt;&#10;" />
<option name="myName" value="GPL v. 2.0" />
</copyright>
</component>

View File

@ -0,0 +1,7 @@
<component name="CopyrightManager">
<settings>
<module2copyright>
<element module="All" copyright="GPL v. 2.0" />
</module2copyright>
</settings>
</component>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

View File

@ -0,0 +1,38 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="7">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="javax.annotation.CheckForNull" />
<item index="3" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="4" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.Nullable" />
<item index="6" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="6">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
<item index="4" class="java.lang.String" itemvalue="androidx.annotation.NonNull" />
<item index="5" class="java.lang.String" itemvalue="androidx.annotation.RecentlyNonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

1
cloud-anchors/app/.gitignore vendored Normal file
View File

@ -0,0 +1 @@
/build

View File

@ -0,0 +1,48 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'com.google.gms.google-services'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.google.ar.sceneform.plugin'
android {
compileSdkVersion 28
defaultConfig {
applicationId "it.norangeb.cloudanchors"
minSdkVersion 26
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
implementation 'com.android.support:design:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation "com.google.ar.sceneform.ux:sceneform-ux:1.6.0"
implementation 'com.google.firebase:firebase-core:16.0.6'
implementation 'com.google.firebase:firebase-database:16.0.5'
}
sceneform.asset('sampledata/model.obj',
'default',
'sampledata/model.sfa',
'src/main/assets/model')

View File

@ -0,0 +1,55 @@
{
"project_info": {
"project_number": "774470937880",
"firebase_url": "https://open-ar.firebaseio.com",
"project_id": "open-ar",
"storage_bucket": "open-ar.appspot.com"
},
"client": [
{
"client_info": {
"mobilesdk_app_id": "1:774470937880:android:903e4220e58d36fa",
"android_client_info": {
"package_name": "it.norangeb.cloudanchors"
}
},
"oauth_client": [
{
"client_id": "774470937880-87uo07o9f9k7r3toc8r65botu8npfmg0.apps.googleusercontent.com",
"client_type": 1,
"android_info": {
"package_name": "it.norangeb.cloudanchors",
"certificate_hash": "7096e843f30ba2d3bb53525799ba9e5525e3544b"
}
},
{
"client_id": "774470937880-eam6gr89vqgqannuaah2vi86m18hqmr3.apps.googleusercontent.com",
"client_type": 3
}
],
"api_key": [
{
"current_key": "AIzaSyCkJohrCQfBuEQAFbnm6eW1hStY7scHuJQ"
}
],
"services": {
"analytics_service": {
"status": 1
},
"appinvite_service": {
"status": 2,
"other_platform_oauth_client": [
{
"client_id": "774470937880-eam6gr89vqgqannuaah2vi86m18hqmr3.apps.googleusercontent.com",
"client_type": 3
}
]
},
"ads_service": {
"status": 2
}
}
}
],
"configuration_version": "1"
}

21
cloud-anchors/app/proguard-rules.pro vendored Normal file
View File

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

View File

@ -0,0 +1,24 @@
newmtl mat14
Kd 1.00 0.34 0.13
newmtl mat8
Kd 0.96 0.26 0.21
newmtl mat12
Kd 1.00 0.92 0.23
newmtl mat10
Kd 0.30 0.69 0.31
newmtl mat20
Kd 0.47 0.33 0.28
newmtl mat24
Ka 0.58 0.65 1.00
Kd 0.92 0.95 0.94
Ks 1 1 1
illum 9
Ns 300
d 0.4
Ni 1.5

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,173 @@
{
materials: [
{
name: 'mat14',
parameters: [
{
baseColor: null,
},
{
baseColorTint: [
1,
0.34000000000000002,
0.13,
1,
],
},
{
metallic: 0,
},
{
roughness: 1,
},
{
opacity: null,
},
],
source: 'build/sceneform_sdk/default_materials/obj_material.sfm',
},
{
name: 'mat8',
parameters: [
{
baseColor: null,
},
{
baseColorTint: [
0.95999999999999996,
0.26000000000000001,
0.20999999999999999,
1,
],
},
{
metallic: 0,
},
{
roughness: 1,
},
{
opacity: null,
},
],
source: 'build/sceneform_sdk/default_materials/obj_material.sfm',
},
{
name: 'mat12',
parameters: [
{
baseColor: null,
},
{
baseColorTint: [
1,
0.92000000000000004,
0.23000000000000001,
1,
],
},
{
metallic: 0,
},
{
roughness: 1,
},
{
opacity: null,
},
],
source: 'build/sceneform_sdk/default_materials/obj_material.sfm',
},
{
name: 'mat10',
parameters: [
{
baseColor: null,
},
{
baseColorTint: [
0.29999999999999999,
0.68999999999999995,
0.31,
1,
],
},
{
metallic: 0,
},
{
roughness: 1,
},
{
opacity: null,
},
],
source: 'build/sceneform_sdk/default_materials/obj_material.sfm',
},
{
name: 'mat20',
parameters: [
{
baseColor: null,
},
{
baseColorTint: [
0.46999999999999997,
0.33000000000000002,
0.28000000000000003,
1,
],
},
{
metallic: 0,
},
{
roughness: 1,
},
{
opacity: null,
},
],
source: 'build/sceneform_sdk/default_materials/obj_material.sfm',
},
{
name: 'mat24',
parameters: [
{
baseColor: null,
},
{
baseColorTint: [
0.92000000000000004,
0.94999999999999996,
0.93999999999999995,
1,
],
},
{
metallic: 0,
},
{
roughness: 1,
},
{
opacity: 0.40000000000000002,
},
],
source: 'build/sceneform_sdk/default_materials/obj_material.sfm',
},
],
model: {
attributes: [
'Position',
'TexCoord',
'Orientation',
],
collision: {},
file: 'sampledata/model.obj',
name: 'model',
recenter: 'root',
scale: 0.30775799999999999,
},
version: '0.54:1',
}

View File

@ -0,0 +1,24 @@
package it.norangeb.cloudanchors
import android.support.test.InstrumentationRegistry
import android.support.test.runner.AndroidJUnit4
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.Assert.*
/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getTargetContext()
assertEquals("it.norangeb.cloudanchors", appContext.packageName)
}
}

View File

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="it.norangeb.cloudanchors">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera.ar" android:required="true" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<meta-data android:name="com.google.ar.core" android:value="required" />
<meta-data
android:name="com.google.android.ar.API_KEY"
android:value="API KEY" />
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>

Binary file not shown.

View File

@ -0,0 +1,33 @@
/*
* 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 com.google.ar.core.Config
import com.google.ar.core.Session
import com.google.ar.sceneform.ux.ArFragment
class CloudArFragment: ArFragment(){
override fun getSessionConfiguration(session: Session?): Config {
val config = super.getSessionConfiguration(session)
config.cloudAnchorMode = Config.CloudAnchorMode.ENABLED
return config
}
}

View File

@ -0,0 +1,159 @@
/*
* 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
private lateinit var storageManager: StorageManager
private var cloudAnchorState = CloudAnchorState.LOCAL
private var cloudAnchor: Anchor? = null
set(value) {
field?.detach()
field = value
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
if (!checkIsSupportedDeviceOrFinish(this, TAG))
return
storageManager = StorageManager(this)
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) {
if (cloudAnchorState != CloudAnchorState.LOCAL)
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()
cloudAnchorState = CloudAnchorState.LOCAL
return
}
if (cloudState != Anchor.CloudAnchorState.SUCCESS)
return
if (cloudAnchorState == CloudAnchorState.HOSTING)
checkHosting(cloudState)
else
checkResolving(cloudState)
}
private fun checkResolving(state: Anchor.CloudAnchorState) {
Toast.makeText(this, "Anchor resolved!", Toast.LENGTH_LONG)
.show()
cloudAnchorState = CloudAnchorState.RESOLVED
}
private fun checkHosting(state: Anchor.CloudAnchorState) {
storageManager.nextShortCode { shortCode ->
if (shortCode == null) {
toastError()
return@nextShortCode
}
storageManager.storeUsingShortCode(shortCode, cloudAnchor?.cloudAnchorId)
Toast.makeText(this, "Anchor hosted with code $shortCode", Toast.LENGTH_LONG)
.show()
Log.d("NORANGEBIT", "$shortCode")
}
cloudAnchorState = CloudAnchorState.HOSTED
}
private fun toastError() =
Toast.makeText(this, "Error", Toast.LENGTH_LONG)
.show()
private fun onResolveOkPressed(dialogValue: String) {
val shortCode = Integer.parseInt(dialogValue)
storageManager.getCloudAnchorID(shortCode) {
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) {
cloudAnchor = null
cloudAnchorState = CloudAnchorState.LOCAL
}
fun onResolveClick(view: View) {
if (cloudAnchor != null)
return
val dialog = ResolveDialogFragment()
dialog.setOkListener(this::onResolveOkPressed)
dialog.show(supportFragmentManager, "Resolve")
}
}

View File

@ -0,0 +1,77 @@
/**
* This class is made by Google
*
* visit https://codelabs.developers.google.com/codelabs/arcore-cloud-anchors/#3
*/
package it.norangeb.cloudanchors;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.os.Bundle;
import android.support.v4.app.DialogFragment;
import android.text.Editable;
import android.text.InputType;
import android.text.InputFilter;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.LinearLayout.LayoutParams;
/** A DialogFragment for the Resolve Dialog Box. */
public class ResolveDialogFragment extends DialogFragment {
// The maximum number of characters that can be entered in the EditText.
private static final int MAX_FIELD_LENGTH = 10;
interface OkListener {
/** This method is called by the dialog box when its OK button is pressed. */
void onOkPressed(String dialogValue);
}
private OkListener okListener;
private EditText shortCodeField;
/** Sets a listener that is invoked when the OK button on this dialog is pressed. */
void setOkListener(OkListener okListener) {
this.okListener = okListener;
}
/**
* Creates a simple layout for the dialog. This contains a single user-editable text field whose
* input type is retricted to numbers only, for simplicity.
*/
private LinearLayout getDialogLayout() {
Context context = getContext();
LinearLayout layout = new LinearLayout(context);
shortCodeField = new EditText(context);
// Only allow numeric input.
shortCodeField.setInputType(InputType.TYPE_CLASS_NUMBER);
shortCodeField.setLayoutParams(
new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
// Set a max length for the input text to avoid overflows when parsing.
shortCodeField.setFilters(new InputFilter[] {new InputFilter.LengthFilter(MAX_FIELD_LENGTH)});
layout.addView(shortCodeField);
layout.setLayoutParams(new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.WRAP_CONTENT));
return layout;
}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState) {
AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
builder
.setView(getDialogLayout())
.setTitle(R.string.resolve_dialog_title)
.setPositiveButton(
R.string.ok,
(dialog, which) -> {
Editable shortCodeText = shortCodeField.getText();
if (okListener != null && shortCodeText != null && shortCodeText.length() > 0) {
// Invoke the callback with the current checked item.
okListener.onOkPressed(shortCodeText.toString());
}
})
.setNegativeButton(R.string.cancel, (dialog, which) -> {});
return builder.create();
}
}

View File

@ -0,0 +1,98 @@
/**
* This class is made by Google
*
* visit https://codelabs.developers.google.com/codelabs/arcore-cloud-anchors/#4
*/
package it.norangeb.cloudanchors;
import android.content.Context;
import android.util.Log;
import com.google.firebase.FirebaseApp;
import com.google.firebase.database.*;
/** Helper class for Firebase storage of cloud anchor IDs. */
class StorageManager {
/** Listener for a new Cloud Anchor ID from the Firebase Database. */
interface CloudAnchorIdListener {
void onCloudAnchorIdAvailable(String cloudAnchorId);
}
/** Listener for a new short code from the Firebase Database. */
interface ShortCodeListener {
void onShortCodeAvailable(Integer shortCode);
}
private static final String TAG = StorageManager.class.getName();
private static final String KEY_ROOT_DIR = "shared_anchor_codelab_root";
private static final String KEY_NEXT_SHORT_CODE = "next_short_code";
private static final String KEY_PREFIX = "anchor;";
private static final int INITIAL_SHORT_CODE = 142;
private final DatabaseReference rootRef;
StorageManager(Context context) {
FirebaseApp firebaseApp = FirebaseApp.initializeApp(context);
rootRef = FirebaseDatabase.getInstance(firebaseApp).getReference().child(KEY_ROOT_DIR);
DatabaseReference.goOnline();
}
/** Gets a new short code that can be used to store the anchor ID. */
void nextShortCode(ShortCodeListener listener) {
// Run a transaction on the node containing the next short code available. This increments the
// value in the database and retrieves it in one atomic all-or-nothing operation.
rootRef
.child(KEY_NEXT_SHORT_CODE)
.runTransaction(
new Transaction.Handler() {
@Override
public Transaction.Result doTransaction(MutableData currentData) {
Integer shortCode = currentData.getValue(Integer.class);
if (shortCode == null) {
shortCode = INITIAL_SHORT_CODE - 1;
}
currentData.setValue(shortCode + 1);
return Transaction.success(currentData);
}
@Override
public void onComplete(
DatabaseError error, boolean committed, DataSnapshot currentData) {
if (!committed) {
Log.e(TAG, "Firebase Error", error.toException());
listener.onShortCodeAvailable(null);
} else {
listener.onShortCodeAvailable(currentData.getValue(Integer.class));
}
}
});
}
/** Stores the cloud anchor ID in the configured Firebase Database. */
void storeUsingShortCode(int shortCode, String cloudAnchorId) {
rootRef.child(KEY_PREFIX + shortCode).setValue(cloudAnchorId);
}
/**
* Retrieves the cloud anchor ID using a short code. Returns an empty string if a cloud anchor ID
* was not stored for this short code.
*/
void getCloudAnchorID(int shortCode, CloudAnchorIdListener listener) {
rootRef
.child(KEY_PREFIX + shortCode)
.addListenerForSingleValueEvent(
new ValueEventListener() {
@Override
public void onDataChange(DataSnapshot dataSnapshot) {
listener.onCloudAnchorIdAvailable(String.valueOf(dataSnapshot.getValue()));
}
@Override
public void onCancelled(DatabaseError error) {
Log.e(TAG, "The database operation for getCloudAnchorID was cancelled.",
error.toException());
listener.onCloudAnchorIdAvailable(null);
}
});
}
}

View File

@ -0,0 +1,150 @@
/*
* 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.annotation.SuppressLint
import android.app.Activity
import android.app.ActivityManager
import android.content.Context
import android.net.Uri
import android.os.Build
import android.util.Log
import android.widget.Toast
import com.google.ar.core.Anchor
import com.google.ar.core.Session
import com.google.ar.core.Trackable
import com.google.ar.core.TrackingState
import com.google.ar.sceneform.AnchorNode
import com.google.ar.sceneform.Node
import com.google.ar.sceneform.math.Vector3
import com.google.ar.sceneform.rendering.*
import com.google.ar.sceneform.ux.ArFragment
import com.google.ar.sceneform.ux.TransformableNode
private val MIN_OPENGL_VERSION = 3.0
@SuppressLint("ObsoleteSdkInt")
fun checkIsSupportedDeviceOrFinish(activity: Activity, tag: String): Boolean {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
Log.e(tag, "Sceneform requires Android N or later")
Toast.makeText(activity, "Sceneform requires Android N or later", Toast.LENGTH_LONG).show()
activity.finish()
return false
}
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
}
operator fun ArFragment.invoke(λ: ArFragment.() -> Unit) = λ()
fun isTrackig(trackable: Trackable) = trackable.trackingState == TrackingState.TRACKING
fun buildRenderable(
context: Context,
model: Uri,
onSuccess: (renderable: Renderable) -> Unit
) {
ModelRenderable.builder()
.setSource(context, model)
.build()
.thenAccept(onSuccess)
.exceptionally {
Log.e("SCENEFORM", "unable to load model", it)
return@exceptionally null
}
}
fun buildMaterial(
context: Context,
color: Color,
onSuccess: (material: Material) -> Unit
) {
MaterialFactory
.makeOpaqueWithColor(context, color)
.thenAccept(onSuccess)
}
fun changeColorOfMaterial(
context: Context,
color: Color,
renderable: Renderable
) {
val newColor = buildMaterial(context, color) {
renderable.material = it
}
}
/**
fun buildRenderable(
context: Context,
model: RenderableSource,
modelUri: Uri,
onSuccess: (renderable: Renderable) -> Unit
) {
ModelRenderable.builder()
.setRegistryId(modelUri)
.setSource(context, model)
.build()
.thenAccept(onSuccess)
.exceptionally {
Log.e("SCENEFORM", "unable to load model", it)
return@exceptionally null
}
}
fun fetchModel(
context: Context,
source: Uri
) : RenderableSource {
return RenderableSource.builder()
.setSource(context, source, RenderableSource.SourceType.GLTF2)
.setRecenterMode(RenderableSource.RecenterMode.ROOT)
.build()
}
*/
fun addTransformableNodeToScene(arFragment: ArFragment, anchor: Anchor, renderable: Renderable): Node {
val anchorNode = AnchorNode(anchor)
val transformableNode = TransformableNode(arFragment.transformationSystem)
transformableNode.renderable = renderable
transformableNode.setParent(anchorNode)
arFragment.arSceneView.scene.addChild(anchorNode)
transformableNode.select()
return transformableNode
}
enum class CloudAnchorState {
LOCAL,
HOSTING,
HOSTED,
RESOLVING,
RESOLVED
}

View File

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0"/>
<item
android:color="#00000000"
android:offset="1.0"/>
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1"/>
</vector>

View File

@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<vector
xmlns:android="http://schemas.android.com/apk/res/android"
android:height="108dp"
android:width="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path android:fillColor="#008577"
android:pathData="M0,0h108v108h-108z"/>
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
</vector>

View File

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>
~
-->
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<include layout="@layout/content_main" android:id="@+id/include"/>
<Button
android:text="@string/clear"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/clear_btn" app:layout_anchorGravity="left|bottom"
app:layout_anchor="@+id/include" android:onClick="onClearClick"/>
<Button
android:text="@string/resolve"
android:layout_width="wrap_content"
android:layout_height="wrap_content" android:id="@+id/resolve_btn" app:layout_anchorGravity="right|bottom"
app:layout_anchor="@+id/include" android:onClick="onResolveClick"/>
</android.support.design.widget.CoordinatorLayout>

View File

@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ 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/>
~
-->
<FrameLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
tools:showIn="@layout/activity_main"
tools:context=".MainActivity">
<fragment
android:layout_width="match_parent"
android:layout_height="match_parent" android:name="it.norangeb.cloudanchors.CloudArFragment"
android:id="@+id/ar_fragment"/>
</FrameLayout>

View File

@ -0,0 +1,9 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
tools:context="it.norangeb.cloudanchors.MainActivity">
<item android:id="@+id/action_settings"
android:title="@string/action_settings"
android:orderInCategory="100"
app:showAsAction="never"/>
</menu>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#008577</color>
<color name="colorPrimaryDark">#00574B</color>
<color name="colorAccent">#D81B60</color>
</resources>

View File

@ -0,0 +1,3 @@
<resources>
<dimen name="fab_margin">16dp</dimen>
</resources>

View File

@ -0,0 +1,9 @@
<resources>
<string name="app_name">cloud anchors</string>
<string name="action_settings">Settings</string>
<string name="clear">Clear</string>
<string name="resolve">resolve</string>
<string name="ok">OK</string>
<string name="cancel">Cancel</string>
<string name="resolve_dialog_title">Resolve Anchor</string>
</resources>

View File

@ -0,0 +1,17 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
<style name="AppTheme.NoActionBar">
<item name="windowActionBar">false</item>
<item name="windowNoTitle">true</item>
</style>
<style name="AppTheme.AppBarOverlay" parent="ThemeOverlay.AppCompat.Dark.ActionBar"/>
<style name="AppTheme.PopupOverlay" parent="ThemeOverlay.AppCompat.Light"/>
</resources>

View File

@ -0,0 +1,17 @@
package it.norangeb.cloudanchors
import org.junit.Test
import org.junit.Assert.*
/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}

View File

@ -0,0 +1,29 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
ext.kotlin_version = '1.3.11'
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.2.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.google.ar.sceneform:plugin:1.6.0'
classpath 'com.google.gms:google-services:4.2.0' // google-services plugin
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
google()
jcenter()
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}

View File

@ -0,0 +1,15 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
# Kotlin code style for this project: "official" or "obsolete":
kotlin.code.style=official

Binary file not shown.

View File

@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

172
cloud-anchors/gradlew vendored Executable file
View File

@ -0,0 +1,172 @@
#!/usr/bin/env sh
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

84
cloud-anchors/gradlew.bat vendored Normal file
View File

@ -0,0 +1,84 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

View File

@ -0,0 +1 @@
include ':app'