SkAR Java: DrawManager dox and minor changes, removed unnecessary files

Bug: skia:
Change-Id: If1a92c5b70d99233208f7db74f5dda9641b1c65b
Reviewed-on: https://skia-review.googlesource.com/144027
Reviewed-by: Mike Reed <reed@google.com>
This commit is contained in:
ziadb 2018-07-27 13:16:21 -04:00 committed by Ziad Ben Hadj-Alouane
parent 6fc3092af1
commit 55e553525d
14 changed files with 163 additions and 172 deletions

View File

@ -1,6 +1,7 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2016 Google Inc.
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -14,6 +15,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.google.ar.core.examples.java.helloskar">

View File

@ -1,31 +0,0 @@
/*
* Copyright 2017 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.
*/
precision highp float;
uniform sampler2D u_Texture;
uniform vec4 u_dotColor;
uniform vec4 u_lineColor;
uniform vec4 u_gridControl; // dotThreshold, lineThreshold, lineFadeShrink, occlusionShrink
varying vec3 v_TexCoordAlpha;
void main() {
vec4 control = texture2D(u_Texture, v_TexCoordAlpha.xy);
float dotScale = v_TexCoordAlpha.z;
float lineFade = max(0.0, u_gridControl.z * v_TexCoordAlpha.z - (u_gridControl.z - 1.0));
vec3 color = (control.r * dotScale > u_gridControl.x) ? u_dotColor.rgb
: (control.g > u_gridControl.y) ? u_lineColor.rgb * lineFade
: (u_lineColor.rgb * 0.25 * lineFade) ;
gl_FragColor = vec4(color, v_TexCoordAlpha.z * u_gridControl.w);
}

View File

@ -1,40 +0,0 @@
/*
* Copyright 2017 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.
*/
uniform mat4 u_Model;
uniform mat4 u_ModelViewProjection;
uniform mat2 u_PlaneUvMatrix;
uniform vec3 u_Normal;
attribute vec3 a_XZPositionAlpha; // (x, z, alpha)
varying vec3 v_TexCoordAlpha;
void main() {
vec4 local_pos = vec4(a_XZPositionAlpha.x, 0.0, a_XZPositionAlpha.y, 1.0);
vec4 world_pos = u_Model * local_pos;
// Construct two vectors that are orthogonal to the normal.
// This arbitrary choice is not co-linear with either horizontal
// or vertical plane normals.
const vec3 arbitrary = vec3(1.0, 1.0, 0.0);
vec3 vec_u = normalize(cross(u_Normal, arbitrary));
vec3 vec_v = normalize(cross(u_Normal, vec_u));
// Project vertices in world frame onto vec_u and vec_v.
vec2 uv = vec2(dot(world_pos.xyz, vec_u), dot(world_pos.xyz, vec_v));
v_TexCoordAlpha = vec3(u_PlaneUvMatrix * uv, a_XZPositionAlpha.z);
gl_Position = u_ModelViewProjection * local_pos;
}

View File

@ -1,21 +0,0 @@
/*
* Copyright 2017 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.
*/
precision mediump float;
varying vec4 v_Color;
void main() {
gl_FragColor = v_Color;
}

View File

@ -1,28 +0,0 @@
/*
* Copyright 2017 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.
*/
uniform mat4 u_ModelViewProjection;
uniform vec4 u_Color;
uniform float u_PointSize;
attribute vec4 a_Position;
varying vec4 v_Color;
void main() {
v_Color = u_Color;
gl_Position = u_ModelViewProjection * vec4(a_Position.xyz, 1.0);
gl_PointSize = u_PointSize;
}

View File

@ -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.
* You may obtain a copy of the License at
@ -12,6 +12,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#extension GL_OES_EGL_image_external : require
precision mediump float;

View File

@ -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.
* You may obtain a copy of the License at

View File

@ -514,6 +514,7 @@ public class HelloCanvasAR extends AppCompatActivity implements GLSurfaceView.Re
private void drawFingerPainting(Canvas canvas) {
drawManager.fingerPainting.setSmoothness(drawManager.drawSmoothPainting);
drawManager.fingerPainting.buildPath();
drawManager.drawFingerPainting(canvas);
}

View File

