Samsung / GearVRf

The GearVR framework(GearVRf) is an Open Source VR rendering library for application development on VR-supported Android devices.
http://www.gearvrf.org
Apache License 2.0
407 stars 217 forks source link

Eyepicker + TextViewSceneObjects #800

Open Nathipha opened 8 years ago

Nathipha commented 8 years ago

I'm currently trying to get the following to work: Two to four buttons (TextViewSceneObjects) with the one you look at changing color. Later I also want to make them clickable to start different things depending on which one got chosen.

Here's my code (half taken from the "gvrpickandmove" sample):

public class PickHandler implements IPickEvents {
    public void onEnter(GVRSceneObject sceneObj, GVRPicker.GVRPickedObject pickInfo) {
        if(sceneObj instanceof GVRTextViewSceneObject) {
            ((GVRTextViewSceneObject) sceneObj).setBackgroundColor(Color.GREEN);
            picked = sceneObj;
        }
    }
    public void onExit(GVRSceneObject sceneObj) {
        if(sceneObj instanceof GVRTextViewSceneObject) {
            ((GVRTextViewSceneObject) sceneObj).setBackgroundColor(Color.BLACK);
        }
    }
    public void onNoPick(GVRPicker picker) {
        picked = null;
    }
    public void onPick(GVRPicker picker) { }
    public void onInside(GVRSceneObject sceneObj, GVRPicker.GVRPickedObject pickInfo) { }
}

@Override
public void onInit(GVRContext gvrContext) {
    .....

    GVRSceneObject headTracker = new GVRSceneObject(gvrContext,
        new FutureWrapper<GVRMesh>(gvrContext.createQuad(0.1f, 0.1f)),
        gvrContext.loadFutureTexture(new GVRAndroidResource(
            gvrc, R.drawable.crosshair)));
    headTracker.getTransform().setPosition(0.0f, 0.0f, -1.0f);
    headTracker.getRenderData().setDepthTest(false);
    headTracker.getRenderData().setRenderingOrder(100000);
    scene.getMainCameraRig().addChildObject(headTracker);
    headTracker.attachComponent(new GVRPicker(gvrContext, scene));
    pickHandler = new PickHandler();
    scene.getEventReceiver().addListener(pickHandler);

    scene.getMainCameraRig().getLeftCamera().setBackgroundColor(1.0f, 0.0f, 0.0f, 1.0f);
    scene.getMainCameraRig().getRightCamera().setBackgroundColor(1.0f, 0.0f, 0.0f, 1.0f);
    GVRTextViewSceneObject b1 = new GVRTextViewSceneObject(gvrContext, 2f, 0.5f, "test 1");
    GVRTextViewSceneObject b2 = new GVRTextViewSceneObject(gvrContext, 2f, 0.5f, "test 2");
    b1.getTransform().setPosition(0.0f, 0.5f, -2.0f);
    b1.setGravity(Gravity.CENTER | Gravity.CENTER);
    b1.setTextSize(5);
    b1.setBackgroundColor(Color.BLACK);
    scene.addSceneObject(b1);
    buttons.add(b1);
    b1.attachComponent(new GVRMeshCollider(gvrc, true));

    b2.getTransform().setPosition(0.0f, -0.5f, -2.0f);
    b2.setGravity(Gravity.CENTER | Gravity.CENTER);
    b2.setTextSize(5);
    b2.setBackgroundColor(Color.BLACK);
    scene.addSceneObject(b2);
    buttons.add(b2);
    b2.attachComponent(new GVRMeshCollider(gvrc, true));
}

The problem is: Depending on what I attach, changing the color doesn't work properly, it simply ignores the outer half of the background: http://i.imgur.com/JQUyRyp.png

... or changes the color even though I don't even look at the button anymore: http://i.imgur.com/89g6mLG.png

Plus, there's this weird black border outside of the green background.

What I've already tried:

  1. b1.attachComponent(new GVRMeshCollider(gvrc, true)): The button is green and also stays green if I look at it but I get the two bugs mentioned above.
  2. With the second parameter set to false, the background doesn't stay green when the pointer is inside. If I additionally use "onInside", the text isn't seen as inside, so looking at it will turn the background black again, plus there's only a small area around the text that will make the background change its color.
  3. b1.attachComponent(new GVRSphereCollider(gvrc)): Same problems as in 1..
  4. b1.attachComponent(new GVRMeshCollider(gvrc, b1.getRenderData().getMesh())): Same problems as in 2..

