SkAR Java: refactoring main app class & finger painting class
Main things to look at:
1) onDrawFrame changes + moving many functions as separate helpers
2) SkARFingerPainting changes (name should change too)
Bug: skia:
Change-Id: I5068ce6c416a2f5d6c6c389cd63d08d5350e83e6
Reviewed-on: https://skia-review.googlesource.com/143701
Reviewed-by: Mike Reed <reed@google.com>
diff --git a/platform_tools/android/apps/skar_java/src/main/AndroidManifest.xml b/platform_tools/android/apps/skar_java/src/main/AndroidManifest.xml
index abfacc5..efd40d1 100644
--- a/platform_tools/android/apps/skar_java/src/main/AndroidManifest.xml
+++ b/platform_tools/android/apps/skar_java/src/main/AndroidManifest.xml
@@ -33,7 +33,7 @@
tools:ignore="GoogleAppIndexingWarning">
<activity
- android:name="com.google.ar.core.examples.java.helloskar.HelloCanvasAR"
+ android:name="com.google.skar.examples.helloskar.app.HelloCanvasAR"
android:configChanges="orientation|screenSize"
android:exported="true"
android:theme="@style/Theme.AppCompat.DayNight.NoActionBar"
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/CanvasMatrixUtil.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/CanvasMatrixUtil.java
index bfab93e..d0d594a 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/CanvasMatrixUtil.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/CanvasMatrixUtil.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.google.skar;
import android.graphics.Matrix;
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/PaintUtil.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/PaintUtil.java
index 75fa86b..b9aaa01 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/PaintUtil.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/PaintUtil.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.google.skar;
import android.graphics.ColorFilter;
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/ARSurfaceView.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/ARSurfaceView.java
deleted file mode 100644
index 03185c2..0000000
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/ARSurfaceView.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package com.google.skar.examples.helloskar.app;
-
-import android.content.Context;
-import android.graphics.Color;
-import android.graphics.PixelFormat;
-import android.util.AttributeSet;
-import android.view.SurfaceHolder;
-import android.view.SurfaceView;
-
-/**
- * SurfaceView that is overlayed on top of a GLSurfaceView. All 2D drawings can be done on this
- * surface.
- */
-public class ARSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
-
- boolean running;
-
- public ARSurfaceView(Context context, AttributeSet attrs) {
- super(context, attrs);
-
- SurfaceHolder holder = getHolder();
- this.setBackgroundColor(Color.TRANSPARENT);
- this.setZOrderOnTop(true);
- holder.setFormat(PixelFormat.TRANSPARENT);
- holder.addCallback(this);
- }
-
- public boolean isRunning() {
- return running;
- }
-
- @Override
- public void surfaceCreated(SurfaceHolder holder) {
- running = true;
- }
-
- @Override
- public void surfaceDestroyed(SurfaceHolder holder) {
- running = false;
- }
-
- @Override
- public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
- }
-}
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/CanvasARSurfaceView.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/CanvasARSurfaceView.java
new file mode 100644
index 0000000..40c789d
--- /dev/null
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/CanvasARSurfaceView.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.skar.examples.helloskar.app;
+
+import android.content.Context;
+import android.graphics.Color;
+import android.graphics.PixelFormat;
+import android.util.AttributeSet;
+import android.view.SurfaceHolder;
+import android.view.SurfaceView;
+
+/**
+ * SurfaceView that is overlayed on top of a GLSurfaceView. All Canvas 2D drawings can be done on
+ * this surface.
+ */
+
+public class CanvasARSurfaceView extends SurfaceView implements SurfaceHolder.Callback {
+
+ boolean running;
+
+ public CanvasARSurfaceView(Context context, AttributeSet attrs) {
+ super(context, attrs);
+
+ SurfaceHolder holder = getHolder();
+ this.setBackgroundColor(Color.TRANSPARENT);
+ this.setZOrderOnTop(true);
+ holder.setFormat(PixelFormat.TRANSPARENT);
+ holder.addCallback(this);
+ }
+
+ public boolean isRunning() {
+ return running;
+ }
+
+ @Override
+ public void surfaceCreated(SurfaceHolder holder) {
+ running = true;
+ }
+
+ @Override
+ public void surfaceDestroyed(SurfaceHolder holder) {
+ running = false;
+ }
+
+ @Override
+ public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
+ }
+}
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/FingerPainting.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/FingerPainting.java
new file mode 100644
index 0000000..e4aaf57
--- /dev/null
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/FingerPainting.java
@@ -0,0 +1,260 @@
+/*
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.google.skar.examples.helloskar.app;
+
+import android.graphics.Color;
+import android.graphics.Path;
+import android.graphics.PointF;
+import android.util.Log;
+
+import com.google.skar.examples.helloskar.helpers.TapHelper;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import java.util.ArrayList;
+
+public class FingerPainting {
+ public static class BuiltPath {
+ public Path path;
+ public int color;
+
+ BuiltPath(Path p, int c) {
+ this.path = p;
+ this.color = c;
+ }
+ }
+
+ // Points obtained by touching the screen. The first point is always brought to (0,0).
+ // All subsequent points are translated by the same amount.
+ private ArrayList<PointF> points = new ArrayList<>();
+
+ // Indices in points array that indicate the start of a new path. E.g: if 5 is added to
+ // jumpPoints, then index 5 of the points array is the start of a new path (use moveTo())
+ private ArrayList<Integer> jumpPoints = new ArrayList<>();
+
+ // Map from index (start of path) to color of path
+ private Map<Integer, Integer> indexColors = new HashMap<>();
+
+ // List of built paths (reset each frame)
+ private ArrayList<BuiltPath> paths = new ArrayList<>();
+
+ // Previous point added to the path. This points belongs to the path in local space.
+ private float[] previousLocalPoint = new float[2];
+
+ // Previous point added to the path. This points belongs to the path in global space (i.e Pose)
+ private float[] previousGlobalPoint = new float[2];
+
+ // Holds the model matrix of the first point added to such that the path can be drawn at the
+ // model location (i.e on the Plane)
+ private float[] modelMatrix;
+
+ // Currently selected color in the UI
+ private int color = Color.RED;
+
+ // True if path should be drawn using buildSmoothFromTo()
+ private boolean isSmooth;
+
+ public FingerPainting(boolean smooth) {
+ this.isSmooth = smooth;
+ }
+
+ public void setSmoothness(boolean smooth) {
+ isSmooth = smooth;
+ }
+
+ /**
+ * Given a hit location in Global space (e.g on a Plane), and the associated ScrollEvent,
+ * construct the next point in the path in Local space. The first point of the Finger Painting
+ * must be at (0,0)
+ * @param hitLocation (x, y) coordinates of the hit position in Global space
+ * @param holdTap ScrollEvent associated with the hit test that calls this function
+ * @return true if point was computed and added. False otherwise.
+ */
+ public boolean computeNextPoint(float[] hitLocation, TapHelper.ScrollEvent holdTap) {
+ if (isEmpty()) {
+ // If finger painting is empty, then first point is origin. Model matrix
+ // of the finger painting is the model matrix of the first point
+ addPoint(new PointF(0, 0), true);
+
+ // Get model matrix of first point
+ setModelMatrix(modelMatrix);
+ } else {
+ // Else, construct next point given its distance from previous point
+ float localDistanceScale = 1000;
+ PointF distance = new PointF(hitLocation[0] - previousGlobalPoint[0],
+ hitLocation[2] - previousGlobalPoint[1]);
+
+ if (distance.length() < 0.01f) {
+ // If distance between previous stored point and current point is too
+ // small, skip it
+ return false;
+ }
+
+ // New point is distance + old point
+ PointF p = new PointF(distance.x * localDistanceScale + previousLocalPoint[0],
+ distance.y * localDistanceScale + previousLocalPoint[1]);
+
+ addPoint(p, holdTap.isStartOfScroll);
+ }
+ previousGlobalPoint[0] = hitLocation[0];
+ previousGlobalPoint[1] = hitLocation[1];
+ return true;
+ }
+
+ /**
+ * Constructs the Paths to be drawn (populates the paths List). Call this before drawing this
+ * Finger Painting (every frame).
+ */
+ public void buildPath() {
+ if (points.size() <= 1) {
+ // Don't build anything if the path only contains one point
+ return;
+ }
+
+ paths = new ArrayList<>();
+
+ if (isSmooth) {
+ buildSmooth();
+ } else {
+ buildRough();
+ }
+ }
+
+ /**
+ * @return 16-float matrix that takes a point from Local space to Global space (onto the Plane)
+ */
+ public float[] getModelMatrix() {
+ return modelMatrix;
+ }
+
+ /**
+ * Change currently selected color. Preferably called through a UI element (a menu)
+ * @param color color to be selected this frame
+ */
+ public void setColor(int color) {
+ this.color = color;
+ }
+
+ /**
+ * @return List of built paths contained within this Finger Painting
+ */
+ public List<BuiltPath> getPaths() {
+ return paths;
+ }
+
+ /**
+ * Clears data contained within this Finger Painting
+ */
+ public void reset() {
+ points.clear();
+ jumpPoints.clear();
+ paths.clear();
+ indexColors.clear();
+ }
+
+ /********************** PRIVATE HELPERS **************************************/
+
+ // Adds another point to the path in Local space
+ private void addPoint(PointF p, boolean jumpPoint) {
+ points.add(p);
+ if (jumpPoint) {
+ jumpPoints.add(points.size() - 1);
+ indexColors.put(points.size() - 1, color);
+ }
+ previousLocalPoint[0] = p.x;
+ previousLocalPoint[1] = p.y;
+ }
+
+ // Builds paths of this Finger Painting using the rough algorithm
+ private void buildRough() {
+ int start = 0; // starting index of each path. 1st path starts at index 0 points list
+ for (int j = 1; j < jumpPoints.size(); j++) {
+ int finish = jumpPoints.get(j); // finishing index of current path
+ buildRoughFromTo(start, finish);
+ start = finish;
+ }
+
+ buildRoughFromTo(start, points.size());
+ }
+
+ // Builds paths of this Finger Painting using the smooth algorithm
+ private void buildSmooth() {
+ int start = 0;
+ for (int j = 1; j < jumpPoints.size(); j++) {
+ int finish = jumpPoints.get(j);
+ buildSmoothFromTo(start, finish);
+ start = finish;
+ }
+
+ buildSmoothFromTo(start, points.size());
+ }
+
+ // Builds a rough path that starts at index (start) of the points List, and ends at (finish - 1)
+ // of the points List
+ 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);
+ }
+
+ BuiltPath bp = new BuiltPath(p, c);
+ paths.add(bp);
+ }
+
+ // Builds a smooth path that starts at index (start) of the points List, and ends at (finish - 1)
+ // of the points List
+ private void buildSmoothFromTo(int start, int finish) {
+ Path p = new Path();
+ int c = indexColors.get(start);
+
+ int nbPts = finish - start; // # of points within this path (not including the finish index)
+
+ // If only 2 points in path, draw a line between them
+ if (nbPts == 2) {
+ 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 (3 pts +), essentially run deCasteljau
+ p.moveTo(points.get(start).x, points.get(start).y);
+ p.lineTo((points.get(start).x + points.get(start + 1).x) / 2,
+ (points.get(start).y + points.get(start + 1).y) / 2);
+
+ 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);
+ }
+
+ BuiltPath bp = new BuiltPath(p, c);
+ paths.add(bp);
+ }
+
+ private boolean isEmpty() { return points.isEmpty(); }
+
+ private void setModelMatrix(float[] m) {
+ modelMatrix = m;
+ }
+}
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/HelloCanvasAR.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/HelloCanvasAR.java
index 718545e..d883c69 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/HelloCanvasAR.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/HelloCanvasAR.java
@@ -1,5 +1,5 @@
/*
- * Copyright 2017 Google Inc. All Rights Reserved.
+ * Copyright 2018 Google LLC All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -20,14 +20,13 @@
import android.animation.ValueAnimator;
import android.graphics.Canvas;
import android.graphics.Color;
-import android.graphics.PointF;
import android.graphics.PorterDuff;
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;
@@ -53,12 +52,17 @@
import com.google.ar.core.Session;
import com.google.ar.core.Trackable;
import com.google.ar.core.TrackingState;
-import com.google.ar.core.examples.java.common.helpers.CameraPermissionHelper;
-import com.google.ar.core.examples.java.common.helpers.DisplayRotationHelper;
-import com.google.ar.core.examples.java.common.helpers.FullScreenHelper;
-import com.google.ar.core.examples.java.common.helpers.SnackbarHelper;
-import com.google.ar.core.examples.java.common.helpers.TapHelper;
-import com.google.ar.core.examples.java.common.rendering.BackgroundRenderer;
+
+import com.google.ar.core.examples.java.helloskar.R;
+import com.google.skar.examples.helloskar.helpers.CameraPermissionHelper;
+import com.google.skar.examples.helloskar.helpers.DisplayRotationHelper;
+import com.google.skar.examples.helloskar.helpers.FullScreenHelper;
+import com.google.skar.examples.helloskar.helpers.SnackbarHelper;
+import com.google.skar.examples.helloskar.helpers.TapHelper;
+
+import com.google.skar.examples.helloskar.rendering.BackgroundRenderer;
+import com.google.skar.examples.helloskar.rendering.DrawManager;
+
import com.google.ar.core.exceptions.CameraNotAvailableException;
import com.google.ar.core.exceptions.UnavailableApkTooOldException;
import com.google.ar.core.exceptions.UnavailableArcoreNotInstalledException;
@@ -79,41 +83,33 @@
*/
public class HelloCanvasAR extends AppCompatActivity implements GLSurfaceView.Renderer {
- public enum DrawingType {
- circle, rect, text, animation
- }
-
private static final String TAG = HelloCanvasAR.class.getSimpleName();
+ private final int MAX_NUMBER_DRAWABLES = 50; // Arbitrary limit to the # of anchors to store
- //Simple SurfaceView used to draw 2D objects on top of the GLSurfaceView
- private ARSurfaceView arSurfaceView;
- private Canvas canvas;
+ // Simple SurfaceView used to draw 2D objects on top of the GLSurfaceView
+ private CanvasARSurfaceView arSurfaceView;
private SurfaceHolder holder;
- //GLSurfaceView used to draw 3D objects & camera input
+ // GLSurfaceView used to draw 3D objects & camera input
private GLSurfaceView glSurfaceView;
- //ARSession
+ // ARSession
private Session session;
- private boolean installRequested;
- private final SnackbarHelper messageSnackbarHelper = new SnackbarHelper();
- private DisplayRotationHelper displayRotationHelper;
- private TapHelper tapHelper;
-
// OpenGL background renderer
private final BackgroundRenderer backgroundRenderer = new BackgroundRenderer();
// 2D Renderer
private DrawManager drawManager = new DrawManager();
- private DrawingType currentDrawabletype = DrawingType.circle;
- private boolean drawSmoothPainting = true;
+
+ private boolean installRequested;
+ private final SnackbarHelper messageSnackbarHelper = new SnackbarHelper();
+ private DisplayRotationHelper displayRotationHelper;
+ private TapHelper tapHelper;
// Temporary matrix allocated here to reduce number of allocations for each frame.
private final float[] anchorMatrix = new float[16];
- PointF previousEvent;
-
// Anchors created from taps used for object placing.
private final ArrayList<Anchor> anchors = new ArrayList<>();
@@ -127,22 +123,22 @@
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
- Toolbar myToolbar = (Toolbar) findViewById(R.id.my_toolbar);
- setSupportActionBar(myToolbar);
+ // Menu tool bar set up
+ Toolbar toolbar = findViewById(R.id.main_toolbar);
+ setSupportActionBar(toolbar);
-
- //hide notifications bar
+ // Hide notifications bar
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
- arSurfaceView = findViewById(R.id.arsurfaceview);
- glSurfaceView = findViewById(R.id.glsurfaceview);
+ // Canvas Surface View set up
+ arSurfaceView = findViewById(R.id.canvas_surfaceview);
arSurfaceView.bringToFront();
arSurfaceView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
- displayRotationHelper = new DisplayRotationHelper(/*context=*/ this);
+ holder = arSurfaceView.getHolder();
// Set up tap listener.
- tapHelper = new TapHelper(/*context=*/ this);
+ tapHelper = new TapHelper(this);
glSurfaceView.setOnTouchListener(tapHelper);
// Set up renderer.
@@ -151,9 +147,10 @@
glSurfaceView.setEGLConfigChooser(8, 8, 8, 8, 16, 0); // Alpha used for plane blending.
glSurfaceView.setRenderer(this);
glSurfaceView.setRenderMode(GLSurfaceView.RENDERMODE_CONTINUOUSLY);
-
+ displayRotationHelper = new DisplayRotationHelper(this);
installRequested = false;
+ // Set up finger painting palette bar
BottomNavigationView bottomNav = findViewById(R.id.palette);
bottomNav.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
@Override
@@ -174,7 +171,7 @@
}
});
- // Animator set up
+ // Value Animator set up
PropertyValuesHolder propertyRadius = PropertyValuesHolder.ofFloat(PROPERTY_RADIUS, 0, 0.5f);
animator = new ValueAnimator();
animator.setValues(propertyRadius);
@@ -310,7 +307,7 @@
@Override
public void onDrawFrame(GL10 gl) {
- canvas = null;
+ Canvas canvas = null;
holder = null;
// Clear screen to notify driver it should not load any pixels from previous frame.
@@ -319,38 +316,18 @@
if (session == null) {
return;
}
+
// Notify ARCore session that the view size changed so that the perspective matrix and
// the video background can be properly adjusted.
displayRotationHelper.updateSessionIfNeeded(session);
-
try {
session.setCameraTextureName(backgroundRenderer.getTextureId());
Frame frame = session.update();
Camera camera = frame.getCamera();
- MotionEvent tap = tapHelper.poll();
- if (tap != null && camera.getTrackingState() == TrackingState.TRACKING) {
- for (HitResult hit : frame.hitTest(tap)) {
- // 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.
- if ((trackable instanceof Plane
- && ((Plane) trackable).isPoseInPolygon(hit.getHitPose())
- && (DrawManager.calculateDistanceToPlane(hit.getHitPose(), camera.getPose())
- > 0))
- || (trackable instanceof Point
- && ((Point) trackable).getOrientationMode()
- == OrientationMode.ESTIMATED_SURFACE_NORMAL)) {
- if (anchors.size() >= 20) {
- anchors.get(0).detach();
- anchors.remove(0);
- }
- anchors.add(hit.createAnchor());
- break;
- }
- }
- }
+ // Query information from single tap gestures to get anchors
+ handleSingleTaps(frame, camera);
// Draw background with OpenGL.
// TODO: possibly find a way to extract texture and draw on Canvas
@@ -362,76 +339,26 @@
}
// Get projection matrix.
- float[] projmtx = new float[16];
- camera.getProjectionMatrix(projmtx, 0, 0.1f, 100.0f);
- drawManager.updateProjectionMatrix(projmtx);
+ float[] projMatrix = new float[16];
+ camera.getProjectionMatrix(projMatrix, 0, 0.1f, 100.0f);
+ drawManager.updateProjectionMatrix(projMatrix);
// Get camera matrix and draw.
- float[] viewmtx = new float[16];
- camera.getViewMatrix(viewmtx, 0);
- drawManager.updateViewMatrix(viewmtx);
+ float[] viewMatrix = new float[16];
+ camera.getViewMatrix(viewMatrix, 0);
+ drawManager.updateViewMatrix(viewMatrix);
final float[] colorCorrectionRgba = new float[4];
frame.getLightEstimate().getColorCorrection(colorCorrectionRgba, 0);
drawManager.updateLightColorFilter(colorCorrectionRgba);
- // Building finger painting
- TapHelper.ScrollEvent holdTap = tapHelper.holdPoll();
- if (holdTap != null && camera.getTrackingState() == TrackingState.TRACKING) {
- 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.
- if ((trackable instanceof Plane
- && ((Plane) trackable).isPoseInPolygon(hit.getHitPose())
- && (DrawManager.calculateDistanceToPlane(hit.getHitPose(), camera.getPose())
- > 0))
- || (trackable instanceof Point
- && ((Point) trackable).getOrientationMode()
- == OrientationMode.ESTIMATED_SURFACE_NORMAL)) {
-
- // Get hit point transform, apply it to the origin
- float[] gm = new float[16];
- hit.getHitPose().toMatrix(gm, 0);
- float[] point = {0, 0, 0, 1};
- Matrix.multiplyMV(point, 0, gm, 0, point, 0);
-
- if (drawManager.fingerPainting.isEmpty()) {
- drawManager.fingerPainting.addPoint(new PointF(0, 0), true);
-
- // Get model matrix of first point
- float[] m = new float[16];
- hit.getHitPose().toMatrix(m, 0);
- drawManager.fingerPainting.setModelMatrix(m);
- } else {
- float localDistanceScale = 1000;
- PointF distance = new PointF(point[0] - previousEvent.x,
- point[2] - previousEvent.y);
-
- if (distance.length() < 0.05f) {
- continue;
- }
-
- // New point is distance + old point
- PointF p = new PointF(distance.x * localDistanceScale
- + drawManager.fingerPainting.previousPoint.x,
- distance.y * localDistanceScale
- + drawManager.fingerPainting.previousPoint.y);
-
- drawManager.fingerPainting.addPoint(p, holdTap.isStartOfScroll);
- }
-
- previousEvent = new PointF(point[0], point[2]);
- break;
- }
- }
- }
+ // Query information from scrolling gestures to build finger paintings
+ handleHoldTaps(frame, camera);
// Drawing on Canvas (SurfaceView)
if (arSurfaceView.isRunning()) {
// Lock canvas
- SurfaceHolder holder = arSurfaceView.getHolder();
- Canvas canvas = holder.lockHardwareCanvas();
+ canvas = holder.lockHardwareCanvas();
canvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
// Draw point cloud
@@ -472,6 +399,81 @@
}
}
+ /**************************** Gesture helpers ******************************/
+ /**
+ * Given a Frame and a Camera, perform hit tests on stored UI touch events. If a hit test is
+ * successful, construct an Anchor at the hit position and add it to the set of anchors.
+ * @param frame Frame of this update() call
+ * @param camera Camera of this update() call
+ */
+ private void handleSingleTaps(Frame frame, Camera camera) {
+ MotionEvent tap = tapHelper.poll();
+ if (tap != null && camera.getTrackingState() == TrackingState.TRACKING) {
+ for (HitResult hit : frame.hitTest(tap)) {
+ // 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.
+ if ((trackable instanceof Plane
+ && ((Plane) trackable).isPoseInPolygon(hit.getHitPose())
+ && (DrawManager.calculateDistanceToPlane(hit.getHitPose(), camera.getPose())
+ > 0))
+ || (trackable instanceof Point
+ && ((Point) trackable).getOrientationMode()
+ == OrientationMode.ESTIMATED_SURFACE_NORMAL)) {
+ if (anchors.size() >= MAX_NUMBER_DRAWABLES) {
+ anchors.get(0).detach();
+ anchors.remove(0);
+ }
+ anchors.add(hit.createAnchor());
+ break;
+ }
+ }
+ }
+ }
+
+ /**
+ * Given a Frame and a Camera, perform hit tests on stored UI touch events. If a hit test is
+ * successful, construct an Anchor at the hit position and add it to the set of anchors.
+ * @param frame Frame of this update() call
+ * @param camera Camera of this update() call
+ */
+ private void handleHoldTaps(Frame frame, Camera camera) {
+ // Building finger painting
+ TapHelper.ScrollEvent holdTap = tapHelper.holdPoll();
+ if (holdTap != null && camera.getTrackingState() == TrackingState.TRACKING) {
+ 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.
+ if ((trackable instanceof Plane
+ && ((Plane) trackable).isPoseInPolygon(hit.getHitPose())
+ && (DrawManager.calculateDistanceToPlane(hit.getHitPose(), camera.getPose())
+ > 0))
+ || (trackable instanceof Point
+ && ((Point) trackable).getOrientationMode()
+ == OrientationMode.ESTIMATED_SURFACE_NORMAL)) {
+
+ // Get hit point transform, apply it to the origin --> point is not in hit
+ // location on the plane
+ float[] modelMatrix = new float[16];
+ hit.getHitPose().toMatrix(modelMatrix, 0);
+ float[] hitLocation = {0, 0, 0, 1};
+ Matrix.multiplyMV(hitLocation, 0, modelMatrix, 0,
+ hitLocation, 0);
+
+ if (! drawManager.fingerPainting.computeNextPoint(hitLocation, holdTap)) {
+ // Try to add the next point to the finger painting. If return value
+ // is false, then keep looping
+ continue;
+ }
+
+ break;
+ }
+ }
+ }
+ }
+
+ /**************************** Drawing helpers ******************************/
// Helper drawing functions that invoke drawManager
private void drawPlanes(Canvas canvas, Camera camera) {
drawManager.drawPlanes(canvas, camera.getPose(), session.getAllTrackables(Plane.class));
@@ -486,12 +488,11 @@
if (anchor.getTrackingState() != TrackingState.TRACKING) {
continue;
}
- // Get the current pose of an Anchor in world space. The Anchor pose is updated
- // during calls to session.update() as ARCore refines its estimate of the world.
+ // Get the current pose of an Anchor in world space
anchor.getPose().toMatrix(anchorMatrix, 0);
drawManager.modelMatrices.add(0, anchorMatrix);
- switch (currentDrawabletype) {
+ switch (drawManager.currentDrawabletype) {
case circle:
drawManager.drawCircle(canvas);
break;
@@ -512,11 +513,12 @@
}
private void drawFingerPainting(Canvas canvas) {
- drawManager.fingerPainting.setSmoothness(drawSmoothPainting);
+ drawManager.fingerPainting.setSmoothness(drawManager.drawSmoothPainting);
drawManager.drawFingerPainting(canvas);
}
- // Menu functions
+ /**************************** UI helpers ******************************/
+ // Tool bar functions
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main_menu, menu);
@@ -529,22 +531,22 @@
drawManager.fingerPainting.reset();
return true;
case R.id.smooth_paint:
- drawSmoothPainting = true;
+ drawManager.drawSmoothPainting = true;
return true;
case R.id.rough_paint:
- drawSmoothPainting = false;
+ drawManager.drawSmoothPainting = false;
return true;
case R.id.draw_circle:
- currentDrawabletype = DrawingType.circle;
+ drawManager.currentDrawabletype = DrawManager.DrawingType.circle;
return true;
case R.id.draw_rect:
- currentDrawabletype = DrawingType.rect;
+ drawManager.currentDrawabletype = DrawManager.DrawingType.rect;
return true;
case R.id.draw_animation:
- currentDrawabletype = DrawingType.animation;
+ drawManager.currentDrawabletype = DrawManager.DrawingType.animation;
return true;
case R.id.draw_text:
- currentDrawabletype = DrawingType.text;
+ drawManager.currentDrawabletype = DrawManager.DrawingType.text;
return true;
default:
return super.onOptionsItemSelected(item);
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/SkARFingerPainting.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/SkARFingerPainting.java
deleted file mode 100644
index eac2a6b..0000000
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/app/SkARFingerPainting.java
+++ /dev/null
@@ -1,155 +0,0 @@
-package com.google.skar.examples.helloskar.app;
-
-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.
- private ArrayList<PointF> points = new ArrayList<>();
- private ArrayList<Integer> jumpPoints = new ArrayList<>();
- private Map<Integer, Integer> indexColors = new HashMap<>();
- private Map<Path, Integer> pathColors = new HashMap<>();
- private ArrayList<Path> 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;
-
- // Holds the model matrix of the first point added to such that the path can be drawn at the
- // model location (i.e on the Plane)
- private float[] modelMatrix;
-
- private boolean isSmooth;
-
- public SkARFingerPainting(boolean smooth) {
- this.isSmooth = smooth;
- }
-
- public boolean getSmoothness() {
- return isSmooth;
- }
-
- public void setSmoothness(boolean smooth) {
- isSmooth = smooth;
- }
-
- // Adds another point to the path in Local space
- 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() {
- paths = new ArrayList<>();
- if (points.size() <= 1) {
- return;
- }
-
-
- if (isSmooth) {
- int start = 0;
- for (int j = 1; j < jumpPoints.size(); j++) {
-
- int finish = jumpPoints.get(j);
- buildSmoothFromTo(start, finish);
- start = finish;
- }
-
- buildSmoothFromTo(start, points.size());
- } else {
-
- 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);
- p.lineTo((points.get(start).x + points.get(start + 1).x) / 2,
- (points.get(start).y + points.get(start + 1).y) / 2);
-
- 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 points.isEmpty();
- }
-
- public float[] getModelMatrix() {
- return modelMatrix;
- }
-
- public void setModelMatrix(float[] m) {
- modelMatrix = m;
- }
-
- public void setColor(int color) {
- this.color = color;
- }
-
- public int getPathColor(Path p) {
- return pathColors.get(p);
- }
-
- public ArrayList<Path> getPaths() {
- return paths;
- }
-
- public void reset() {
- points.clear();
- jumpPoints.clear();
- paths.clear();
- pathColors.clear();
- indexColors.clear();
- }
-}
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/CameraPermissionHelper.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/CameraPermissionHelper.java
index f8e9c33..9cab829 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/CameraPermissionHelper.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/CameraPermissionHelper.java
@@ -1,10 +1,11 @@
/*
- * Copyright 2017 Google Inc. All Rights Reserved.
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -12,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.google.skar.examples.helloskar.helpers;
import android.Manifest;
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/DisplayRotationHelper.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/DisplayRotationHelper.java
index 7e4ce81..0f06094 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/DisplayRotationHelper.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/DisplayRotationHelper.java
@@ -1,10 +1,11 @@
/*
- * Copyright 2017 Google Inc. All Rights Reserved.
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -12,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.google.skar.examples.helloskar.helpers;
import android.app.Activity;
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/FullScreenHelper.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/FullScreenHelper.java
index 3738b96..6951459 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/FullScreenHelper.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/FullScreenHelper.java
@@ -1,10 +1,11 @@
/*
- * Copyright 2017 Google Inc. All Rights Reserved.
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -12,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.google.skar.examples.helloskar.helpers;
import android.app.Activity;
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/SnackbarHelper.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/SnackbarHelper.java
index 0239349..6294f93 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/SnackbarHelper.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/SnackbarHelper.java
@@ -1,10 +1,11 @@
/*
- * Copyright 2017 Google Inc. All Rights Reserved.
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -12,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.google.skar.examples.helloskar.helpers;
import android.app.Activity;
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/TapHelper.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/TapHelper.java
index bcbfe2a..6dcfd8f 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/TapHelper.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/helpers/TapHelper.java
@@ -1,10 +1,11 @@
/*
- * Copyright 2017 Google Inc. All Rights Reserved.
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -12,19 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.google.skar.examples.helloskar.helpers;
import android.content.Context;
-import android.util.Log;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
-
-import java.util.ArrayDeque;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Queue;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@@ -72,7 +68,9 @@
if (e2.getPointerCount() == 1 && e1.getPointerCount() == 1) {
previousScroll = isScrolling;
isScrolling = true;
- queuedFingerHold.offer(new ScrollEvent(e2, startedScrolling()));
+
+ queuedFingerHold.offer(new ScrollEvent(e2, isStartedScrolling()));
+
return true;
}
return false;
@@ -97,10 +95,6 @@
public ScrollEvent holdPoll() { return queuedFingerHold.poll(); }
- public boolean startedScrolling() {
- return isScrolling && !previousScroll;
- }
-
@Override
public boolean onTouch(View view, MotionEvent motionEvent) {
boolean val = gestureDetector.onTouchEvent(motionEvent);
@@ -113,4 +107,5 @@
}
return val;
}
+ private boolean isStartedScrolling() { return isScrolling && !previousScroll; }
}
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/BackgroundRenderer.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/BackgroundRenderer.java
index b6b5a85..acf3dc5 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/BackgroundRenderer.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/BackgroundRenderer.java
@@ -1,10 +1,11 @@
/*
- * Copyright 2017 Google Inc. All Rights Reserved.
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -12,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.google.skar.examples.helloskar.rendering;
import android.content.Context;
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/DrawManager.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/DrawManager.java
index 2ef85b0..35bcf70 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/DrawManager.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/DrawManager.java
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.google.skar.examples.helloskar.rendering;
import android.content.Context;
@@ -21,7 +37,8 @@
import com.google.ar.core.TrackingState;
import com.google.skar.CanvasMatrixUtil;
import com.google.skar.PaintUtil;
-import com.google.skar.SkARFingerPainting;
+import com.google.skar.examples.helloskar.app.FingerPainting;
+
import java.io.IOException;
import java.nio.FloatBuffer;
import java.util.ArrayList;
@@ -34,6 +51,14 @@
*/
public class DrawManager {
+ public enum DrawingType {
+ circle, rect, text, animation
+ }
+
+ // App defaults
+ public DrawManager.DrawingType currentDrawabletype = DrawManager.DrawingType.circle;
+ public boolean drawSmoothPainting = true;
+
private float[] projectionMatrix = new float[16];
private float[] viewMatrix = new float[16];
private float viewportWidth;
@@ -41,7 +66,7 @@
private ColorFilter lightFilter;
private BitmapShader planeShader;
public ArrayList<float[]> modelMatrices = new ArrayList<>();
- public SkARFingerPainting fingerPainting = new SkARFingerPainting(false);
+ public FingerPainting fingerPainting = new FingerPainting(false);
public void updateViewport(float width, float height) {
viewportWidth = width;
@@ -165,11 +190,11 @@
p.setStrokeWidth(30f);
p.setAlpha(120);
- for (Path path : fingerPainting.getPaths()) {
- if (path.isEmpty()) {
+ for (FingerPainting.BuiltPath bp : fingerPainting.getPaths()) {
+ if (bp.path.isEmpty()) {
continue;
}
- p.setColor(fingerPainting.getPathColor(path));
+ p.setColor(bp.color);
// Scaling issues appear to happen when drawing a Path and transforming the Canvas
// directly with a matrix on Android versions less than P. Ideally we would
@@ -179,12 +204,12 @@
// Transform applied through canvas
canvas.save();
canvas.setMatrix(mvpv);
- canvas.drawPath(path, p);
+ canvas.drawPath(bp.path, p);
canvas.restore();
} else {
// Transform path directly
Path pathDst = new Path();
- path.transform(mvpv, pathDst);
+ bp.path.transform(mvpv, pathDst);
// Draw dest path
canvas.save();
diff --git a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/ShaderUtil.java b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/ShaderUtil.java
index ce33a45..468b47d 100644
--- a/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/ShaderUtil.java
+++ b/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/examples/helloskar/rendering/ShaderUtil.java
@@ -1,10 +1,11 @@
/*
- * Copyright 2017 Google Inc. All Rights Reserved.
+ * Copyright 2018 Google LLC All Rights Reserved.
+ *
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * 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,
@@ -12,6 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
+
package com.google.skar.examples.helloskar.rendering;
import android.content.Context;
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 d1737c5..a08144a 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
@@ -18,14 +18,14 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto"
- tools:context="com.google.ar.core.examples.java.helloskar.HelloCanvasAR">
+ tools:context="com.google.skar.examples.helloskar.app.HelloCanvasAR">
<FrameLayout
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.Toolbar
- android:id="@+id/my_toolbar"
+ android:id="@+id/main_toolbar"
android:layout_width="match_parent"
android:layout_height="?attr/actionBarSize"
android:background="?attr/colorPrimary"
@@ -33,13 +33,13 @@
android:theme="@style/ThemeOverlay.AppCompat.ActionBar"
app:popupTheme="@style/ThemeOverlay.AppCompat.Light"/>
- <com.google.ar.core.examples.java.helloskar.ARSurfaceView
- android:id="@+id/arsurfaceview"
+ <com.google.skar.examples.helloskar.app.CanvasARSurfaceView
+ android:id="@+id/canvas_surfaceview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.opengl.GLSurfaceView
- android:id="@+id/glsurfaceview"
+ android:id="@+id/gl_surfaceview"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<android.support.design.widget.BottomNavigationView