diff --git a/platform_tools/android/apps/skar_java/build.gradle b/platform_tools/android/apps/skar_java/build.gradle index fd85e24230..a3ad6b00df 100644 --- a/platform_tools/android/apps/skar_java/build.gradle +++ b/platform_tools/android/apps/skar_java/build.gradle @@ -33,7 +33,7 @@ dependencies { implementation 'de.javagl:obj:0.2.1' implementation 'com.android.support:appcompat-v7:27.0.2' - implementation 'com.android.support:design:27.0.2' + implementation 'com.android.support:design:27.1.1' // Required -- JUnit 4 framework testImplementation 'junit:junit:4.12' diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/ar/core/examples/java/helloskar/DrawManager.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/ar/core/examples/java/helloskar/DrawManager.java index 98f36fbe1f..19dbb22057 100644 --- a/platform_tools/android/apps/skar_java/src/main/java/com/google/ar/core/examples/java/helloskar/DrawManager.java +++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/ar/core/examples/java/helloskar/DrawManager.java @@ -143,7 +143,7 @@ public class DrawManager { fingerPainting.buildPath(); // If path empty, return - if (fingerPainting.path.isEmpty()) { + if (fingerPainting.getPaths().isEmpty()) { return; } @@ -164,35 +164,37 @@ public class DrawManager { float[][] matrices = {scale, initRot, in, viewMatrix, projectionMatrix, SkARMatrix.createViewportMatrix(viewportWidth, viewportHeight)}; android.graphics.Matrix mvpv = SkARMatrix.createMatrixFrom4x4(SkARMatrix.multiplyMatrices4x4(matrices)); - // Set up paint - Paint p = new Paint(); - if (fingerPainting.getSmoothness()) { - p.setColor(Color.CYAN); - } else { - p.setColor(Color.GREEN); + for (Path path : fingerPainting.getPaths()) { + if (path.isEmpty()) { + continue; + } + // Set up paint + Paint p = new Paint(); + p.setColor(fingerPainting.getPathColor(path)); + + p.setStyle(Paint.Style.STROKE); + p.setStrokeWidth(30f); + p.setAlpha(120); + + if (true) { + // Transform applied through canvas + canvas.save(); + canvas.setMatrix(mvpv); + canvas.drawPath(path, p); + canvas.restore(); + } else { + // Transform path directly + Path pathDst = new Path(); + path.transform(mvpv, pathDst); + + // Draw dest path + canvas.save(); + canvas.setMatrix(new android.graphics.Matrix()); + canvas.drawPath(pathDst, p); + canvas.restore(); + } } - p.setStyle(Paint.Style.STROKE); - p.setStrokeWidth(30f); - p.setAlpha(120); - - if (true) { - // Transform applied through canvas - canvas.save(); - canvas.setMatrix(mvpv); - canvas.drawPath(fingerPainting.path, p); - canvas.restore(); - } else { - // Transform path directly - Path pathDst = new Path(); - fingerPainting.path.transform(mvpv, pathDst); - - // Draw dest path - canvas.save(); - canvas.setMatrix(new android.graphics.Matrix()); - canvas.drawPath(pathDst, p); - canvas.restore(); - } } // Sample function for drawing the AR point cloud diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/ar/core/examples/java/helloskar/HelloSkARActivity.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/ar/core/examples/java/helloskar/HelloSkARActivity.java index 56b46017e7..7032d13e89 100644 --- a/platform_tools/android/apps/skar_java/src/main/java/com/google/ar/core/examples/java/helloskar/HelloSkARActivity.java +++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/ar/core/examples/java/helloskar/HelloSkARActivity.java @@ -26,6 +26,9 @@ import android.opengl.GLES20; import android.opengl.GLSurfaceView; import android.opengl.Matrix; import android.os.Bundle; +import android.support.annotation.NonNull; +import android.support.design.internal.BottomNavigationMenuView; +import android.support.design.widget.BottomNavigationView; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; import android.util.Log; @@ -104,12 +107,12 @@ public class HelloSkARActivity extends AppCompatActivity implements GLSurfaceVie // 2D Renderer private DrawManager drawManager = new DrawManager(); private DrawingType currentDrawabletype = DrawingType.circle; - private boolean drawSmoothPainting = false; + private boolean drawSmoothPainting = true; // Temporary matrix allocated here to reduce number of allocations for each frame. private final float[] anchorMatrix = new float[16]; - PointF previousEvent;; + PointF previousEvent; // Anchors created from taps used for object placing. private final ArrayList anchors = new ArrayList<>(); @@ -151,6 +154,26 @@ public class HelloSkARActivity extends AppCompatActivity implements GLSurfaceVie installRequested = false; + BottomNavigationView bottomNav = findViewById(R.id.palette); + bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() { + @Override + public boolean onNavigationItemSelected(@NonNull MenuItem item) { + switch (item.getItemId()) { + case R.id.palette_green: + drawManager.fingerPainting.setColor(Color.GREEN); + return true; + case R.id.palette_red: + drawManager.fingerPainting.setColor(Color.RED); + return true; + case R.id.palette_reset: + drawManager.fingerPainting.reset(); + return true; + default: + return true; + } + } + }); + // Animator set up PropertyValuesHolder propertyRadius = PropertyValuesHolder.ofFloat(PROPERTY_RADIUS, 0, 0.5f); animator = new ValueAnimator(); @@ -353,9 +376,9 @@ public class HelloSkARActivity extends AppCompatActivity implements GLSurfaceVie drawManager.updateLightColorFilter(colorCorrectionRgba); // Building finger painting - MotionEvent holdTap = tapHelper.holdPoll(); + TapHelper.ScrollEvent holdTap = tapHelper.holdPoll(); if (holdTap != null && camera.getTrackingState() == TrackingState.TRACKING) { - for (HitResult hit : frame.hitTest(holdTap)) { + for (HitResult hit : frame.hitTest(holdTap.e)) { // Check if any plane was hit, and if it was hit inside the plane polygon Trackable trackable = hit.getTrackable(); // Creates an anchor if a plane or an oriented point was hit. @@ -374,7 +397,7 @@ public class HelloSkARActivity extends AppCompatActivity implements GLSurfaceVie Matrix.multiplyMV(point, 0, gm, 0, point, 0); if (drawManager.fingerPainting.isEmpty()) { - drawManager.fingerPainting.addPoint(new PointF(0, 0)); + drawManager.fingerPainting.addPoint(new PointF(0, 0), true); // Get model matrix of first point float[] m = new float[16]; @@ -395,7 +418,7 @@ public class HelloSkARActivity extends AppCompatActivity implements GLSurfaceVie distance.y * localDistanceScale + drawManager.fingerPainting.previousPoint.y); - drawManager.fingerPainting.addPoint(p); + drawManager.fingerPainting.addPoint(p, holdTap.isStartOfScroll); } previousEvent = new PointF(point[0], point[2]); diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/SkARFingerPainting.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/SkARFingerPainting.java index c93a900f58..e28037dc33 100644 --- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/SkARFingerPainting.java +++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/SkARFingerPainting.java @@ -1,16 +1,25 @@ package com.google.skar; +import android.graphics.Color; import android.graphics.Path; import android.graphics.PointF; +import android.util.Log; + +import java.util.ArrayList; +import java.util.HashMap; +import java.util.Map; import java.util.ArrayList; public class SkARFingerPainting { // Points obtained by touching the screen. The first point is always brough to (0,0). // All subsequent points are translated by the same amount. - public ArrayList points = new ArrayList<>(); - - public Path path = new Path(); + private ArrayList points = new ArrayList<>(); + private ArrayList jumpPoints = new ArrayList<>(); + private Map indexColors = new HashMap<>(); + private Map pathColors = new HashMap<>(); + private ArrayList paths = new ArrayList<>(); + private int color = Color.RED; // Previous point added to the path. This points belongs to the path in local space. public PointF previousPoint; @@ -34,49 +43,87 @@ public class SkARFingerPainting { } // Adds another point to the path in Local space - public void addPoint(PointF p) { + public void addPoint(PointF p, boolean jumpPoint) { points.add(p); + if (jumpPoint) { + Log.i("Jumped!", Integer.toString(points.size() - 1)); + jumpPoints.add(points.size() - 1); + indexColors.put(points.size() - 1, color); + } previousPoint = p; } // Used to build a path before rendering it public void buildPath() { - if (points.size() < 1) { + paths = new ArrayList<>(); + if (points.size() <= 1) { return; } - path = new Path(); + if (isSmooth) { - // If less than 3 points, than draw a line between the two points - if (points.size() <= 2 && points.size() > 0) { - path.moveTo(points.get(0).x, points.get(0).y); - path.lineTo(points.get(1).x, points.get(1).y); - } else if (points.size() >= 3){ - // Else, essentially run deCasteljau - path.moveTo(points.get(0).x, points.get(0).y); - PointF mid = new PointF((points.get(0).x + points.get(1).x) / 2, - (points.get(0).y + points.get(1).y) / 2); - path.lineTo(mid.x, mid.y); + int start = 0; + for (int j = 1; j < jumpPoints.size(); j++) { - for (int i = 1; i < points.size() - 1; i++) { - PointF p1 = points.get(i); - PointF p2 = points.get(i + 1); - PointF midP = new PointF((p1.x + p2.x) / 2,(p1.y + p2.y) / 2); - path.quadTo(p1.x, p1.y, midP.x, midP.y); - } - - path.lineTo(points.get(points.size() - 1).x, points.get(points.size() - 1).y); + int finish = jumpPoints.get(j); + buildSmoothFromTo(start, finish); + start = finish; } + + buildSmoothFromTo(start, points.size()); } else { - path.moveTo(points.get(0).x, points.get(0).y); - for (int i = 1; i < points.size(); i++) { - path.lineTo(points.get(i).x, points.get(i).y); + + int start = 0; + for (int j = 1; j < jumpPoints.size(); j++) { + int finish = jumpPoints.get(j); + buildRoughFromTo(start, finish); + start = finish; } + + buildRoughFromTo(start, points.size()); } } + private void buildRoughFromTo(int start, int finish) { + Path p = new Path(); + int c = indexColors.get(start); + p.moveTo(points.get(start).x, points.get(start).y); + for (int i = start + 1; i < finish; i++) { + p.lineTo(points.get(i).x, points.get(i).y); + } + paths.add(p); + pathColors.put(p, c); + } + + private void buildSmoothFromTo(int start, int finish) { + Path p = new Path(); + int c = indexColors.get(start); + int nbPts = finish - start; + // If less than 3 points, than draw a line between the two points + if (nbPts <= 2 && nbPts > 1) { + p.moveTo(points.get(start).x, points.get(start).y); + p.lineTo(points.get(start + 1).x, points.get(start + 1).y); + } else if (nbPts >= 3){ + // Else, essentially run deCasteljau + p.moveTo(points.get(start).x, points.get(start).y); + PointF mid = new PointF((points.get(start).x + points.get(start + 1).x) / 2, + (points.get(start).y + points.get(start + 1).y) / 2); + p.lineTo(mid.x, mid.y); + + for (int i = start + 1; i < finish - 1; i++) { + PointF p1 = points.get(i); + PointF p2 = points.get(i + 1); + p.quadTo(p1.x, p1.y, (p1.x + p2.x) / 2, (p1.y + p2.y) / 2); + } + + p.lineTo(points.get(finish - 1).x, points.get(finish - 1).y); + } + paths.add(p); + pathColors.put(p, c); + } + public boolean isEmpty() { - return path.isEmpty(); + return points.isEmpty(); } public float[] getModelMatrix() { @@ -87,8 +134,23 @@ public class SkARFingerPainting { modelMatrix = m; } + public void setColor(int color) { + this.color = color; + } + + public int getPathColor(Path p) { + return pathColors.get(p); + } + + public ArrayList getPaths() { + return paths; + } + public void reset() { - points = new ArrayList<>(); - path = new Path(); + points.clear(); + jumpPoints.clear(); + paths.clear(); + pathColors.clear(); + indexColors.clear(); } } diff --git a/platform_tools/android/apps/skar_java/src/main/res/layout/activity_main.xml b/platform_tools/android/apps/skar_java/src/main/res/layout/activity_main.xml index d5c14031ee..109c40c829 100644 --- a/platform_tools/android/apps/skar_java/src/main/res/layout/activity_main.xml +++ b/platform_tools/android/apps/skar_java/src/main/res/layout/activity_main.xml @@ -42,6 +42,13 @@ android:id="@+id/glsurfaceview" android:layout_width="match_parent" android:layout_height="match_parent" /> + diff --git a/platform_tools/android/apps/skar_java/src/main/res/menu/platte_bar.xml b/platform_tools/android/apps/skar_java/src/main/res/menu/platte_bar.xml new file mode 100644 index 0000000000..c3e9f0c66d --- /dev/null +++ b/platform_tools/android/apps/skar_java/src/main/res/menu/platte_bar.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/platform_tools/android/apps/skar_java/src/main/res/values/styles.xml b/platform_tools/android/apps/skar_java/src/main/res/values/styles.xml index 59cf7e9ffb..60e8bdafbb 100644 --- a/platform_tools/android/apps/skar_java/src/main/res/values/styles.xml +++ b/platform_tools/android/apps/skar_java/src/main/res/values/styles.xml @@ -32,4 +32,17 @@ + + + +