diff --git a/build.gradle b/build.gradle index 084f33e..a0ef9ee 100644 --- a/build.gradle +++ b/build.gradle @@ -7,15 +7,12 @@ buildscript { mavenCentral() } dependencies { - classpath 'com.android.tools.build:gradle:2.2.0-alpha6' + classpath 'com.android.tools.build:gradle:2.2.2' classpath 'com.google.gms:google-services:3.0.0' // Retrolambda Support - classpath 'me.tatarka:gradle-retrolambda:3.2.5' - classpath 'me.tatarka.retrolambda.projectlombok:lombok.ast:0.2.3.a2' + classpath 'me.tatarka:gradle-retrolambda:3.3.0' - // Better Dagger Support - classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' } } @@ -31,27 +28,3 @@ allprojects { task clean(type: Delete) { delete rootProject.buildDir } - -ext { - // version numbers for dependencies // source for most recent release - supportLibraryVersion = '24.0.0' // See standalone SDK manager - guavaVersion = '19.0' // https://github.com/google/guava/releases - - commonsIOVersion = '2.5' // https://commons.apache.org/proper/commons-io/ - commonsLangVersion = '3.4' // https://commons.apache.org/proper/commons-lang/ - - daggerVersion = '2.5' // https://github.com/google/dagger/blob/master/CHANGELOG.md - okhttpVersion = '3.3.1' // https://github.com/square/okhttp/blob/master/CHANGELOG.md - retrofitVersion='2.1.0' // https://github.com/square/retrofit/blob/master/CHANGELOG.md - picassoVersion='2.5.2' // https://github.com/square/picasso/blob/master/CHANGELOG.md - picassoOkHttpDownloaderVersion = '1.0.2' // https://github.com/JakeWharton/picasso2-okhttp3-downloader/blob/master/CHANGELOG.md - butterKnifeVersion='8.1.0' // https://github.com/JakeWharton/butterknife/blob/master/CHANGELOG.md - - autoValueVersion='1.2' // https://github.com/google/auto - autoValueGsonVersion='0.3.1' // https://github.com/rharter/auto-value-gson/blob/master/CHANGELOG.md - - rxJavaVersion='1.1.6' // https://github.com/ReactiveX/RxJava/blob/1.x/CHANGES.md - rxAndroidVersion='1.2.1' // https://github.com/ReactiveX/RxAndroid/blob/master/CHANGES.md - rxBindingVersion='0.4.0' // https://github.com/JakeWharton/RxBinding/blob/master/CHANGELOG.md - -} diff --git a/commonLib/build.gradle b/commonLib/build.gradle index 23f7e87..94ccffb 100644 --- a/commonLib/build.gradle +++ b/commonLib/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'me.tatarka.retrolambda' android { compileSdkVersion 24 - buildToolsVersion "24.0.0 rc4" + buildToolsVersion "24.0.2" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -22,32 +22,44 @@ android { } } +final SUPPORT_LIB_VERSION = '24.2.1' // https://developer.android.com/topic/libraries/support-library/revisions.html +final FIREBASE_VERSION = '9.6.1' // https://firebase.google.com/support/release-notes/android +final PLAY_SERVICES_VERSION = '9.6.1' // https://developers.google.com/android/guides/releases + dependencies { // NOTE: commonLib dependencies are for 'framework' type dependencies I always want in my projects. + // Google Framework Dependencies + compile "com.android.support:support-v13:${SUPPORT_LIB_VERSION}" + compile "com.android.support:appcompat-v7:${SUPPORT_LIB_VERSION}" // Timber Logging API: Better method signatures, easy log-level-by-flavor management, decent lint checks, etc. // https://github.com/JakeWharton/timber - compile 'com.jakewharton.timber:timber:4.1.2' + compile "com.jakewharton.timber:timber:4.3.0" // https://github.com/JakeWharton/timber/blob/master/CHANGELOG.md + + // RxJava 2 for your declarative programming needs + compile "io.reactivex.rxjava2:rxjava:2.0.0-RC4" // https://github.com/ReactiveX/RxJava/blob/2.x/CHANGES.md + compile 'io.reactivex.rxjava2:rxandroid:2.0.0-RC1' // https://github.com/ReactiveX/RxAndroid/blob/2.x/CHANGES.md // RxJava - compile "io.reactivex:rxjava:$project.rxJavaVersion" - // Android Extensions - https://github.com/ReactiveX/RxAndroid/wiki - compile "io.reactivex:rxandroid:$project.rxAndroidVersion" +/* + compile "io.reactivex:rxjava:1.1.9" // https://github.com/ReactiveX/RxJava/blob/1.x/CHANGES.md + compile "io.reactivex:rxandroid:1.2.1" // https://github.com/ReactiveX/RxAndroid/blob/1.x/CHANGES.md compile "com.jakewharton.rxrelay:rxrelay:1.1.0" // https://github.com/JakeWharton/RxRelay/blob/master/CHANGELOG.md - compile "com.jakewharton.rxbinding:rxbinding:$project.rxBindingVersion" - compile "com.jakewharton.rxbinding:rxbinding-support-v4:$project.rxBindingVersion" - compile "com.jakewharton.rxbinding:rxbinding-appcompat-v7:$project.rxBindingVersion" - compile 'com.jakewharton.rxbinding:rxbinding-design:0.4.0' - compile 'com.jakewharton.rxbinding:rxbinding-recyclerview-v7:0.4.0' + compile "com.jakewharton.rxbinding:rxbinding:0.4.0" // https://github.com/JakeWharton/RxBinding/blob/master/CHANGELOG.md + compile "com.jakewharton.rxbinding:rxbinding-support-v4:0.4.0" + compile "com.jakewharton.rxbinding:rxbinding-appcompat-v7:0.4.0" + compile "com.jakewharton.rxbinding:rxbinding-design:0.4.0" + compile "com.jakewharton.rxbinding:rxbinding-recyclerview-v7:0.4.0" +*/ // Square Networking - compile "com.squareup.okhttp3:okhttp:$project.okhttpVersion" - compile "com.squareup.okhttp3:logging-interceptor:$project.okhttpVersion" - compile "com.squareup.okhttp3:okhttp-urlconnection:$project.okhttpVersion" - compile "com.squareup.picasso:picasso:$project.picassoVersion" - compile "com.jakewharton.picasso:picasso2-okhttp3-downloader:$project.picassoOkHttpDownloaderVersion" - compile "com.squareup.retrofit2:retrofit:$project.retrofitVersion" - compile "com.squareup.retrofit2:adapter-rxjava:$project.retrofitVersion" - compile "com.squareup.retrofit2:converter-gson:$project.retrofitVersion" + compile "com.squareup.okhttp3:okhttp:3.4.1" // https://github.com/square/okhttp/blob/master/CHANGELOG.md + compile "com.squareup.okhttp3:okhttp-urlconnection:3.4.1" + debugCompile "com.squareup.okhttp3:logging-interceptor:3.4.1" + compile "com.squareup.retrofit2:retrofit:2.1.0" // https://github.com/square/retrofit/blob/master/CHANGELOG.md + compile "com.squareup.retrofit2:converter-gson:2.1.0" + compile "com.jakewharton.retrofit:retrofit2-rxjava2-adapter:1.0.0-RC3" // https://github.com/JakeWharton/retrofit2-rxjava2-adapter/blob/master/CHANGELOG.md + compile "com.squareup.picasso:picasso:2.5.2" // https://github.com/square/picasso/blob/master/CHANGELOG.md + compile "com.jakewharton.picasso:picasso2-okhttp3-downloader:1.0.2" // https://github.com/JakeWharton/picasso2-okhttp3-downloader/blob/master/CHANGELOG.md } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 122a0dc..d8c44cd 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Mon Dec 28 10:00:20 PST 2015 +#Tue Aug 02 17:34:15 EDT 2016 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip diff --git a/rajaDemo/build.gradle b/rajaDemo/build.gradle index 79781bd..aca7d2b 100644 --- a/rajaDemo/build.gradle +++ b/rajaDemo/build.gradle @@ -1,10 +1,9 @@ apply plugin: 'com.android.application' -apply plugin: 'com.neenbedankt.android-apt' apply plugin: 'me.tatarka.retrolambda' android { compileSdkVersion 24 - buildToolsVersion "24.0.0 rc4" + buildToolsVersion "24.0.2" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -36,6 +35,10 @@ android { dependencies { compile project(':commonLib') + annotationProcessor "com.github.stephanenicolas.toothpick:toothpick-compiler:1.0.0" // https://github.com/stephanenicolas/toothpick/blob/master/CHANGELOG.md + compile "com.github.stephanenicolas.toothpick:toothpick-runtime:1.0.0" + compile "com.github.stephanenicolas.toothpick:smoothie:1.0.0" + // compile 'org.rajawali3d:rajawali:1.0.325@aar' // Latest version of Rajawali diff --git a/rajaDemo/src/main/java/com/kanawish/raja/BaselineRenderer.java b/rajaDemo/src/main/java/com/kanawish/raja/BaselineRenderer.java new file mode 100644 index 0000000..d28fabe --- /dev/null +++ b/rajaDemo/src/main/java/com/kanawish/raja/BaselineRenderer.java @@ -0,0 +1,34 @@ +package com.kanawish.raja; + +import android.content.Context; +import android.support.annotation.Nullable; +import android.view.MotionEvent; + +import org.rajawali3d.renderer.Renderer; + +import javax.microedition.khronos.egl.EGLConfig; +import javax.microedition.khronos.opengles.GL10; + +abstract class BaselineRenderer extends Renderer { + + final BaselineRenderingFragment exampleFragment; + + public BaselineRenderer(Context context, @Nullable BaselineRenderingFragment fragment) { + super(context); + exampleFragment = fragment; + } + + @Override + public void onRenderSurfaceCreated(EGLConfig config, GL10 gl, int width, int height) { + super.onRenderSurfaceCreated(config, gl, width, height); + } + + @Override + public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { + } + + @Override + public void onTouchEvent(MotionEvent event) { + } + + } diff --git a/rajaDemo/src/main/java/com/kanawish/raja/BaselineRenderingFragment.java b/rajaDemo/src/main/java/com/kanawish/raja/BaselineRenderingFragment.java index 38f00c1..e03967d 100644 --- a/rajaDemo/src/main/java/com/kanawish/raja/BaselineRenderingFragment.java +++ b/rajaDemo/src/main/java/com/kanawish/raja/BaselineRenderingFragment.java @@ -72,28 +72,5 @@ public void onDestroyView() { layout.removeView((View) surface); } - protected static abstract class BaselineRenderer extends Renderer { - - final BaselineRenderingFragment exampleFragment; - - public BaselineRenderer(Context context, @Nullable BaselineRenderingFragment fragment) { - super(context); - exampleFragment = fragment; - } - - @Override - public void onRenderSurfaceCreated(EGLConfig config, GL10 gl, int width, int height) { - super.onRenderSurfaceCreated(config, gl, width, height); - } - - @Override - public void onOffsetsChanged(float xOffset, float yOffset, float xOffsetStep, float yOffsetStep, int xPixelOffset, int yPixelOffset) { - } - - @Override - public void onTouchEvent(MotionEvent event) { - } - - } } \ No newline at end of file diff --git a/rajaDemo/src/main/java/com/kanawish/raja/DemoFragment.java b/rajaDemo/src/main/java/com/kanawish/raja/DemoFragment.java index 8c38573..64f816b 100644 --- a/rajaDemo/src/main/java/com/kanawish/raja/DemoFragment.java +++ b/rajaDemo/src/main/java/com/kanawish/raja/DemoFragment.java @@ -1,39 +1,14 @@ package com.kanawish.raja; -import android.content.Context; import android.os.Bundle; -import android.support.annotation.NonNull; -import android.support.annotation.Nullable; import android.view.Gravity; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.LinearLayout; -import com.kanawish.raja.rajademo.R; - -import org.rajawali3d.Object3D; -import org.rajawali3d.animation.Animation; -import org.rajawali3d.animation.Animation3D; -import org.rajawali3d.animation.RotateOnAxisAnimation; -import org.rajawali3d.lights.DirectionalLight; -import org.rajawali3d.loader.LoaderOBJ; -import org.rajawali3d.loader.ParsingException; -import org.rajawali3d.materials.Material; -import org.rajawali3d.materials.methods.DiffuseMethod; -import org.rajawali3d.materials.methods.SpecularMethod; -import org.rajawali3d.materials.plugins.FogMaterialPlugin; -import org.rajawali3d.materials.textures.ATexture; -import org.rajawali3d.materials.textures.Texture; -import org.rajawali3d.math.vector.Vector3; -import org.rajawali3d.postprocessing.PostProcessingManager; -import org.rajawali3d.postprocessing.effects.BloomEffect; -import org.rajawali3d.postprocessing.passes.BlendPass; - public class DemoFragment extends BaselineRenderingFragment { - private PostProcessingManager effectsManager; - @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { super.onCreateView(inflater, container, savedInstanceState); @@ -50,139 +25,11 @@ public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle sa @Override public BaselineRenderer createRenderer() { - return new FBXRenderer(getActivity(), this); + // NOTE: If you build your own renderer, simply switch them in here. + return new SimpleRenderer(getActivity(), this); } public static DemoFragment buildInstance() { return new DemoFragment(); } - - private final class FBXRenderer extends BaselineRenderer { - - public FBXRenderer(Context context, @Nullable BaselineRenderingFragment fragment) { - super(context, fragment); - } - - @Override - protected void initScene() { - - // Add overall light to our scene. Directional behaves like sunlight. - DirectionalLight light = buildDirectionalLight(); - getCurrentScene().addLight(light); - - // For skybox below. - getCurrentCamera().setFarPlane(1000); - - // Skybox images by Emil Persson, aka Humus. http://www.humus.name humus@comhem.se - try { - getCurrentScene().setSkybox(R.drawable.posx, R.drawable.negx, - R.drawable.posy, R.drawable.negy, R.drawable.posz, R.drawable.negz); - } catch (ATexture.TextureException e) { - e.printStackTrace(); - } - - getCurrentScene().addChild(buildLandscape()); - - getCurrentCamera().setPosition(0,2,8); - getCurrentCamera().setLookAt(0,1,-40); - - getCurrentScene().setFog(new FogMaterialPlugin.FogParams(FogMaterialPlugin.FogType.LINEAR, 0xCCCCCC, 1, 150)); - - Material planeMaterial = new Material(); - planeMaterial.enableLighting(true); - planeMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); - - Material sphereMaterial = new Material(); - sphereMaterial.enableLighting(true); - sphereMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); - - // - // -- Create a post processing manager. We can add multiple passes to this. - // - - effectsManager = new PostProcessingManager(this); - - BloomEffect bloomEffect = new BloomEffect( - getCurrentScene(), getCurrentCamera(), getViewportWidth(), - getViewportHeight(), 0x111111, 0xffffff, BlendPass.BlendMode.SCREEN); - effectsManager.addEffect(bloomEffect); - bloomEffect.setRenderToScreen(true); - - } - - public void onRender(final long elapsedTime, final double deltaTime) { - effectsManager.render(elapsedTime, deltaTime); - } - - private Object3D buildLandscape() { - LoaderOBJ objParser = new LoaderOBJ(mContext.getResources(), mTextureManager, R.raw.minecart_scene_obj); - try { - objParser.parse(); - } catch (ParsingException e) { - e.printStackTrace(); - } - - Object3D o = objParser.getParsedObject(); - return o; - } - - private Object3D buildTree() { - LoaderOBJ objParser = new LoaderOBJ(mContext.getResources(), mTextureManager, R.raw.small_tree_color_obj); - try { - objParser.parse(); - } catch (ParsingException e) { - e.printStackTrace(); - } - - Object3D o = objParser.getParsedObject(); - o.setPosition(0,0,0); - - Animation3D anim = new RotateOnAxisAnimation(Vector3.Axis.Y, 360); - anim.setDurationMilliseconds(16000); - anim.setRepeatMode(Animation.RepeatMode.INFINITE); - anim.setTransformable3D(o); - getCurrentScene().registerAnimation(anim); - anim.play(); - - return o; - } - - @NonNull - private DirectionalLight buildDirectionalLight() { - final DirectionalLight directionalLight = new DirectionalLight(); - directionalLight.setPosition(0.20, 5.0, 0.6); - directionalLight.setPower(0.95f); - directionalLight.setLookAt(Vector3.ZERO); - directionalLight.enableLookAt(); - return directionalLight; - } - - @NonNull - private Material buildMaterial(int color) { - Material material = new Material(); - material.enableLighting(true); - material.setColor(color); - material.setDiffuseMethod(new DiffuseMethod.Lambert()); - return material; - } - - private Material buildTextureMaterial(int color) { - Material material = new Material(); - Texture texture = new Texture("earthColors", - R.drawable.earthtruecolor_nasa_big); - material.enableLighting(true); - material.setDiffuseMethod(new DiffuseMethod.Lambert()); - material.setSpecularMethod(new SpecularMethod.Phong()); - - try { - material.addTexture(texture); - } catch (ATexture.TextureException e) { - e.printStackTrace(); - } - material.setColorInfluence(0); - texture.setInfluence(1.0f); - - return material; - } - } } \ No newline at end of file diff --git a/rajaDemo/src/main/java/com/kanawish/raja/DemoRenderer.java b/rajaDemo/src/main/java/com/kanawish/raja/DemoRenderer.java new file mode 100644 index 0000000..6c001a1 --- /dev/null +++ b/rajaDemo/src/main/java/com/kanawish/raja/DemoRenderer.java @@ -0,0 +1,158 @@ +package com.kanawish.raja; + +import android.content.Context; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.kanawish.raja.rajademo.R; + +import org.rajawali3d.Object3D; +import org.rajawali3d.animation.Animation; +import org.rajawali3d.animation.Animation3D; +import org.rajawali3d.animation.RotateOnAxisAnimation; +import org.rajawali3d.lights.DirectionalLight; +import org.rajawali3d.loader.LoaderOBJ; +import org.rajawali3d.loader.ParsingException; +import org.rajawali3d.materials.Material; +import org.rajawali3d.materials.methods.DiffuseMethod; +import org.rajawali3d.materials.methods.SpecularMethod; +import org.rajawali3d.materials.plugins.FogMaterialPlugin; +import org.rajawali3d.materials.textures.ATexture; +import org.rajawali3d.materials.textures.Texture; +import org.rajawali3d.math.vector.Vector3; +import org.rajawali3d.postprocessing.PostProcessingManager; +import org.rajawali3d.postprocessing.effects.BloomEffect; +import org.rajawali3d.postprocessing.passes.BlendPass; + +/** + * Created by kanawish on 2016-08-03. + */ +final class DemoRenderer extends BaselineRenderer { + + private PostProcessingManager effectsManager; + + public DemoRenderer(Context context, @Nullable BaselineRenderingFragment fragment) { + super(context, fragment); + } + + @Override + protected void initScene() { + + // Add overall light to our scene. Directional behaves like sunlight. + DirectionalLight light = buildDirectionalLight(); + getCurrentScene().addLight(light); + + // For skybox below. + getCurrentCamera().setFarPlane(1000); + + // Skybox images by Emil Persson, aka Humus. http://www.humus.name humus@comhem.se + try { + getCurrentScene().setSkybox(R.drawable.posx, R.drawable.negx, + R.drawable.posy, R.drawable.negy, R.drawable.posz, R.drawable.negz); + } catch (ATexture.TextureException e) { + e.printStackTrace(); + } + + getCurrentScene().addChild(buildLandscape()); + + getCurrentCamera().setPosition(0, 2, 8); + getCurrentCamera().setLookAt(0, 1, -40); + + getCurrentScene().setFog(new FogMaterialPlugin.FogParams(FogMaterialPlugin.FogType.LINEAR, 0xCCCCCC, 1, 150)); + + Material planeMaterial = new Material(); + planeMaterial.enableLighting(true); + planeMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); + + Material sphereMaterial = new Material(); + sphereMaterial.enableLighting(true); + sphereMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); + + // + // -- Create a post processing manager. We can add multiple passes to this. + // + + effectsManager = new PostProcessingManager(this); + + BloomEffect bloomEffect = new BloomEffect( + getCurrentScene(), getCurrentCamera(), getViewportWidth(), + getViewportHeight(), 0x111111, 0xffffff, BlendPass.BlendMode.SCREEN); + effectsManager.addEffect(bloomEffect); + bloomEffect.setRenderToScreen(true); + } + + public void onRender(final long elapsedTime, final double deltaTime) { + effectsManager.render(elapsedTime, deltaTime); + } + + private Object3D buildLandscape() { + LoaderOBJ objParser = new LoaderOBJ(mContext.getResources(), mTextureManager, R.raw.minecart_scene_obj); + try { + objParser.parse(); + } catch (ParsingException e) { + e.printStackTrace(); + } + + Object3D o = objParser.getParsedObject(); + return o; + } + + private Object3D buildTree() { + LoaderOBJ objParser = new LoaderOBJ(mContext.getResources(), mTextureManager, R.raw.small_tree_color_obj); + try { + objParser.parse(); + } catch (ParsingException e) { + e.printStackTrace(); + } + + Object3D o = objParser.getParsedObject(); + o.setPosition(0, 0, 0); + + Animation3D anim = new RotateOnAxisAnimation(Vector3.Axis.Y, 360); + anim.setDurationMilliseconds(16000); + anim.setRepeatMode(Animation.RepeatMode.INFINITE); + anim.setTransformable3D(o); + getCurrentScene().registerAnimation(anim); + anim.play(); + + return o; + } + + @NonNull + private DirectionalLight buildDirectionalLight() { + final DirectionalLight directionalLight = new DirectionalLight(); + directionalLight.setPosition(0.20, 5.0, 0.6); + directionalLight.setPower(0.95f); + directionalLight.setLookAt(Vector3.ZERO); + directionalLight.enableLookAt(); + return directionalLight; + } + + @NonNull + private Material buildMaterial(int color) { + Material material = new Material(); + material.enableLighting(true); + material.setColor(color); + material.setDiffuseMethod(new DiffuseMethod.Lambert()); + return material; + } + + private Material buildTextureMaterial(int color) { + Material material = new Material(); + Texture texture = new Texture("earthColors", + R.drawable.earthtruecolor_nasa_big); + material.enableLighting(true); + material.setDiffuseMethod(new DiffuseMethod.Lambert()); + material.setSpecularMethod(new SpecularMethod.Phong()); + + try { + material.addTexture(texture); + } catch (ATexture.TextureException e) { + e.printStackTrace(); + } + material.setColorInfluence(0); + texture.setInfluence(1.0f); + + return material; + } +} diff --git a/rajaDemo/src/main/java/com/kanawish/raja/ShadowMappingRenderer.java b/rajaDemo/src/main/java/com/kanawish/raja/ShadowMappingRenderer.java new file mode 100644 index 0000000..5a4bd16 --- /dev/null +++ b/rajaDemo/src/main/java/com/kanawish/raja/ShadowMappingRenderer.java @@ -0,0 +1,153 @@ +package com.kanawish.raja; + +import android.content.Context; +import android.graphics.Color; +import android.support.annotation.Nullable; + +import org.rajawali3d.ATransformable3D; +import org.rajawali3d.animation.Animation; +import org.rajawali3d.animation.EllipticalOrbitAnimation3D; +import org.rajawali3d.animation.RotateOnAxisAnimation; +import org.rajawali3d.lights.DirectionalLight; +import org.rajawali3d.lights.PointLight; +import org.rajawali3d.materials.Material; +import org.rajawali3d.materials.methods.DiffuseMethod; +import org.rajawali3d.math.vector.Vector3; +import org.rajawali3d.postprocessing.PostProcessingManager; +import org.rajawali3d.postprocessing.effects.ShadowEffect; +import org.rajawali3d.primitives.Cube; +import org.rajawali3d.primitives.Plane; +import org.rajawali3d.primitives.Sphere; + +public class ShadowMappingRenderer extends BaselineRenderer { + + private PostProcessingManager mPostProcessingManager; + + public ShadowMappingRenderer(Context context, @Nullable BaselineRenderingFragment fragment) { + super(context, fragment); + } + + @Override + protected void initScene() { + try { + getCurrentScene().setBackgroundColor(Color.BLUE); + + DirectionalLight key = new DirectionalLight(0,-2,0); + key.setPosition(0,2,0.1); +// key.setLookAt(0,-2,0); + key.enableLookAt(); + key.setPower(4); + getCurrentScene().addLight(key); + + Material material = new Material(); + material.setDiffuseMethod(new DiffuseMethod.Lambert()); + material.enableLighting(true); + Cube cube = new Cube(1); + cube.setMaterial(material); + getCurrentScene().addChild(cube); + + RotateOnAxisAnimation anim = new RotateOnAxisAnimation(new Vector3(1,1,1), 360); + anim.setTransformable3D(cube); + anim.setDurationMilliseconds(20000); + anim.setRepeatMode(Animation.RepeatMode.INFINITE); + getCurrentScene().registerAnimation(anim); + anim.play(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + public void initScene2() { + Vector3 focalPoint = new Vector3(0,7,0); + + DirectionalLight mLight; + mLight = new DirectionalLight(); + mLight.setPosition(0.0, 1.0, 0.01f); + mLight.setPower(0.95f); + mLight.setLookAt(Vector3.ZERO); + mLight.enableLookAt(); + getCurrentScene().addLight(mLight); + + Material lightMaterial = new Material(); + lightMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); + + // Build a Sphere + Sphere sphere = new Sphere(0.55f,20,20); + sphere.setMaterial(lightMaterial); + sphere.setColor(Color.YELLOW); + sphere.setPosition(mLight.getPosition()); + sphere.setVisible(true); + +// animate(focalPoint, mLight); +// getCurrentScene().addLight(mLight); +// +// animate(focalPoint, sphere); +// getCurrentScene().addChild(sphere); + + getCurrentCamera().setFarPlane(50); + getCurrentCamera().setPosition(0, 7, 15); + getCurrentCamera().setLookAt(0, 0, 0); + getCurrentCamera().enableLookAt(); + + Material planeMaterial = new Material(); + planeMaterial.enableLighting(true); + planeMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); + + Plane plane = new Plane(Vector3.Axis.Y); + plane.setScale(7.5); + plane.setMaterial(planeMaterial); + plane.setColor(Color.GREEN); + getCurrentScene().addChild(plane); + + Material regCubeMaterial = new Material(); + regCubeMaterial.enableLighting(true); + regCubeMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); + + for (int z = 0; z < 10; z++) { + for (int x = 0; x < 10; x++) { + Cube cube = new Cube(.7f); + cube.setMaterial(regCubeMaterial); + cube.setColor(Color.rgb(100 + 10 * x, 0, 0)); + cube.setPosition(-4.5f + x, 5, -4.5f + z); + + getCurrentScene().addChild(cube); + } + } + + Material cubeMaterial = new Material(); + cubeMaterial.enableLighting(true); + cubeMaterial.setDiffuseMethod(new DiffuseMethod.Lambert()); + + Cube cube = new Cube(2); + cube.setMaterial(cubeMaterial); + cube.setColor(Color.GRAY); + cube.setY(1.5f); + getCurrentScene().addChild(cube); + + +/* + mPostProcessingManager = new PostProcessingManager(this); + ShadowEffect shadowEffect = new ShadowEffect(getCurrentScene(), getCurrentCamera(), mLight, 2048); + shadowEffect.setShadowInfluence(2.5f); + mPostProcessingManager.addEffect(shadowEffect); + shadowEffect.setRenderToScreen(true); +*/ + } + + private void animate(Vector3 focalPoint, ATransformable3D transformable3D) { + EllipticalOrbitAnimation3D lightAnim = new EllipticalOrbitAnimation3D( + focalPoint, new Vector3(0, 12, 5), 0, 360, + EllipticalOrbitAnimation3D.OrbitDirection.CLOCKWISE); + lightAnim.setDurationMilliseconds(20000); + lightAnim.setRepeatMode(Animation.RepeatMode.INFINITE); + lightAnim.setTransformable3D(transformable3D); + getCurrentScene().registerAnimation(lightAnim); + lightAnim.play(); + } + + @Override + public void onRender(final long ellapsedTime, final double deltaTime) { + super.onRender(ellapsedTime, deltaTime); +// mPostProcessingManager.render(ellapsedTime, deltaTime); + } +} diff --git a/rajaDemo/src/main/java/com/kanawish/raja/SimpleRenderer.java b/rajaDemo/src/main/java/com/kanawish/raja/SimpleRenderer.java new file mode 100644 index 0000000..22bfa37 --- /dev/null +++ b/rajaDemo/src/main/java/com/kanawish/raja/SimpleRenderer.java @@ -0,0 +1,96 @@ +package com.kanawish.raja; + +import android.content.Context; +import android.graphics.Color; +import android.support.annotation.Nullable; + +import com.kanawish.raja.rajademo.R; + +import org.rajawali3d.ATransformable3D; +import org.rajawali3d.animation.Animation; +import org.rajawali3d.animation.EllipticalOrbitAnimation3D; +import org.rajawali3d.animation.RotateOnAxisAnimation; +import org.rajawali3d.lights.DirectionalLight; +import org.rajawali3d.materials.Material; +import org.rajawali3d.materials.methods.DiffuseMethod; +import org.rajawali3d.materials.textures.ATexture; +import org.rajawali3d.math.vector.Vector3; +import org.rajawali3d.primitives.Cube; +import org.rajawali3d.primitives.Sphere; + +class SimpleRenderer extends BaselineRenderer { + + SimpleRenderer(Context context, @Nullable BaselineRenderingFragment fragment) { + super(context, fragment); + } + + @Override + protected void initScene() { + try { + getCurrentScene().setBackgroundColor(Color.BLUE); + + getCurrentCamera().setFarPlane(1000); + + // Skybox images by Emil Persson, aka Humus. http://www.humus.name humus@comhem.se + try { + getCurrentScene().setSkybox(R.drawable.posx, R.drawable.negx, + R.drawable.posy, R.drawable.negy, R.drawable.posz, R.drawable.negz); + } catch (ATexture.TextureException e) { + e.printStackTrace(); + } + + // Lights, + DirectionalLight key = new DirectionalLight(0,0.1,0.2); + key.setPosition(0.0,10.0,2.5); + key.enableLookAt(); + key.setPower(2); + getCurrentScene().addLight(key); + + // Models + Material material = new Material(); + material.setDiffuseMethod(new DiffuseMethod.Lambert()); + material.setColor(0xffff0000); + material.setColorInfluence(1); + material.enableLighting(true); + Cube cube = new Cube(1); + cube.setMaterial(material); + getCurrentScene().addChild(cube); + + Sphere sphere = new Sphere(0.5f,10,10); + sphere.setMaterial(material); + getCurrentScene().addChild(sphere); + animateOrbit(new Vector3(0),sphere); + + // Camera, + getCurrentCamera().setPosition(0, 5, 4); + getCurrentCamera().setLookAt(0.0, 0.0, -0.1); + + // Action! + RotateOnAxisAnimation anim = new RotateOnAxisAnimation(new Vector3(1,1,1), 360); + anim.setTransformable3D(cube); + anim.setDurationMilliseconds(20000); + anim.setRepeatMode(Animation.RepeatMode.INFINITE); + getCurrentScene().registerAnimation(anim); +// anim.play(); + + } catch (Exception e) { + e.printStackTrace(); + } + } + + private void animateOrbit(Vector3 focalPoint, ATransformable3D transformable3D) { + EllipticalOrbitAnimation3D lightAnim = new EllipticalOrbitAnimation3D( + new Vector3(1,0,0), new Vector3(3, 0, 0), Vector3.getAxisVector(Vector3.Axis.Y), 0, 360, + EllipticalOrbitAnimation3D.OrbitDirection.CLOCKWISE); + lightAnim.setDurationMilliseconds(2000); + lightAnim.setRepeatMode(Animation.RepeatMode.INFINITE); + lightAnim.setTransformable3D(transformable3D); + getCurrentScene().registerAnimation(lightAnim); + lightAnim.play(); + } + + @Override + public void onRender(final long ellapsedTime, final double deltaTime) { + super.onRender(ellapsedTime, deltaTime); + } +} diff --git a/rajaTangoLib/build.gradle b/rajaTangoLib/build.gradle index 3722dfd..f776735 100644 --- a/rajaTangoLib/build.gradle +++ b/rajaTangoLib/build.gradle @@ -3,7 +3,7 @@ apply plugin: 'me.tatarka.retrolambda' android { compileSdkVersion 24 - buildToolsVersion "24.0.0 rc4" + buildToolsVersion "24.0.2" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -33,13 +33,13 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: external_lib_prefix + '/jar', include: ['**/*.jar']) - compile (name: 'TangoSupport_Qianru_Java', ext: 'aar') + compile (name: 'tango_support_java_lib', ext: 'aar') compile project(':commonLib') // NOTE: Latest Rajawali lib version introduces issues in the sample code, we use an older one for now. - compile 'org.rajawali3d:rajawali:1.0.325@aar' -// compile 'org.rajawali3d:rajawali:1.1.517-SNAPSHOT@aar' +// compile 'org.rajawali3d:rajawali:1.0.325@aar' + compile 'org.rajawali3d:rajawali:1.1.517-SNAPSHOT@aar' } diff --git a/rajaVrDemo/build.gradle b/rajaVrDemo/build.gradle index 67d163e..876bcc5 100644 --- a/rajaVrDemo/build.gradle +++ b/rajaVrDemo/build.gradle @@ -1,34 +1,17 @@ -/* - * Copyright 2015 Google Inc. 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. - */ apply plugin: 'com.android.application' -apply plugin: 'com.neenbedankt.android-apt' apply plugin: 'me.tatarka.retrolambda' android { - compileSdkVersion 24 - buildToolsVersion "24.0.0 rc4" + compileSdkVersion 25 + buildToolsVersion "25.0.0" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } - defaultConfig { applicationId "com.kanawish.raja.vr" minSdkVersion 19 - targetSdkVersion 24 + targetSdkVersion 25 versionCode 1 versionName "1.0" } @@ -54,7 +37,10 @@ dependencies { compile project(':commonLib') -// compile 'org.rajawali3d:rajawali:1.0.325@aar' + // APT/Plugin based goodness + annotationProcessor "com.github.stephanenicolas.toothpick:toothpick-compiler:1.0.1" // https://github.com/stephanenicolas/toothpick/blob/master/CHANGELOG.md + compile "com.github.stephanenicolas.toothpick:toothpick-runtime:1.0.1" + compile "com.github.stephanenicolas.toothpick:smoothie:1.0.1" // Latest version of Rajawali // see https://github.com/Rajawali/Rajawali diff --git a/rajaVrDemo/src/main/java/com/kanawish/raja/vr/DemoVRRenderer.java b/rajaVrDemo/src/main/java/com/kanawish/raja/vr/DemoVRRenderer.java index 7dc4b83..04b5bf6 100644 --- a/rajaVrDemo/src/main/java/com/kanawish/raja/vr/DemoVRRenderer.java +++ b/rajaVrDemo/src/main/java/com/kanawish/raja/vr/DemoVRRenderer.java @@ -22,7 +22,7 @@ import org.rajawali3d.primitives.Sphere; import org.rajawali3d.vr.renderer.RajaStereoRenderer; -public final class DemoVRRenderer extends RajaStereoRenderer { +public final class DemoVrRenderer extends RajaStereoRenderer { private Material sphereAMaterial; private Material lookedAtMaterial; @@ -30,7 +30,7 @@ public final class DemoVRRenderer extends RajaStereoRenderer { private PostProcessingManager effectsManager; - public DemoVRRenderer(Context context) { + public DemoVrRenderer(Context context) { super(context); } @@ -67,16 +67,6 @@ public void initScene() { getCurrentScene().setFog(new FogMaterialPlugin.FogParams(FogMaterialPlugin.FogType.LINEAR, 0xCCCCCC, 1, 150)); - // Raja-effects don't play nice with Gvr. - // TODO: GPU post processing? Using render to texture? -/* - effectsManager = new PostProcessingManager(this); - BloomEffect bloomEffect = new BloomEffect( - getCurrentScene(), getCurrentCamera(), getViewportWidth(), - getViewportHeight(), 0x111111, 0xffffff, BlendPass.BlendMode.SCREEN); - effectsManager.addEffect(bloomEffect); - bloomEffect.setRenderToScreen(true); -*/ } @Override diff --git a/rajaVrDemo/src/main/java/com/kanawish/raja/vr/RajaVrDemoActivity.java b/rajaVrDemo/src/main/java/com/kanawish/raja/vr/RajaVrDemoActivity.java index 4090d1c..d92119e 100644 --- a/rajaVrDemo/src/main/java/com/kanawish/raja/vr/RajaVrDemoActivity.java +++ b/rajaVrDemo/src/main/java/com/kanawish/raja/vr/RajaVrDemoActivity.java @@ -53,10 +53,13 @@ public void onCreate(Bundle savedInstanceState) { RajaVrView gvrView = (RajaVrView) findViewById(R.id.gvr_view); gvrView.setEGLConfigChooser(8, 8, 8, 8, 16, 8); - gvrView.setRenderer(new DemoVRRenderer(this)); + + // NOTE: If you build your own renderer, simply switch them in here. + gvrView.setRenderer(new SimpleVrRenderer(this)); + gvrView.setTransitionViewEnabled(true); gvrView.setOnCardboardBackButtonListener(() -> vibrator.vibrate(50)); - setGvrView(gvrView); + this.setGvrView(gvrView); // Initialize 3D audio engine. gvrAudioEngine = new GvrAudioEngine(this, GvrAudioEngine.RenderingMode.BINAURAL_HIGH_QUALITY); diff --git a/rajaVrDemo/src/main/java/com/kanawish/raja/vr/SimpleVRRenderer.java b/rajaVrDemo/src/main/java/com/kanawish/raja/vr/SimpleVRRenderer.java new file mode 100644 index 0000000..7693912 --- /dev/null +++ b/rajaVrDemo/src/main/java/com/kanawish/raja/vr/SimpleVRRenderer.java @@ -0,0 +1,76 @@ +package com.kanawish.raja.vr; + +import android.content.Context; +import android.graphics.Color; +import android.view.MotionEvent; + +import org.rajawali3d.animation.Animation; +import org.rajawali3d.animation.RotateOnAxisAnimation; +import org.rajawali3d.lights.DirectionalLight; +import org.rajawali3d.materials.Material; +import org.rajawali3d.materials.methods.DiffuseMethod; +import org.rajawali3d.materials.textures.ATexture; +import org.rajawali3d.math.vector.Vector3; +import org.rajawali3d.primitives.Cube; +import org.rajawali3d.vr.renderer.RajaStereoRenderer; + +class SimpleVrRenderer extends RajaStereoRenderer { + + SimpleVrRenderer(Context context) { + super(context); + } + + @Override + protected void initScene() { + try { + getCurrentScene().setBackgroundColor(Color.BLUE); + + getCurrentCamera().setFarPlane(1000); + + // Skybox images by Emil Persson, aka Humus. http://www.humus.name humus@comhem.se + try { + getCurrentScene().setSkybox(R.drawable.posx, R.drawable.negx, + R.drawable.posy, R.drawable.negy, R.drawable.posz, R.drawable.negz); + } catch (ATexture.TextureException e) { + e.printStackTrace(); + } + + // Lights, + DirectionalLight key = new DirectionalLight(0, 0.1, 0.2); + key.setPosition(0.0, 10.0, 2.5); + key.enableLookAt(); + key.setPower(2); + getCurrentScene().addLight(key); + + // Models + Material material = new Material(); + material.setDiffuseMethod(new DiffuseMethod.Lambert()); + material.enableLighting(true); + Cube cube = new Cube(1); + cube.setPosition(0, -1, -3); + cube.setMaterial(material); + getCurrentScene().addChild(cube); + + // NOTE: Camera is controlled via VR headset orientation. + + // Action! + RotateOnAxisAnimation anim = new RotateOnAxisAnimation(new Vector3(1, 1, 1), 360); + anim.setTransformable3D(cube); + anim.setDurationMilliseconds(20000); + anim.setRepeatMode(Animation.RepeatMode.INFINITE); + getCurrentScene().registerAnimation(anim); + anim.play(); + } catch (Exception e) { + e.printStackTrace(); + } + } + + @Override + public void onRender(final long ellapsedTime, final double deltaTime) { + super.onRender(ellapsedTime, deltaTime); + } + + @Override + public void onTouchEvent(MotionEvent event) { + } +} diff --git a/rajaVrDemo/src/main/java/org/rajawali3d/vr/renderer/RajaStereoRenderer.java b/rajaVrDemo/src/main/java/org/rajawali3d/vr/renderer/RajaStereoRenderer.java index 29fb40c..1e15937 100644 --- a/rajaVrDemo/src/main/java/org/rajawali3d/vr/renderer/RajaStereoRenderer.java +++ b/rajaVrDemo/src/main/java/org/rajawali3d/vr/renderer/RajaStereoRenderer.java @@ -19,7 +19,6 @@ import com.google.vr.sdk.base.GvrView; import com.google.vr.sdk.base.HeadTransform; import com.google.vr.sdk.base.Viewport; -import com.jakewharton.rxrelay.PublishRelay; import org.rajawali3d.Object3D; import org.rajawali3d.math.Matrix4; @@ -31,6 +30,8 @@ import javax.microedition.khronos.egl.EGLConfig; +import io.reactivex.subjects.PublishSubject; +import io.reactivex.subjects.Subject; import timber.log.Timber; /** @@ -58,7 +59,8 @@ public abstract class RajaStereoRenderer extends Renderer implements GvrView.Ste private float[] headView; // Using relays allows for less spammy logs, possibly other features as well. - PublishRelay headTransforms = PublishRelay.create(); + + PublishSubject headTransforms = PublishSubject.create(); public RajaStereoRenderer(Context context) { super(context); @@ -91,7 +93,7 @@ public final void onOffsetsChanged(float v, float v2, float v3, float v4, int i, @Override public void onNewFrame(HeadTransform headTransform) { float[] headView = headTransform.getHeadView(); - headTransforms.call(headView); + headTransforms.onNext(headView); headTransform.getHeadView(this.headView, 0); headViewMatrix.setAll(this.headView); diff --git a/tangoLibs/aar/TangoSupport_Qianru_Java.aar b/tangoLibs/aar/TangoSupport_Qianru_Java.aar deleted file mode 100644 index 6cca10e..0000000 Binary files a/tangoLibs/aar/TangoSupport_Qianru_Java.aar and /dev/null differ diff --git a/tangoLibs/aar/TangoUX_Qianru_Java.aar b/tangoLibs/aar/TangoUX_Qianru_Java.aar deleted file mode 100644 index b084a42..0000000 Binary files a/tangoLibs/aar/TangoUX_Qianru_Java.aar and /dev/null differ diff --git a/tangoLibs/aar/tango_support_java_lib.aar b/tangoLibs/aar/tango_support_java_lib.aar new file mode 100644 index 0000000..0ad5488 Binary files /dev/null and b/tangoLibs/aar/tango_support_java_lib.aar differ diff --git a/tangoLibs/jar/TangoSDK_Qianru_Java.jar b/tangoLibs/jar/TangoSDK_Qianru_Java.jar deleted file mode 100644 index 7e01dd6..0000000 Binary files a/tangoLibs/jar/TangoSDK_Qianru_Java.jar and /dev/null differ diff --git a/tangoLibs/jar/tango_java_lib.jar b/tangoLibs/jar/tango_java_lib.jar new file mode 100644 index 0000000..5cdabba Binary files /dev/null and b/tangoLibs/jar/tango_java_lib.jar differ diff --git a/tangoRoomEditor/build.gradle b/tangoRoomEditor/build.gradle index e2965ee..f2012ab 100644 --- a/tangoRoomEditor/build.gradle +++ b/tangoRoomEditor/build.gradle @@ -1,10 +1,9 @@ apply plugin: 'com.android.application' -apply plugin: 'com.neenbedankt.android-apt' apply plugin: 'me.tatarka.retrolambda' android { compileSdkVersion 24 - buildToolsVersion "24.0.0 rc4" + buildToolsVersion "24.0.2" compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 @@ -45,16 +44,18 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile fileTree(dir: external_lib_prefix + '/jar', include: ['**/*.jar']) - compile (name: 'TangoSupport_Qianru_Java', ext: 'aar') + compile (name: 'tango_support_java_lib', ext: 'aar') compile project(':rajaTangoLib') - compile 'com.android.support:appcompat-v7:24.0.0' - compile 'com.android.support.constraint:constraint-layout:1.0.0-alpha3' + compile 'com.android.support:appcompat-v7:24.2.1' // APT/Plugin based goodness - apt "com.jakewharton:butterknife-compiler:$project.butterKnifeVersion" - compile "com.jakewharton:butterknife:$project.butterKnifeVersion" - apt "com.google.auto.value:auto-value:$project.autoValueVersion" - apt "com.ryanharter.auto.value:auto-value-gson:$project.autoValueGsonVersion" + annotationProcessor "com.github.stephanenicolas.toothpick:toothpick-compiler:1.0.0" // https://github.com/stephanenicolas/toothpick/blob/master/CHANGELOG.md + compile "com.github.stephanenicolas.toothpick:toothpick-runtime:1.0.0" + compile "com.github.stephanenicolas.toothpick:smoothie:1.0.0" + annotationProcessor "com.jakewharton:butterknife-compiler:8.4.0" // https://github.com/JakeWharton/butterknife/blob/master/CHANGELOG.md + compile "com.jakewharton:butterknife:8.4.0" + annotationProcessor "com.google.auto.value:auto-value:1.2" // https://github.com/google/auto + annotationProcessor "com.ryanharter.auto.value:auto-value-gson:0.4.2" // https://github.com/rharter/auto-value-gson/blob/master/CHANGELOG.md } diff --git a/tangoRoomEditor/src/main/AndroidManifest.xml b/tangoRoomEditor/src/main/AndroidManifest.xml index 2851139..751f132 100644 --- a/tangoRoomEditor/src/main/AndroidManifest.xml +++ b/tangoRoomEditor/src/main/AndroidManifest.xml @@ -9,6 +9,7 @@ log = PublishRelay.create(); private TextView logTextView; - private RajawaliSurfaceView surfaceView; + private SurfaceView surfaceView; private ControlRoomRenderer renderer; - private Subscription logSubscription; + private PublishSubject log = PublishSubject.create(); + private Disposable logDisposable; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + logTextView = (TextView) findViewById(R.id.log_text); - surfaceView = new RajawaliSurfaceView(this); -// surfaceView.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,ViewGroup.LayoutParams.MATCH_PARENT)); + + surfaceView = new SurfaceView(this); + surfaceView.setOnTouchListener(this); renderer = new ControlRoomRenderer(this); surfaceView.setSurfaceRenderer(renderer); - surfaceView.setOnTouchListener(this); ((LinearLayout)findViewById(R.id.parent)).addView(surfaceView); tangoPointCloudManager = new TangoPointCloudManager(); -// setContentView(surfaceView); } @Override protected void onResume() { super.onResume(); - logSubscription = log + logDisposable = log .throttleFirst(100, TimeUnit.MILLISECONDS) .observeOn(AndroidSchedulers.mainThread()) .subscribe( @@ -93,6 +95,7 @@ protected void onResume() { throwable -> Log.e(TAG, "log error", throwable)); if (!isConnected) { + // runOnTangoReady is run on a new Thread(). tango = new Tango(ControlRoomActivity.this, () -> { try { TangoSupport.initialize(); @@ -110,8 +113,9 @@ protected void onResume() { protected void onPause() { super.onPause(); - logSubscription.unsubscribe(); + logDisposable.dispose(); + // mainThread synchronized (this) { if (isConnected) { renderer.getCurrentScene().clearFrameCallbacks(); @@ -125,11 +129,66 @@ protected void onPause() { } } + @Override + public boolean onTouch(View view, MotionEvent motionEvent) { + if (motionEvent.getAction() == MotionEvent.ACTION_UP) { + + // Calculate click location in u,v (0;1) coordinates. + float u = motionEvent.getX() / view.getWidth(); + float v = motionEvent.getY() / view.getHeight(); + + try { + // Fit a plane on the clicked point using the latest point cloud data + // Synchronize against concurrent access to the RGB timestamp + // in the OpenGL thread and a possible service disconnection + // due to an onPause event. + float[] planeFitTransform; + // mainThread + synchronized (this) { + planeFitTransform = doFitPlane(u, v, rgbTimestampGlThread); + } + + if (planeFitTransform != null) { + // Update the position of the rendered cube to the pose of the detected plane + // This update is made thread safe by the renderer + renderer.updateObjectPose(planeFitTransform); + } + + } catch (TangoException t) { + Toast.makeText(getApplicationContext(), + R.string.failed_measurement, + Toast.LENGTH_SHORT).show(); + Log.e(TAG, getString(R.string.failed_measurement), t); + } catch (SecurityException t) { + Toast.makeText(getApplicationContext(), + R.string.failed_permissions, + Toast.LENGTH_SHORT).show(); + Log.e(TAG, getString(R.string.failed_permissions), t); + } + } + return true; + } + /** * Configures the Tango service and connect it to callbacks. */ private void connectTango() { + TangoConfig config = buildTangoConfig(); + tango.connect(config); + + // Defining the coordinate frame pairs we are interested in. + ArrayList framePairs = new ArrayList<>(); + framePairs.add(new TangoCoordinateFramePair( + TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE, + TangoPoseData.COORDINATE_FRAME_DEVICE)); + tango.connectListener(framePairs, buildTangoUpdateListener()); + + tangoCameraIntrinsics = tango.getCameraIntrinsics(TangoCameraIntrinsics.TANGO_CAMERA_COLOR); + } + + @NonNull + private TangoConfig buildTangoConfig() { // Use default configuration for Tango Service, plus low latency IMU integration. TangoConfig config = tango.getConfig(TangoConfig.CONFIG_TYPE_DEFAULT); config.putBoolean(TangoConfig.KEY_BOOLEAN_DEPTH, true); @@ -142,16 +201,12 @@ private void connectTango() { // NOTE: These are extra motion tracking flags. config.putBoolean(TangoConfig.KEY_BOOLEAN_MOTIONTRACKING, true); config.putBoolean(TangoConfig.KEY_BOOLEAN_AUTORECOVERY, true); + return config; + } - tango.connect(config); - - // Defining the coordinate frame pairs we are interested in. - ArrayList framePairs = new ArrayList(); - framePairs.add(new TangoCoordinateFramePair( - TangoPoseData.COORDINATE_FRAME_START_OF_SERVICE, - TangoPoseData.COORDINATE_FRAME_DEVICE)); - - tango.connectListener(framePairs, new OnTangoUpdateListener() { + @NonNull + private OnTangoUpdateListener buildTangoUpdateListener() { + return new OnTangoUpdateListener() { @Override public void onPoseAvailable(TangoPoseData pose) { // We could process pose data here, but we are not @@ -180,25 +235,7 @@ public void onTangoEvent(TangoEvent event) { // Information about events that occur in the Tango system. // Allows you to monitor the health of services at runtime. } - }); - - tangoCameraIntrinsics = tango.getCameraIntrinsics(TangoCameraIntrinsics.TANGO_CAMERA_COLOR); - } - - /** - * Log the Position and Orientation of the given pose in the Logcat as information. - * - * @param pose the pose to log. - */ - private void logPose(TangoPoseData pose) { - StringBuilder stringBuilder = new StringBuilder(); - float translation[] = pose.getTranslationAsFloats(); - float orientation[] = pose.getRotationAsFloats(); - - stringBuilder.append(String.format("[%+3.3f,%+3.3f,%+3.3f]\n",translation[0],translation[1],translation[2])); - stringBuilder.append(String.format("(%+3.3f,%+3.3f,%+3.3f,%+3.3f)",orientation[0],orientation[1],orientation[2],orientation[3])); - - log.call(stringBuilder.toString()); + }; } /** @@ -214,6 +251,7 @@ public void onPreFrame(long sceneTime, double deltaTime) { // onRender callbacks had a chance to run and before scene objects are rendered // into the scene. + // TODO: Check, but very likely Tango thread. synchronized (ControlRoomActivity.this) { // Don't execute any tango API actions if we're not connected to the service if (!isConnected) { @@ -229,8 +267,7 @@ public void onPreFrame(long sceneTime, double deltaTime) { // NOTE: When the OpenGL context is recycled, Rajawali may re-generate the // texture with a different ID. if (connectedTextureIdGlThread != renderer.getTextureId()) { - tango.connectTextureId(TangoCameraIntrinsics.TANGO_CAMERA_COLOR, - renderer.getTextureId()); + tango.connectTextureId(TangoCameraIntrinsics.TANGO_CAMERA_COLOR, renderer.getTextureId()); connectedTextureIdGlThread = renderer.getTextureId(); Log.d(TAG, "connected to texture id: " + renderer.getTextureId()); } @@ -278,45 +315,6 @@ public boolean callPreFrame() { }); } - @Override - public boolean onTouch(View view, MotionEvent motionEvent) { - if (motionEvent.getAction() == MotionEvent.ACTION_UP) { - - // Calculate click location in u,v (0;1) coordinates. - float u = motionEvent.getX() / view.getWidth(); - float v = motionEvent.getY() / view.getHeight(); - - try { - // Fit a plane on the clicked point using the latest point cloud data - // Synchronize against concurrent access to the RGB timestamp - // in the OpenGL thread and a possible service disconnection - // due to an onPause event. - float[] planeFitTransform; - synchronized (this) { - planeFitTransform = doFitPlane(u, v, rgbTimestampGlThread); - } - - if (planeFitTransform != null) { - // Update the position of the rendered cube to the pose of the detected plane - // This update is made thread safe by the renderer - renderer.updateObjectPose(planeFitTransform); - } - - } catch (TangoException t) { - Toast.makeText(getApplicationContext(), - R.string.failed_measurement, - Toast.LENGTH_SHORT).show(); - Log.e(TAG, getString(R.string.failed_measurement), t); - } catch (SecurityException t) { - Toast.makeText(getApplicationContext(), - R.string.failed_permissions, - Toast.LENGTH_SHORT).show(); - Log.e(TAG, getString(R.string.failed_permissions), t); - } - } - return true; - } - /** * Use the TangoSupport library with point cloud data to calculate the plane * of the world feature pointed at the location the camera is looking. @@ -352,7 +350,7 @@ private float[] doFitPlane(float u, float v, double rgbTimestamp) { TANGO_SUPPORT_ENGINE_TANGO); if (transform.statusCode == TangoPoseData.POSE_VALID) { - float[] openGlTPlane = calculatePlaneTransform( + float[] openGlTPlane = TangoMath.calculatePlaneTransform( intersectionPointPlaneModelPair.intersectionPoint, intersectionPointPlaneModelPair.planeModel, transform.matrix); @@ -364,71 +362,19 @@ private float[] doFitPlane(float u, float v, double rgbTimestamp) { } /** - * Calculate the pose of the plane based on the position and normal orientation of the plane - * and align it with gravity. - */ - private float[] calculatePlaneTransform(double[] point, double normal[], - float[] openGlTdepth) { - // Vector aligned to gravity. - float[] openGlUp = new float[]{0, 1, 0, 0}; - float[] depthTOpenGl = new float[16]; - Matrix.invertM(depthTOpenGl, 0, openGlTdepth, 0); - float[] depthUp = new float[4]; - Matrix.multiplyMV(depthUp, 0, depthTOpenGl, 0, openGlUp, 0); - // Create the plane matrix transform in depth frame from a point, the plane normal and the - // up vector. - float[] depthTplane = matrixFromPointNormalUp(point, normal, depthUp); - float[] openGlTplane = new float[16]; - Matrix.multiplyMM(openGlTplane, 0, openGlTdepth, 0, depthTplane, 0); - return openGlTplane; - } - - /** - * Calculates a transformation matrix based on a point, a normal and the up gravity vector. - * The coordinate frame of the target transformation will be Z forward, X left, Y up. + * Log the Position and Orientation of the given pose in the Logcat as information. + * + * @param pose the pose to log. */ - private float[] matrixFromPointNormalUp(double[] point, double[] normal, float[] up) { - float[] zAxis = new float[]{(float) normal[0], (float) normal[1], (float) normal[2]}; - normalize(zAxis); - float[] xAxis = crossProduct(zAxis, up); - normalize(xAxis); - float[] yAxis = crossProduct(zAxis, xAxis); - normalize(yAxis); - float[] m = new float[16]; - Matrix.setIdentityM(m, 0); - m[0] = xAxis[0]; - m[1] = xAxis[1]; - m[2] = xAxis[2]; - m[4] = yAxis[0]; - m[5] = yAxis[1]; - m[6] = yAxis[2]; - m[8] = zAxis[0]; - m[9] = zAxis[1]; - m[10] = zAxis[2]; - m[12] = (float) point[0]; - m[13] = (float) point[1]; - m[14] = (float) point[2]; - return m; - } + @SuppressLint("DefaultLocale") + private void logPose(TangoPoseData pose) { + StringBuilder stringBuilder = new StringBuilder(); + float translation[] = pose.getTranslationAsFloats(); + float orientation[] = pose.getRotationAsFloats(); - /** - * Normalize a vector. - */ - private void normalize(float[] v) { - double norm = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); - v[0] /= norm; - v[1] /= norm; - v[2] /= norm; - } + stringBuilder.append(String.format("[%+3.3f,%+3.3f,%+3.3f]\n",translation[0],translation[1],translation[2])); + stringBuilder.append(String.format("(%+3.3f,%+3.3f,%+3.3f,%+3.3f)",orientation[0],orientation[1],orientation[2],orientation[3])); - /** - * Cross product between two vectors following the right hand rule. - */ - private float[] crossProduct(float[] v1, float[] v2) { - float[] result = new float[3]; - result[0] = v1[1] * v2[2] - v2[1] * v1[2]; - result[1] = v1[2] * v2[0] - v2[2] * v1[0]; - result[2] = v1[0] * v2[1] - v2[0] * v1[1]; - return result; + log.onNext(stringBuilder.toString()); } } diff --git a/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/ControlRoomApp.java b/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/ControlRoomApp.java new file mode 100644 index 0000000..5e3396b --- /dev/null +++ b/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/ControlRoomApp.java @@ -0,0 +1,20 @@ +package com.kanawish.raja.controlroom; + +import android.app.Application; + +import timber.log.Timber; + +/** + * Created by kanawish on 2016-07-17. + */ + +public class ControlRoomApp extends Application { + + @Override public void onCreate() { + super.onCreate(); + + if (BuildConfig.DEBUG) { + Timber.plant(new Timber.DebugTree()); + } // NOTE: No logging in release mode. + } +} diff --git a/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/ControlRoomRenderer.java b/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/ControlRoomRenderer.java index 7c0bdc4..30f79ca 100644 --- a/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/ControlRoomRenderer.java +++ b/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/ControlRoomRenderer.java @@ -29,6 +29,9 @@ import org.rajawali3d.animation.Animation; import org.rajawali3d.animation.Animation3D; import org.rajawali3d.animation.RotateOnAxisAnimation; +import org.rajawali3d.debug.CoordinateTrident; +import org.rajawali3d.debug.DebugCamera; +import org.rajawali3d.debug.DebugLight; import org.rajawali3d.lights.DirectionalLight; import org.rajawali3d.loader.LoaderOBJ; import org.rajawali3d.loader.ParsingException; @@ -43,9 +46,10 @@ import org.rajawali3d.math.vector.Vector3; import org.rajawali3d.primitives.Cube; import org.rajawali3d.primitives.Plane; +import org.rajawali3d.primitives.RectangularPrism; import org.rajawali3d.primitives.ScreenQuad; import org.rajawali3d.primitives.Sphere; -import org.rajawali3d.renderer.RajawaliRenderer; +import org.rajawali3d.renderer.Renderer; import javax.microedition.khronos.opengles.GL10; @@ -54,7 +58,7 @@ * The position of the cube in the OpenGL world is updated using the {@code updateObjectPose} * method. */ -public class ControlRoomRenderer extends RajawaliRenderer { +public class ControlRoomRenderer extends Renderer { private static final String TAG = ControlRoomRenderer.class.getSimpleName(); @@ -81,6 +85,7 @@ protected void initScene() { // Create a quad covering the whole background and assign a texture to it where the // Tango color camera contents will be rendered. ScreenQuad backgroundQuad = new ScreenQuad(); + backgroundQuad.setDoubleSided(true); Material tangoCameraMaterial = new Material(); tangoCameraMaterial.setColorInfluence(0); @@ -95,6 +100,7 @@ protected void initScene() { Log.e(TAG, "Exception creating texture for RGB camera contents", e); } getCurrentScene().addChildAt(backgroundQuad, 0); + backgroundQuad.rotate(Vector3.Axis.X,180); // Add a directional light in an arbitrary direction. DirectionalLight light = new DirectionalLight(1, -0.5, -1); @@ -102,20 +108,22 @@ protected void initScene() { light.setPower(1.2f); light.setPosition(0, 10, 0); getCurrentScene().addLight(light); + getCurrentScene().addChild(new DebugLight(light)); // Set-up a material Material cubeMaterial = buildMaterial(Color.RED); // Build a Cube +// cube = new CoordinateTrident(); cube = new Cube(CUBE_SIDE_LENGTH); cube.setMaterial(cubeMaterial); - cube.setPosition(0, 0, 0); cube.setRotation(Vector3.Axis.Z, 180); + cube.setPosition(0, 0, 0); cube.setVisible(false); getCurrentScene().addChild(cube); // Set-up a material - Material sphereMaterial = buildMaterial(Color.GREEN); + Material sphereMaterial = buildMaterial(Color.BLUE); // Build a Sphere sphere = new Sphere(0.25f,20,20); @@ -131,12 +139,14 @@ protected void initScene() { } catch (ATexture.TextureException e) { e.printStackTrace(); } - plane = new Plane(); + plane = new Plane(0.5f,0.5f,1,1); plane.setMaterial(checkerboard); plane.setDoubleSided(true); plane.setColor(0xff0000ff); plane.setVisible(false); getCurrentScene().addChild(plane); + +// getCurrentScene().addChild(new DebugCamera(getCurrentCamera())); // ? } @NonNull @@ -154,6 +164,7 @@ enum Furniture { Furniture next() { int i = (this.ordinal() + 1) % Furniture.values().length; return Furniture.values()[i]; +// return PLANE ; } } Furniture currentFurniture = Furniture.PLANE; @@ -164,11 +175,6 @@ protected void onRender(long elapsedRealTime, double deltaTime) { // Synchronize against concurrent access with the setter below. synchronized (this) { if (objectPoseUpdated) { - sphere.setPosition(objectTransform.getTranslation()); - sphere.setOrientation(new Quaternion().fromMatrix(objectTransform).conjugate()); - sphere.moveForward(0.25f); - sphere.setVisible(true); - // Place the 3D object in the location of the detected plane. switch ( currentFurniture ) { case PLANE: @@ -209,6 +215,7 @@ protected void onRender(long elapsedRealTime, double deltaTime) { public synchronized void updateObjectPose(float[] planeFitTransform) { objectTransform = new Matrix4(planeFitTransform); objectPoseUpdated = true; + } /** @@ -224,6 +231,7 @@ public void updateRenderCameraPose(TangoPoseData cameraPose) { getCurrentCamera().setPosition(translation[0], translation[1], translation[2]); Quaternion quaternion = new Quaternion(rotation[3], rotation[0], rotation[1], rotation[2]); +// getCurrentCamera().setRotation(quaternion.conjugate()); getCurrentCamera().setRotation(quaternion.conjugate()); } @@ -251,7 +259,7 @@ public boolean isSceneCameraConfigured() { } /** - * Sets the projection matrix for the scen camera to match the parameters of the color camera, + * Sets the projection matrix for the scene camera to match the parameters of the color camera, * provided by the {@code TangoCameraIntrinsics}. */ public void setProjectionMatrix(TangoCameraIntrinsics intrinsics) { diff --git a/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/PlanFittingApplication.java b/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/PlanFittingApplication.java deleted file mode 100644 index 1338c25..0000000 --- a/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/PlanFittingApplication.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.kanawish.raja.controlroom; - -import android.app.Application; - -/** - * Created by kanawish on 2016-07-17. - */ - -public class PlanFittingApplication extends Application { - - @Override - public void onCreate() { - super.onCreate(); - } -} diff --git a/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/utils/TangoMath.java b/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/utils/TangoMath.java new file mode 100644 index 0000000..1f5ece5 --- /dev/null +++ b/tangoRoomEditor/src/main/java/com/kanawish/raja/controlroom/utils/TangoMath.java @@ -0,0 +1,78 @@ +package com.kanawish.raja.controlroom.utils; + +import android.opengl.Matrix; + +/** + * Created by kanawish on 2016-08-03. + */ +public class TangoMath { + + /** + * Calculates a transformation matrix based on a point, a normal and the up gravity vector. + * The coordinate frame of the target transformation will be Z forward, X left, Y up. + */ + public static float[] matrixFromPointNormalUp(double[] point, double[] normal, float[] up) { + float[] zAxis = new float[]{(float) normal[0], (float) normal[1], (float) normal[2]}; + normalize(zAxis); + float[] xAxis = crossProduct(zAxis, up); + normalize(xAxis); + float[] yAxis = crossProduct(zAxis, xAxis); + normalize(yAxis); + float[] m = new float[16]; + Matrix.setIdentityM(m, 0); + m[0] = xAxis[0]; + m[1] = xAxis[1]; + m[2] = xAxis[2]; + m[4] = yAxis[0]; + m[5] = yAxis[1]; + m[6] = yAxis[2]; + m[8] = zAxis[0]; + m[9] = zAxis[1]; + m[10] = zAxis[2]; + m[12] = (float) point[0]; + m[13] = (float) point[1]; + m[14] = (float) point[2]; + return m; + } + + /** + * Normalize a vector. + */ + private static void normalize(float[] v) { + double norm = Math.sqrt(v[0] * v[0] + v[1] * v[1] + v[2] * v[2]); + v[0] /= norm; + v[1] /= norm; + v[2] /= norm; + } + + /** + * Cross product between two vectors following the right hand rule. + */ + private static float[] crossProduct(float[] v1, float[] v2) { + float[] result = new float[3]; + result[0] = v1[1] * v2[2] - v2[1] * v1[2]; + result[1] = v1[2] * v2[0] - v2[2] * v1[0]; + result[2] = v1[0] * v2[1] - v2[0] * v1[1]; + return result; + } + + /** + * Calculate the pose of the plane based on the position and normal orientation of the plane + * and align it with gravity. + */ + public static float[] calculatePlaneTransform(double[] point, double normal[], + float[] openGlTdepth) { + // Vector aligned to gravity. + float[] openGlUp = new float[]{0, 1, 0, 0}; + float[] depthTOpenGl = new float[16]; + Matrix.invertM(depthTOpenGl, 0, openGlTdepth, 0); + float[] depthUp = new float[4]; + Matrix.multiplyMV(depthUp, 0, depthTOpenGl, 0, openGlUp, 0); + // Create the plane matrix transform in depth frame from a point, the plane normal and the + // up vector. + float[] depthTplane = matrixFromPointNormalUp(point, normal, depthUp); + float[] openGlTplane = new float[16]; + Matrix.multiplyMM(openGlTplane, 0, openGlTdepth, 0, depthTplane, 0); + return openGlTplane; + } +} diff --git a/tangoRoomEditor/src/main/res/layout/activity_main.xml b/tangoRoomEditor/src/main/res/layout/activity_main.xml index 7a91068..6f72f98 100644 --- a/tangoRoomEditor/src/main/res/layout/activity_main.xml +++ b/tangoRoomEditor/src/main/res/layout/activity_main.xml @@ -32,10 +32,12 @@ android:layout_height="wrap_content" android:text="placeholder"/> + \ No newline at end of file