Is there a specific way I have to do it, so it sees the whole background as "inside"?

rahul27 commented 8 years ago

Could you try

mainScene.getMainCameraRig().getOwnerObject().attachComponent(new GVRPicker(gvrContext, scene));

instead of

headTracker.attachComponent(new GVRPicker(gvrContext, scene));
NolaDonato commented 8 years ago

This is a bug which I have been able to replicate with the latest master. I will look at why picking seems to not work with text view scene objects.

NolaDonato commented 8 years ago

Pull request #812 should fix this bug. Please give it a try and see if it fixes your program.

Nathipha commented 8 years ago

@rahul27 Thank you, I tested all four ways with your suggestion and it looks like "new GVRMeshCollider(gvrc, false)" is the way to go with it. From the left it triggers the color change a little bit too early and from the right a little bit too late but I yet have to test it with two buttons next to each other and if it doesn't get worse, I'd say that the small offset is neglectable with a completely black background (only changed it to red for testing).

As with the other ways:

  1. made the detection area bigger, so the black background completely triggers the change but it looks like the area is a circle and there's still the same problem like in the second screenshot.
  2. Same as 2., so okay.
  3. Same as 1.

Is it important that I detach the picker and delete the tracker again manually? I keep getting this error when I try to clear the scene through "scene.removeAllSceneObjects()" (which is line 790) before adding a TextViewSceneObject (in my case an error message) after pressing the picked button:

08-17 15:39:32.739: E/MessageQueue-JNI(8826): java.lang.UnsupportedOperationException: GVRSceneObject cannot have multiple parents
08-17 15:39:32.739: E/MessageQueue-JNI(8826):   at org.gearvrf.GVRSceneObject.addChildObject(GVRSceneObject.java:754)
08-17 15:39:32.739: E/MessageQueue-JNI(8826):   at org.gearvrf.GVRScene.addSceneObject(GVRScene.java:111)
08-17 15:39:32.739: E/MessageQueue-JNI(8826):   at org.gearvrf.GVRScene.removeAllSceneObjects(GVRScene.java:135)
08-17 15:39:32.739: E/MessageQueue-JNI(8826):   at com.xxxx.xxxx.MainScript.showText(MainScript.java:790)

