aboutsummaryrefslogtreecommitdiffhomepage
path: root/platform_tools/android/apps/skar_java/src/main/java/com/google/skar/SkARFingerPainting.java
blob: c93a900f5835f1d1a08f133d0730ceb6ea085f5b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
package com.google.skar;

import android.graphics.Path;
import android.graphics.PointF;

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<PointF> points = new ArrayList<>();

    public Path path = new Path();

    // 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) {
        points.add(p);
        previousPoint = p;
    }

    // Used to build a path before rendering it
    public void buildPath() {
        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);

                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);
            }
        } 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);
            }
        }
    }

    public boolean isEmpty() {
        return path.isEmpty();
    }

    public float[] getModelMatrix() {
        return modelMatrix;
    }

    public void setModelMatrix(float[] m) {
        modelMatrix = m;
    }

    public void reset() {
        points = new ArrayList<>();
        path = new Path();
    }
}