# all files / src/plugin/ InfinitePlane.js

18.06% Statements 13/72
0% Branches 0/12
25% Functions 1/4
18.06% Lines 13/72

    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
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144

    1×
    1×

    1×

    1×
    1×

    1×
    1×

    1×

    1×
    1×
    4×

    1×

    1×

     import Mesh from '../Mesh';
    import Geometry from '../Geometry';
    import Plane from '../math/Plane';
    import Vector3 from '../math/Vector3';
    import Matrix4 from '../math/Matrix4';
    import Ray from '../math/Ray';

    import glMatrix from '../dep/glmatrix';
    var mat4 = glMatrix.mat4;
    var vec3 = glMatrix.vec3;
    var vec4 = glMatrix.vec4;

    var uvs = [[0, 0], [0, 1], [1, 1], [1, 0]];
    var tris = [0, 1, 2, 2, 3, 0];

    var InfinitePlane = Mesh.extend({

        camera: null,

        plane: null,

        maxGrid: 0,

        // TODO
        frustumCulling: false

    }, function () {
        var geometry = this.geometry = new Geometry({
            dynamic: true
        });
        geometry.attributes.position.init(6);
        geometry.attributes.normal.init(6);
        geometry.attributes.texcoord0.init(6);
        geometry.indices = new Uint16Array(6);

        this.plane = new Plane();
    }, {

        updateGeometry: function () {

            var coords = this._unProjectGrid();
            if (!coords) {
                return;
            }
            var positionAttr = this.geometry.attributes.position;
            var normalAttr = this.geometry.attributes.normal;
            var texcoords = this.geometry.attributes.texcoord0;
            var indices = this.geometry.indices;

            for (var i = 0; i < 6; i++) {
                var idx = tris[i];
                positionAttr.set(i, coords[idx].array);
                normalAttr.set(i, this.plane.normal.array);
                texcoords.set(i, uvs[idx]);
                indices[i] = i;
            }
            this.geometry.dirty();
        },

        // http://fileadmin.cs.lth.se/graphics/theses/projects/projgrid/
        _unProjectGrid: (function () {

            var planeViewSpace = new Plane();
            var lines = [
                0, 1, 0, 2, 1, 3, 2, 3,
                4, 5, 4, 6, 5, 7, 6, 7,
                0, 4, 1, 5, 2, 6, 3, 7
            ];

            var start = new Vector3();
            var end = new Vector3();

            var points = [];

            // 1----2
            // |    |
            // 0----3
            var coords = [];
            for (var i = 0; i < 4; i++) {
                coords[i] = new Vector3(0, 0);
            }

            var ray = new Ray();

            return function () {
                planeViewSpace.copy(this.plane);
                planeViewSpace.applyTransform(this.camera.viewMatrix);

                var frustumVertices = this.camera.frustum.vertices;

                var nPoints = 0;
                // Intersect with lines of frustum
                for (var i = 0; i < 12; i++) {
                    start.array = frustumVertices[lines[i * 2]];
                    end.array = frustumVertices[lines[i * 2 + 1]];

                    var point = planeViewSpace.intersectLine(start, end, points[nPoints]);
                    if (point) {
                        if (!points[nPoints]) {
                            points[nPoints] = point;
                        }
                        nPoints++;
                    }
                }
                if (nPoints === 0) {
                    return;
                }
                for (var i = 0; i < nPoints; i++) {
                    points[i].applyProjection(this.camera.projectionMatrix);
                }
                var minX = points[0].array[0];
                var minY = points[0].array[1];
                var maxX = points[0].array[0];
                var maxY = points[0].array[1];
                for (var i = 1; i < nPoints; i++) {
                    maxX = Math.max(maxX, points[i].array[0]);
                    maxY = Math.max(maxY, points[i].array[1]);
                    minX = Math.min(minX, points[i].array[0]);
                    minY = Math.min(minY, points[i].array[1]);
                }
                if (minX == maxX || minY == maxY) {
                    return;
                }
                coords[0].array[0] = minX;
                coords[0].array[1] = minY;
                coords[1].array[0] = minX;
                coords[1].array[1] = maxY;
                coords[2].array[0] = maxX;
                coords[2].array[1] = maxY;
                coords[3].array[0] = maxX;
                coords[3].array[1] = minY;

                for (var i = 0; i < 4; i++) {
                    this.camera.castRay(coords[i], ray);
                    ray.intersectPlane(this.plane, coords[i]);
                }

                return coords;
            };
        })()
    });

    export default InfinitePlane;