Something else I just noticed: The console says "The library 'framework.jar' contains native libraries that will not run on the device." when I run my app on the phone through Eclipse (don't know if it's a new message or if it's been there the whole time). Will that be a problem at some point or can I just ignore it?

@NolaDonato Thank you. Unfortunately I still haven't gotten Android Studio to work and import the project properly, so unless there are any huge changes and bug fixes my app has to rely on, I'll just finish it with Eclipse and only then migrate and get the newest version.

NolaDonato commented 8 years ago

GVRMeshCollider(gvrc, false) will pick against the triangles in the mesh. It is a good way to go if you are using text views because it is the most precise way of picking and a text view is only two triangles so it is actually cheaper than testing against the bounding box.

GVRMeshCollider(gvrc, true) makes a bounding box around your mesh and picks against that. If you rotate your mesh it recomputes the rotated bounding box from the corners of the original so it is not a tight fit. If you have a complex mesh it is a lot faster.

GVRSphereCollider makes a sphere from the bounding box of your mesh and picks against that. You can supply a radius to make the sphere smaller. This is the fastest but least precise way of picking. I would not use it for buttons that are close. It will give you onEnter for both sometimes.

With pull request #812 I changed GVRPicker to pick from the viewpoint of the camera if you don't attach it to a scene object. Now you simply need to instantiate it to start picking:

GVRPicker myPicker = new GVRPicker(context, scene);

I will look into why removeAllSceneObjects crashes when using text views. This is a bug and it is not caused by anything your program did incorrectly.

NolaDonato commented 8 years ago

Did you get the picker working in your application? The pull request is now checked in to the master branch.

Nathipha commented 8 years ago

Thanks for the explanation!

I didn't even manage to get an older version of my code from just before I switched to 3.0.1 to work with 3.0.1 again but I think I found the problem for that: If I use "scene.removeAllSceneObjects()" on an "empty" scene (apparently there are always at least 5 scene objects in it, even directly after "scene = gvrContext.getNextMainScene()"), it causes the above error message to show. "if(!scene.getSceneObjects().isEmpty())" doesn't work in this case, I had to use "if(scene.getWholeSceneObjects().length>5)".

I also did a little bit more testing and yes, you're right, TextViews make "removeAllSceneObjects" throw that error message but it's not only that, even normal SceneObjects (in my case they were created with "GL_LINE_STRIP") cause the same problem - and "if(scene.getWholeSceneObjects().length>5)" doesn't help then of course.

I did get the initial button picking to work with rahul27's suggestion but sorry, I haven't been able to test your change from the master branch because of the >3.0.1/Eclipse incompatibility yet.

Nathipha commented 8 years ago

Any news on a fix for the crashes? Sorry if I seem a bit impatient, it's just that I can't really do/test anything until this problem is fixed and my app can properly clear the scene again and reverting back to a pre-3.0.1 version of the Framework would most likely break the EyePicker.

NolaDonato commented 8 years ago

I have tested GVRScene.clear() on an empty scene and it does not crash with the latest GearVRF. Here is my test: GVRSceneObject sphere = new GVRSceneObject(ctx); GVRTextViewSceneObject text = new GVRTextViewSceneObject(ctx, "Hello");

    text.getTransform().setPosition(-1, 0, -2);
    sphere.getTransform().setPosition(1, 0, -2);
    scene.addSceneObject(sphere);
    scene.addSceneObject(text);
    text.setName("text");
    sphere.setName("sphere");
    scene.bindShaders();
    scene.clear();

This test does not crash the current framework. I will need a specific sample that crashes for you to see if I can reproduce the problem here.

Nathipha commented 8 years ago

I see you're using "scene.clear()", should I use that or rather "scene.removeAllSceneObjects()" like I always have?

I always clear the scene before adding something new, just to be safe that there are no leftovers, so it's possible that an actually empty scene gets cleared and with "scene.getSceneObjects().isEmpty()" not working in my version, I can't really rely on "if(scene.getWholeSceneObjects().length>5)" in case there are any changes to that later. So, I mean "empty scene" as in actually empty (without adding any objects), like:

GVRTextViewSceneObject text = new GVRTextViewSceneObject(ctx, "Hello");
scene.removeAllSceneObjects();

This only started crashing my app when I got 3.0.1, with the last version I had before that I've never had any problems.

NolaDonato commented 8 years ago

The five objects in the scene are the root node and the camera group which has a left, right and center camera. These are needed for head tracking to work. GVRScene.clear() just calls GVRScene.removeAllSceneObjects() so I am not really doing anything different than you are.

The root node will only have one child if the scene is empty (the camera rig). This does not crash on the latest GearVRF when I run it.

    GVRTextViewSceneObject text = new GVRTextViewSceneObject(ctx, "Hello");
    scene.removeAllSceneObjects();
Nathipha commented 8 years ago

Ah, okay.

Oh, it looks like only 3.0.1 has this bug then, which really isn't good. Is there any way to get a different version of 3.x.x that works properly (clearing and head tracking) but also still supports Eclipse?

thomasflynn commented 8 years ago

@NolaDonato can you checkout 3.0.1 and see if you can apply your bugfix to it? You may have to coordinate with @liaxim. I'd like to 1) unblock @Nathipha and 2) See what we can do to help @Nathipha migrate to Android Studio.

Nathipha commented 8 years ago

Yes, it would be awesome if you could fix 3.0.1 for Eclipse because I'm giving up on Android Studio.

I managed to kind of get it to import my Eclipse project but in the end it gave me the "Gradle project sync failed. Basic functionality (e.g. editing, debugging) will not work properly." message and the folder structure was messed up too, so a complete fail on that part.

New try: With a new project and manually added my java files, res stuff and the changes of the old manifest. I then (like it says here: https://github.com/Samsung/GearVRf/releases/tag/v3.0.1) copied the "libvrapi.so" file to "\app\jniLibs" and "SystemUtils.jar" and "VrApi.jar" to "\app\libs" and added the latter two as libraries. That's where the problems begin: I got the newest version of the framework (so the zip file) and managed to add it as a module but adding it to the "Dependencies" tab (File - Project Structure) as a "Module Dependency" doesn't work. Or it does but it won't save it - same thing with the path of the NDK: I've put it in at least 5 times already but the next time I open those settings, the path is gone again. And yes, I did clean/build the project (Build - Clean Project / Rebuild Project) right after adding every time but even that doesn't work:

Information:Gradle tasks [clean, :app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:prepareDebugUnitTestDependencies, :app:mockableAndroidJar, :framework:generateDebugSources, :framework:generateDebugAndroidTestSources, :framework:prepareDebugUnitTestDependencies, :framework:mockableAndroidJar]
Warning:not copying Oculus files; OVR_MOBILE_SDK not found
Warning:relying on hard-coded paths and environment variables; OVR_MOBILE_SDK not found
:clean
:app:clean
:framework:cleanNative FAILED
Error:Execution failed for task ':framework:cleanNative'.
> A problem occurred starting process 'command 'ndk-build.cmd''
Information:BUILD FAILED

My "ovr_sdk_mobile" folder is still in the same spot it has always been in, same thing for the "Framework" folder and there are environment variables for both the "ovr_sdk_mobile" and the NDK folder.

liaxim commented 8 years ago

Instead of environment variables or relying on a fixed folder structure there is a better way. Modify gradle.properties (either the project's or the global one; global one recommended) to include:

ANDROID_NDK_HOME=<path-to-your-ndk>
OVR_MOBILE_SDK=<path-to-your-ovr-sdk>

Are you using Windows? Which Android Studio version?

The global gradle.properties should be under ~/.gradle/ on Linux and under the .gradle/ in user's directory in Windows.

Nathipha commented 8 years ago

Win 7 (64 bit) and 2.1.2 (I know, there's an update).

I added it in the "gradle.properties" in "wrapper\dists\gradle-2.10-all\samples\userguide\tutorial\properties" (there were three more: 1 in "samples\signing\maven" and 2 in "wrapper\dists\gradle-1.12-all" - my project uses 2.10 according to the folder in Android Studio) but still the same errors. Also no changes after including it in the "gradle-wrapper.properties" file in "G:\Dev\Android\workspace\myapp\gradle\wrapper".

liaxim commented 8 years ago

I guess it would be best for you to just add these properties to the gradle.properties file under ./GVRf/Framework/. Should eliminate some confusion.

NolaDonato commented 8 years ago

I tried to build the latest with Eclipse and it doesn't work because we split out the Oculus back end to be separate and the old project files don't reflect that. I think we are stuck with Android Studio unless this is an easy fix to the Eclipse projects.

NolaDonato commented 8 years ago
If you replace GVRScene.removeAllSceneObjects in release 3.0.1 with the code below, it won't crash anymore.

public void removeAllSceneObjects() { GVRCameraRig rig = getMainCameraRig(); GVRSceneObject head = rig.getOwnerObject(); rig.removeAllChildren(); head.getParent().removeChildObject(head);

    for (GVRSceneObject child : mSceneRoot.getChildren()) {
        child.getParent().removeChildObject(child);
    }

    NativeScene.removeAllSceneObjects(getNative());
    synchronized (mLightList)
    {
        mLightList.clear();
    }
    mSceneRoot = new GVRSceneObject(getGVRContext());
    mSceneRoot.addChildObject(head);
    NativeScene.addSceneObject(getNative(), mSceneRoot.getNative());
}
Nathipha commented 8 years ago

@liaxim I removed the framework in the module settings, deleted the folder in the project overview on the left, then added the paths to the "gradle.properties file under ./GVRf/Framework/" (I used the already existing lines in the file), re-imported it and added the dependency to my app but I still get the same error messages. Another build/cleaning and even "invalidate caches / restart" didn't help and the framework got deleted from the "dependencies" tab again. Something else seems to be going on with Android Studio too. I'm also working on a small side-app for my main app and I sadly have to use Android Studio because there's no ADT versions for API > 21 for Eclipse. It took me over an hour to get the project to even build because of some weird "could not delete file" error messages and when I just now let it install the newest version (2.1.3), it gave me the same "Access Denied" for the "Delete" action **\ again. It looks like Android Studio really wants to be "special" and needs admin access for everything (still didn't fix my problem with the damn thing unfortunately)...

@NolaDonato Thank you so much, with your changes my app works again, even without "if(scene.getWholeSceneObjects().length>5)"! :)

liaxim commented 8 years ago

@Nathipha

  1. start from scratch
  2. import the Framework project (GVRf/Framework/)
  3. open settings.gradle (in the Android view's gradle scripts); add this
include ':myapp'
project(':myapp').projectDir=new File('full-path-to-your-apps-module')

If full-path-to-your-apps-module were to be some of our samples it would look like /home/some_user/GearVRf-Demos/gvr-eyepicking/app

  1. open module settings of your app, go to the dependencies tab; add a module dependency to the framework; this should be it.
Nathipha commented 8 years ago

@liaxim Thanks, I'll try it either later today or tomorrow. Is it not necessary to add the oculussig in Android Studio (didn't find the "assets" folder in the new project) or is there a different folder for it?

@NolaDonato I just found another bug that's most likely connected to the first one: If I get every scene object with "scene.getWholeSceneObjects()", save it as an array and then later readd everything, it throws the same error message. Fortunately I can just do

for(int i=scene.getWholeSceneObjects().length;i<objects.length;i++)

and that'll work (as far as I've seen).

liaxim commented 8 years ago

@Nathipha The oculus sig file needs to go your app's assets folder.

Nathipha commented 8 years ago

@liaxim There's none in my Android Studio project, hm... Possible that it didn't even set up correctly then. I'll check again after following your steps.

NolaDonato commented 8 years ago

The error message is because you are trying to add something to the scene that has already been added. In GearVRf a scene object cannot have multiple parents. If you get all the objects and then try to add them again it is correct in giving you this message. Here is how to add something that is already in the scene somewhere else:

GVRSceneObject parent = sceneObj.getParent(); // get parent of scene object

Parent.removeChildObject(sceneObj); // remove it from the scene

Scene.addSceneObject(sceneObj); // add it somewhere else

Nathipha commented 8 years ago

@liaxim Okay, I created another new project, copied everything from my Eclipse one (java files, res stuff, manifest changes) and the extra files into it, then followed your steps.

There's something wrong with my Android Studio instance, even after the update and also if I start it as admin: For the base project it keeps whining about "Buildtools 24.0.1 requires Java 1.8 or above. Current JDK version is 1.7.", so I changed the JDK location for 1.8. (I currently use 1.7 for my environmental variable), saved the changes and at the end of the next build it whined about the exact same thing again and the settings reset themselves. Now it won't even keep the "SystemUtils.jar" and "VrApi.jar" as dependencies and it still doesn't save the framework (even with your changes to "settings.gradle "). Building, cleaning or "invalidate caches / restart" doesn't change any of it. Plus, it's still missing the "assets" folder, mabye because it's not building correctly, I don't know.

@NolaDonato Ah, I see, that got changed with 3.0.1 then. Before that it just readded the object. Thanks.

liaxim commented 8 years ago

Could you share the build log with us? What do you mean by "save the framework"?

Nathipha commented 8 years ago

Sorry for my late answer.

I re-installed and updated everything (before that, I was stuck in an infinite "Unable to save plugin settings" circle), including the SDK (it's now on the same HDD as the other GearVR stuff and even has the SDK for Nougat), then also started from scratch with a new project and followed your steps again, liaxim. I still got the "Error:Buildtools 24.0.1 requires Java 1.8 or above. Current JDK version is 1.7." message at first but then it finally managed to actually keep the path for JDK 1.8. And - I can't believe what I'm seeing - but it now keeps the two .jar files ("SystemUtils" and "VrApi") and the framework as dependencies (that's what I ment with "save the framework") too.

A build gave me this

Error:(19, 0) NDK integration is deprecated in the current plugin.
<a href="http://tools.android.com/tech-docs/new-build-system/gradle-experimental">Consider trying the new experimental plugin</a><br><a href="useDeprecatedNdk">Set "android.useDeprecatedNdk=true" in gradle.properties to continue using the current NDK integration</a>

but I clicked the last link because I can't update NDK without breaking my Eclipse project.

Regarding the

include ':myapp'
project(':myapp').projectDir=new File('full-path-to-your-apps-module')

part: My settings.gradle file already says "include : 'app'", so should I just use the "project..." part and change it to ":app" or use the real name of my app (with "G:\Dev\Android\workspace\myappname\app")? I hope that that's what you meant, since "G:\Dev\GearVR\GVRf\Framework" or "G:\Dev\GearVR\GVRf\Framework\framework" don't have an "app" folder. Without adding anything to the file (it already says "include ':app', ':framework', ':backend_oculus'" this time around) this is the first time Android Studio at least partially built the project far enough that my code isn't full of "Cannot resolve ..." errors again ("only" for R, android.support.v4.app.ActivityCompat and android.support.v4.content.ContextCompat).

As for the build logs: Event Log:

17:41:21 Executing tasks: [clean, :app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:prepareDebugUnitTestDependencies, :app:mockableAndroidJar, :app:compileDebugSources, :app:compileDebugAndroidTestSources, :app:compileDebugUnitTestSources, :framework:generateDebugSources, :framework:prepareDebugUnitTestDependencies, :framework:mockableAndroidJar, :framework:generateDebugAndroidTestSources, :framework:compileDebugSources, :framework:compileDebugUnitTestSources, :framework:compileDebugAndroidTestSources, :backend_oculus:generateDebugSources, :backend_oculus:prepareDebugUnitTestDependencies, :backend_oculus:mockableAndroidJar, :backend_oculus:generateDebugAndroidTestSources, :backend_oculus:compileDebugSources, :backend_oculus:compileDebugUnitTestSources, :backend_oculus:compileDebugAndroidTestSources]
17:41:23 Gradle build finished with 1 error(s) and 2 warning(s) in 1s 154ms

Gradle Console:

Executing tasks: [clean, :app:generateDebugSources, :app:generateDebugAndroidTestSources, :app:prepareDebugUnitTestDependencies, :app:mockableAndroidJar, :app:compileDebugSources, :app:compileDebugAndroidTestSources, :app:compileDebugUnitTestSources, :framework:generateDebugSources, :framework:prepareDebugUnitTestDependencies, :framework:mockableAndroidJar, :framework:generateDebugAndroidTestSources, :framework:compileDebugSources, :framework:compileDebugUnitTestSources, :framework:compileDebugAndroidTestSources, :backend_oculus:generateDebugSources, :backend_oculus:prepareDebugUnitTestDependencies, :backend_oculus:mockableAndroidJar, :backend_oculus:generateDebugAndroidTestSources, :backend_oculus:compileDebugSources, :backend_oculus:compileDebugUnitTestSources, :backend_oculus:compileDebugAndroidTestSources]

Configuration on demand is an incubating feature.
Incremental java compilation is an incubating feature.
WARNING: not copying Oculus files; OVR_MOBILE_SDK not found
WARNING: relying on hard-coded paths and environment variables; OVR_MOBILE_SDK not found
:clean UP-TO-DATE
:app:clean UP-TO-DATE
:backend_oculus:cleanNative FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':backend_oculus:cleanNative'.
> A problem occurred starting process 'command 'ndk-build.cmd''

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 0.85 secs
liaxim commented 8 years ago

@Nathipha Please add an ANDROID_NDK_HOME property to your gradle.properties file and specify the path to the your NDK installation; https://github.com/Samsung/GearVRf/wiki/Build%20Tips

liaxim commented 8 years ago

@Nathipha I created a pre-release - https://github.com/Samsung/GearVRf/releases/tag/v3.0.2. This has the latest framework. Please update your application to depend on both .aars from the pre-release.

liaxim commented 8 years ago

@Nathipha Where do we stand with this issue?

Nathipha commented 8 years ago

@liaxim Sorry, I didn't find the time for it lately.

Can I replace the files in the "Framework" folder or does Android Studio want special treatment before I can do that?

Please update your application to depend on both .aars from the pre-release.

So simply add them as dependencies - apart from the framework module and the two jar files - too?

My "gradle.properties" file now says (sorry, forgot to readd the OVR path):

android.useDeprecatedNdk=true
OVR_MOBILE_SDK=G:\\Dev\\GearVR\\ovr_sdk_mobile
ANDROID_NDK_HOME=G:\\Dev\\AndroidNDK

Edit: Looks like it didn't like the quotation marks in its path. Now there's a different build error I have to look into.

Edit 2: It builds a lot further now but there's still an error (Gradle Console):

:app:mergeDebugResources
:app:processDebugManifest
G:\Dev\Android\workspace\xxx\app\src\main\AndroidManifest.xml:15:9-43 Error:
    Attribute application@icon value=(@mipmap/ic_launcher) from AndroidManifest.xml:15:9-43
    is also present at [xxx:framework:unspecified] AndroidManifest.xml:35:9-45 value=(@drawable/ic_launcher).
    Suggestion: add 'tools:replace="android:icon"' to <application> element at AndroidManifest.xml:13:5-29:19 to override.

See http://g.co/androidstudio/manifest-merger for more information about the manifest merger.

:app:processDebugManifest FAILED

FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:processDebugManifest'.
> Manifest merger failed : Attribute application@icon value=(@mipmap/ic_launcher) from AndroidManifest.xml:15:9-43
    is also present at [xxx:framework:unspecified] AndroidManifest.xml:35:9-45 value=(@drawable/ic_launcher).
    Suggestion: add 'tools:replace="android:icon"' to <application> element at AndroidManifest.xml:13:5-29:19 to override.

* Try:
Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output.

BUILD FAILED

Total time: 46.15 secs

This happens with both the original manifest file Android Studio created and the latest one that has my changes. The exact error message above was output while using the changed version.

Original:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xxxxx.xxx">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">

        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

Changed:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.xxxxx.xxx">
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="19"
        android:targetSdkVersion="23" />

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <meta-data android:name="com.samsung.android.vr.application.mode" android:value="vr_only"/>
        <!-- If you uncomment "vr_only" above, please put android:screenOrientation="landscape" in activity to run correctly.
        Otherwise you should hold your device on landscape by hand-->
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

I did replace the "ic_launcher.png" files with the other ones from my Eclipse project (I haven't made one for "mipmap-xxxhdpi" yet but left the default one) and put my .jpg textures into the "mipmap-xxhdpi" folder but I don't think that that would cause the error, would it?

liaxim commented 8 years ago

Can I replace the files in the "Framework" folder or does Android Studio want special treatment before I can do that?

Not sure which files you are referring to. Could you please be more specific?

So simply add them as dependencies - apart from the framework module and the two jar files - too?

In your app's build.gradle you will need something like this:

dependencies {
    compile(name: 'framework-debug', ext: 'aar')
    compile(name: 'backend-debug', ext: 'aar')
}

Edit 2: It builds a lot further now but there's still an error (Gradle Console):

Why don't you just add the tools:replace="android:icon" attribute? Like this:

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:replace="android:icon">
NolaDonato commented 7 years ago

Are you still having build problems or can I close this issue?

Nathipha commented 7 years ago

I'm still at the same point I was in September and haven't really had the time or patience to deal with AndroidStudio since then, partially because I was working on a different project. I'm back to working on my original app now and I know that at one point I do have to migrate the whole thing to AndroidStudio. I don't mind opening a new issue just for the build problems and then link back to this thread, so you can either close this one and I'll open a new one once I need it or just leave it open and I'll use it again - I don't mind either way.

thomasflynn commented 7 years ago

@Nathipha, go ahead and open a new one once you need it and we'll help you out at that point.

Nathipha commented 7 years ago

Okay, I will do that.

I have a quick last question regarding TextViewSceneObjects in combination with the EyePicker: I know how to change the background color on entry or exit but is it also possible to give it a border ("padding" inside the object), e.g. white one for a black TextViewSceneObject on a black background? If there's no way to do it directly, I'll look at how to do it with a Drawable myself.

NolaDonato commented 7 years ago

You can do this by putting two border objects as children positioned behind the text view scene object, one black and one white. Add a GVRSwitch component to the text view to allow you to select one of the children to display. Then set the switch index on entry and exit. This will allow you to change the border color when the object is selected.

Nathipha commented 7 years ago

Ah, a GVRSwitch is exactly what I need (in my case: show the border onExit once you press a button on the controller), already found the sample, thanks! Stupid question though, is there a special way to create a border object? I've been using:

GradientDrawable border = new GradientDrawable();
border.setStroke(1, Color.WHITE);
sceneObj.setBackGround(border);

... but if there's a shorter way that doesn't mess with the background color (with my way it always defaults to black), I'd happily take it.

A slight - I don't want to call it a problem - thing I just noticed with my eyepicker: If it enters a TextViewSceneObject (with "new GVRMeshCollider(gvrc, false)") from the right, I always have to go further towards the middle of the object to actually have it picked/change color compared to entering it from the left. It doesn't matter where the objects are (middle of the screen, far left, far right,...) and entering from the top or bottom doesn't seem to make a difference. Is there a way to fix this?

liaxim commented 7 years ago

You could use GVRBitmapTextures for your two border objects. To create a Bitmap with color of your choice you do:

Bitmap bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(color);
NolaDonato commented 7 years ago

I want to look at your issue regarding picking. Can you send me the piece of code where you make your text view scene objects and attach the colliders?

thomasflynn commented 7 years ago

@Nathipha, ping :) Do you have a moment to send your code to @NolaDonato ? thanks.

Nathipha commented 7 years ago

@liaxim Thank you. Is it possible to attach that to a GVRTextViewSceneObject or is it an extra thing?

@thomasflynn I'm sorry that it sometimes takes me a while to answer. This is more like a sideproject and I can't work on it every day. :/

@NolaDonato I'm using a couple of TextViewSceneObjects to let the user pick the background color/enable camera passthrough in an options menu. The ones that are the furthest right are:

GVRTextViewSceneObject hgf4 = new GVRTextViewSceneObject(gvrc, 0.2f, 0.5f, "");
GVRTextViewSceneObject hgf5 = new GVRTextViewSceneObject(gvrc, 0.2f, 0.5f, "");
GVRTextViewSceneObject hgf6 = new GVRTextViewSceneObject(gvrc, 0.2f, 0.5f, "");

hgf4.getTransform().setPosition(0.5f, 0f, -2.0f);
hgf4.setBackgroundColor(Color.LTGRAY);
hgf4.setName("4");
scene.addSceneObject(hgf4);
buttonsoptions.add(hgf4);
hgf4.attachComponent(new GVRMeshCollider(gvrc, false));

hgf5.getTransform().setPosition(0.8f, 0f, -2.0f);
hgf5.setName("5");
scene.addSceneObject(hgf5);
buttonsoptions.add(hgf5);
hgf5.attachComponent(new GVRMeshCollider(gvrc, false));

hgf6.getTransform().setPosition(1.1f, 0f, -2.0f);
hgf6.setBackgroundColor(Color.GREEN);
hgf6.setName("6");
scene.addSceneObject(hgf6);
buttonsoptions.add(hgf6);
hgf6.attachComponent(new GVRMeshCollider(gvrc, false));

The same thing also happens with bigger buttons:

GVRTextViewSceneObject m1 = new GVRTextViewSceneObject(gvrc, 1f, 0.5f, "Normal");
m1.getTransform().setPosition(0.0f, 0.65f, -2.0f);
m1.setGravity(Gravity.CENTER | Gravity.CENTER);
m1.setTextSize(5);
m1.setBackgroundColor(Color.GRAY);
scene.addSceneObject(m1);
buttonsoptions.add(m1);
m1.attachComponent(new GVRMeshCollider(gvrc, false));

OnEnter sets the background color to magenta, onExit changes it back to the original color (depending on the name) but I want to change the whole thing to work with GVRSwitches.

liaxim commented 7 years ago

@Nathipha You can put the two border scene objects in a GVRSwitch. Then have the GVRTextViewSceneObject and the GVRSwitch share the same parent. But if you really wanted to, you can add the GVRSwitch to the GVRTextViewSceneObject and make that work too.

thomasflynn commented 7 years ago

@NolaDonato i'm primarily concerned with whether there is a framework bug in here somewhere. @Nathipha had a comment earlier saying,

"If it enters a TextViewSceneObject (with "new GVRMeshCollider(gvrc, false)") from the right, I always have to go further towards the middle of the object to actually have it picked/change color compared to entering it from the left. It doesn't matter where the objects are (middle of the screen, far left, far right,...) and entering from the top or bottom doesn't seem to make a difference. Is there a way to fix this?"

Is there a bug here? If so, what is it? Once I understand that, I can make an informed decision as to whether to keep this on the 3.2 blocker list.

Nathipha commented 7 years ago

@liaxim I was thinking about creating 3 child objects for each of my GVRTextViewSceneObjects/roots, one for the different color for onEnter of my picker, 1 with a border for an enabled option and one without border. The question is now: I have 10 buttons, will creating a single GVRSwitch with 3 child objects for each of them be slower or faster than manually adding/deleting a border object or changing the background color or does it simply not matter with that amount of buttons?

@NolaDonato Does this happen in 3.1 too? Possible that it's just a bug with 3.0.1 and if so, I can live with it. Unfortunately there's another bug I've noticed since 2.x (so basically since I started using the framework) but haven't paid too close attention to but while we're at it: Sometimes it doesn't load GVRTextViewSceneObjects properly, they have a black background and the font size is huge, so the text gets cut off. This only seems to happen if a picker is active, at least I've never had it happen while displaying an error message.

The bug: http://i.imgur.com/GhIPJ8b.png?1

What it should look like (I can easily reset the button through my onExit method): http://i.imgur.com/z3mFjIM.png?1

NolaDonato commented 7 years ago

Without knowing what colliders are being used I cannot tell. I will try to make a sample with sphere colliders to try and reproduce it.

NolaDonato commented 7 years ago

I wrote independent picking tests to verify that on the current master branch it does not trigger onEnter at a different place on the right than on the left. The point where onEnter is triggered is compatible for sphere and mesh colliders. The tests are in PR #74 in GearVRF-Tests.

liaxim commented 7 years ago

@Nathipha I think both options would work reasonably well. I'd say get it to work first and if you notice performance issues, we will help out.

liaxim commented 7 years ago

What we could do is use 3.0.1 to recreate @Nathipha's issue. If we do that we can determine is it fixed and why in master. This is what I will attempt since our release is waiting on this particular issue.

@Nathipha Please open new issues for other problems you encounter.