@ -46,7 +46,7 @@ import java.util.Collection;
/**
* Sample class that handles drawing different types of geometry using the matrices provided
* by ARCore. The matrices are handled by SkARMatrix in order to be passed to the drawing
* by ARCore. The matrices are handled by CanvasMatrixUtil in order to be passed to the drawing
* Canvas.
*/
@ -59,15 +59,32 @@ public class DrawManager {
public DrawManager.DrawingType currentDrawabletype = DrawManager.DrawingType.circle;
public boolean drawSmoothPainting = true;
// Camera matrices + viewport info
private float[] projectionMatrix = new float[16];
private float[] viewMatrix = new float[16];
private float viewportWidth;
private float viewportHeight;
// Paint modifiers
private ColorFilter lightFilter;
private BitmapShader planeShader;
// Drawables info
public ArrayList<float[]> modelMatrices = new ArrayList<>();
public FingerPainting fingerPainting = new FingerPainting(false);
/************ Initilization calls ****************************/
public void initializePlaneShader(Context context, String gridDistanceTextureName)
throws IOException {
// Read the texture.
Bitmap planeTexture =
BitmapFactory.decodeStream(context.getAssets().open(gridDistanceTextureName));
// Set up the shader
planeShader = new BitmapShader(planeTexture, Shader.TileMode.REPEAT,
Shader.TileMode.REPEAT););
}
/************ ARCore onDrawFrame() calls ********************/
public void updateViewport(float width, float height) {
viewportWidth = width;
viewportHeight = height;
@ -85,11 +102,14 @@ public class DrawManager {
lightFilter = PaintUtil.createLightCorrectionColorFilter(colorCorr);
}
/********** 2D objects drawing functions **********************/
// Sample function for drawing a circle
public void drawCircle(Canvas canvas) {
if (modelMatrices.isEmpty()) {
return;
}
Paint p = new Paint();
p.setColorFilter(lightFilter);
p.setARGB(180, 100, 0, 0);
@ -103,7 +123,8 @@ public class DrawManager {
canvas.restore();
}
// Sample function for drawing an animated round rect
// Sample function for drawing an animated round rect.
// Radius parameter is animated by the application
public void drawAnimatedRoundRect(Canvas canvas, float radius) {
if (modelMatrices.isEmpty()) {
return;
@ -127,6 +148,7 @@ public class DrawManager {
Paint p = new Paint();
p.setColorFilter(lightFilter);
p.setARGB(180, 0, 0, 255);
canvas.save();
canvas.setMatrix(CanvasMatrixUtil.createPerspectiveMatrix(modelMatrices.get(0),
viewMatrix, projectionMatrix, viewportWidth, viewportHeight));
@ -146,22 +168,23 @@ public class DrawManager {
p.setARGB(255, 0, 255, 0);
p.setTextSize(textSize);
// TODO: Remove scale matrix and scale text directly. Potential unfixed bug in versions < P
float[] scaleMatrix = getTextScaleMatrix(textSize);
float[] rotateMatrix = CanvasMatrixUtil.createXYtoXZRotationMatrix();
float[][] matrices = { scaleMatrix, rotateMatrix, modelMatrices.get(0), viewMatrix,
projectionMatrix,
CanvasMatrixUtil.createViewportMatrix(viewportWidth, viewportHeight)};
projectionMatrix,
CanvasMatrixUtil.createViewportMatrix(viewportWidth,
viewportHeight)};
canvas.save();
canvas.setMatrix(CanvasMatrixUtil.createMatrixFrom4x4(CanvasMatrixUtil.multiplyMatrices4x4(matrices)));
canvas.setMatrix(CanvasMatrixUtil.createMatrixFrom4x4(
CanvasMatrixUtil.multiplyMatrices4x4(matrices)));
canvas.drawText(text, 0, 0, p);
canvas.restore();
}
// Sample function for drawing a built FingerPainting object
public void drawFingerPainting(Canvas canvas) {
// Build the path before rendering
fingerPainting.buildPath();
// If path empty, return
if (fingerPainting.getPaths().isEmpty()) {
return;
@ -169,20 +192,24 @@ public class DrawManager {
// Get finger painting model matrix
float[] model = fingerPainting.getModelMatrix();
float[] in = new float[16];
Matrix.setIdentityM(in, 0);
Matrix.translateM(in, 0, model[12], model[13], model[14]);
float[] modelTranslate = new float[16]; // stores translate components of model matrix
Matrix.setIdentityM(modelTranslate, 0);
Matrix.translateM(modelTranslate, 0, model[12], model[13], model[14]);
// Rotation onto plane
float[] initRot = CanvasMatrixUtil.createXYtoXZRotationMatrix();
// Arbitrary scale for the finger painting
float[] scale = new float[16];
float s = 0.001f;
Matrix.setIdentityM(scale, 0);
Matrix.scaleM(scale, 0, s, s, s);
// Matrix = mvpv
float[][] matrices = {scale, initRot, in, viewMatrix, projectionMatrix, CanvasMatrixUtil.createViewportMatrix(viewportWidth, viewportHeight)};
android.graphics.Matrix mvpv = CanvasMatrixUtil.createMatrixFrom4x4(CanvasMatrixUtil.multiplyMatrices4x4(matrices));
// Matrix = mvpv (model, view, projection, viewport)
float[][] matrices = {scale, initRot, modelTranslate, viewMatrix, projectionMatrix,
CanvasMatrixUtil.createViewportMatrix(viewportWidth, viewportHeight)};
android.graphics.Matrix mvpv =
CanvasMatrixUtil.createMatrixFrom4x4(CanvasMatrixUtil.multiplyMatrices4x4(matrices));
// Paint set up
Paint p = new Paint();
@ -194,11 +221,12 @@ public class DrawManager {
if (bp.path.isEmpty()) {
continue;
}
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
// switch true to be (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
// directly with a matrix on Android versions less than P.
// TODO: Ideally switch true to be (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
if (true) {
// Transform applied through canvas
@ -221,14 +249,19 @@ public class DrawManager {
}
/*********************** AR Environment drawing functions *************************/
// Sample function for drawing the AR point cloud
public void drawPointCloud(Canvas canvas, PointCloud cloud) {
FloatBuffer points = cloud.getPoints();
int numberOfPoints = points.remaining() / 4;
float[][] matrices = {viewMatrix, projectionMatrix, CanvasMatrixUtil.createViewportMatrix(viewportWidth, viewportHeight)};
// Build vpv matrix
float[][] matrices = {viewMatrix, projectionMatrix,
CanvasMatrixUtil.createViewportMatrix(viewportWidth, viewportHeight)};
float[] vpv = CanvasMatrixUtil.multiplyMatrices4x4(matrices);
// Transform points on CPU
float[] pointsToDraw = new float[numberOfPoints * 2];
for (int i = 0; i < numberOfPoints; i++) {
float[] point = {points.get(i * 4), points.get(i * 4 + 1), points.get(i * 4 + 2), 1};
@ -243,10 +276,7 @@ public class DrawManager {
p.setStrokeWidth(6.0f);
canvas.save();
float[] id = new float[16];
Matrix.setIdentityM(id, 0);
android.graphics.Matrix identity = CanvasMatrixUtil.createMatrixFrom4x4(id);
canvas.setMatrix(identity);
canvas.setMatrix(new android.graphics.Matrix());
canvas.drawPoints(pointsToDraw, p);
canvas.restore();
}
@ -277,15 +307,18 @@ public class DrawManager {
float[] initRot = CanvasMatrixUtil.createXYtoXZRotationMatrix();
// Matrix = mvpv
float[][] matrices = {initRot, model, viewMatrix, projectionMatrix, CanvasMatrixUtil.createViewportMatrix(viewportWidth, viewportHeight)};
android.graphics.Matrix mvpv = CanvasMatrixUtil.createMatrixFrom4x4(CanvasMatrixUtil.multiplyMatrices4x4(matrices));
float[][] matrices = {initRot, model, viewMatrix, projectionMatrix,
CanvasMatrixUtil.createViewportMatrix(viewportWidth,
viewportHeight)};
android.graphics.Matrix mvpv = CanvasMatrixUtil.createMatrixFrom4x4(
CanvasMatrixUtil.multiplyMatrices4x4(matrices));
drawPlaneAsPath(canvas, mvpv, plane);
drawPlaneOutline(canvas, mvpv, plane);
}
}
// Helper function that draws an AR plane using a path
private void drawPlaneAsPath(Canvas canvas, android.graphics.Matrix mvpv, Plane plane) {
// Helper function that draws an AR plane's outline using a path
private void drawPlaneOutline(Canvas canvas, android.graphics.Matrix mvpv, Plane plane) {
int vertsSize = plane.getPolygon().limit() / 2;
FloatBuffer polygon = plane.getPolygon();
polygon.rewind();
@ -300,24 +333,66 @@ public class DrawManager {
// Set up paint
Paint p = new Paint();
if (false) {
//p.setShader(planeShader);
p.setColorFilter(new PorterDuffColorFilter(Color.argb(0.4f, 1, 0, 0),
PorterDuff.Mode.SRC_ATOP));
}
p.setColor(Color.RED);
p.setAlpha(100);
p.setStrokeWidth(0.01f);
p.setStyle(Paint.Style.STROKE);
// Scaling issues appear to happen when drawing a Path and transforming the Canvas
// directly with a matrix on Android versions less than P.
// TODO: Ideally switch true to be (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
if (true) {
// Draw dest path
canvas.save();
canvas.setMatrix(mvpv);
canvas.drawPath(pathSrc, p);
canvas.restore();
} else {
// Build destination path by transforming source path
Path pathDst = new Path();
pathSrc.transform(mvpv, pathDst);
// Draw dest path
canvas.save();
canvas.setMatrix(new android.graphics.Matrix());
canvas.drawPath(pathDst, p);
canvas.restore();
}
}
// Helper function that draws an AR plane using a path + initialized shader
private void drawPlaneWithShader(Canvas canvas, android.graphics.Matrix mvpv, Plane plane) {
int vertsSize = plane.getPolygon().limit() / 2;
FloatBuffer polygon = plane.getPolygon();
polygon.rewind();
// Build source path from polygon data
Path pathSrc = new Path();
pathSrc.moveTo(polygon.get(0), polygon.get(1));
for (int i = 1; i < vertsSize; i++) {
pathSrc.lineTo(polygon.get(i * 2), polygon.get(i * 2 + 1));
}
pathSrc.close();
// Set up paint
Paint p = new Paint();
p.setShader(planeShader);
p.setColorFilter(new PorterDuffColorFilter(Color.argb(0.4f, 1, 0, 0),
PorterDuff.Mode.SRC_ATOP));
p.setColor(Color.RED);
p.setAlpha(100);
p.setStrokeWidth(0.01f);
// Scaling issues appear to happen when drawing a Path and transforming the Canvas
// directly with a matrix on Android versions less than P.
// TODO: Ideally switch true to be (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P)
if (true) {
// Shader local matrix
android.graphics.Matrix lm = new android.graphics.Matrix();
lm.setScale(0.00005f, 0.00005f);
planeShader.setLocalMatrix(lm);
// Draw dest path
canvas.save();
canvas.setMatrix(mvpv);
@ -342,15 +417,9 @@ public class DrawManager {
}
}
public void initializePlaneShader(Context context, String gridDistanceTextureName) throws IOException {
// Read the texture.
Bitmap planeTexture =
BitmapFactory.decodeStream(context.getAssets().open(gridDistanceTextureName));
// Set up the shader
planeShader = new BitmapShader(planeTexture, Shader.TileMode.REPEAT, Shader.TileMode.REPEAT);
planeShader.setLocalMatrix(new android.graphics.Matrix());
}
/*************** Misc helpers *************************************/
// Returns a scale matrix for drawing text given the size of the text. Workaround that solves
// a text size bug not fixed in Android versions < P
private float[] getTextScaleMatrix(float size) {
float scaleFactor = 1 / (size * 10);
float[] initScale = new float[16];
@ -364,6 +433,7 @@ public class DrawManager {
float cameraX = cameraPose.tx();
float cameraY = cameraPose.ty();
float cameraZ = cameraPose.tz();
// Get transformed Y axis of plane's coordinate system.
planePose.getTransformedAxis(1, 1.0f, normal, 0);
// Compute dot product of plane's normal with vector from camera to plane center.

View File

@ -1,5 +1,5 @@
<!--
Copyright 2016 Google Inc.
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -13,6 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"

View File

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 Google LLC
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.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<group
android:id="@+id/menu_top">

View File

@ -1,4 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 Google LLC
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.
-->
<menu xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:id="@+id/palette_red"

View File

@ -1,5 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright 2016 Google Inc.
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -13,6 +15,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<string name="app_name">HelloSkAR Java</string>
<string name="app_name">Hello CanvasAR</string>
</resources>

View File

@ -1,5 +1,5 @@
<!--
Copyright 2016 Google Inc.
Copyright 2018 Google LLC
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@ -13,6 +13,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources>
<!--
@ -41,8 +42,6 @@
<style name="BottomNavigation" parent="Widget.Design.BottomNavigationView">
<item name="itemBackground">@android:color/darker_gray</item>
<!-- <item name="paddingStart">10dp</item>
<item name="paddingEnd">10dp</item>-->
</style>
</resources>