protected void fixNormalEdges(TerrainPatch right,
                                TerrainPatch bottom,
                                TerrainPatch top,
                                TerrainPatch left,
                                TerrainPatch bottomRight,
                                TerrainPatch bottomLeft,
                                TerrainPatch topRight,
                                TerrainPatch topLeft)
    {
        Vector3f rootPoint = new Vector3f();
        Vector3f rightPoint = new Vector3f();
        Vector3f leftPoint = new Vector3f();
        Vector3f topPoint = new Vector3f();

        Vector3f bottomPoint = new Vector3f();

        Vector3f tangent = new Vector3f();
        Vector3f binormal = new Vector3f();
        Vector3f normal = new Vector3f();


        int s = this.getSize()-1;

        if (right != null) { // right side,    works its way down
            for (int i=0; i<s+1; i++) {
                rootPoint.set(0, this.getHeightmapHeight(s,i), 0);
                leftPoint.set(-1, this.getHeightmapHeight(s-1,i), 0);
                rightPoint.set(1, right.getHeightmapHeight(1,i), 0);

                if (i == 0) { // top point
                    bottomPoint.set(0, this.getHeightmapHeight(s,i+1), 1);

                    if (top == null) {
                        averageNormalsTangents(null, rootPoint, leftPoint, bottomPoint, rightPoint,  normal, tangent, binormal);
                        setInBuffer(this.getMesh(), s, normal, tangent, binormal);
                        setInBuffer(right.getMesh(), 0, normal, tangent, binormal);
                    } else {
                        topPoint.set(0, top.getHeightmapHeight(s,s-1), -1);

                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint,normal, tangent, binormal);
                        setInBuffer(this.getMesh(), s, normal, tangent, binormal);
                        setInBuffer(right.getMesh(), 0, normal, tangent, binormal);
                        setInBuffer(top.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);

                        if (topRight != null) {
                    //        setInBuffer(topRight.getMesh(), (s+1)*s, normal, tangent, binormal);
                        }
                    }
                } else if (i == s) { // bottom point
                    topPoint.set(0, this.getHeightmapHeight(s,s-1), -1);

                    if (bottom == null) {
                        averageNormalsTangents(topPoint, rootPoint, leftPoint, null, rightPoint, normal, tangent, binormal);
                        setInBuffer(this.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
                        setInBuffer(right.getMesh(), (s+1)*(s), normal, tangent, binormal);
                    } else {
                        bottomPoint.set(0, bottom.getHeightmapHeight(s,1), 1);
                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
                        setInBuffer(this.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
                        setInBuffer(right.getMesh(), (s+1)*s, normal, tangent, binormal);
                        setInBuffer(bottom.getMesh(), s, normal, tangent, binormal);

                        if (bottomRight != null) {
                   //         setInBuffer(bottomRight.getMesh(), 0, normal, tangent, binormal);
                        }
                    }
                } else { // all in the middle
                    topPoint.set(0, this.getHeightmapHeight(s,i-1), -1);
                    bottomPoint.set(0, this.getHeightmapHeight(s,i+1), 1);
                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
                    setInBuffer(this.getMesh(), (s+1)*(i+1)-1, normal, tangent, binormal);
                    setInBuffer(right.getMesh(), (s+1)*(i), normal, tangent, binormal);
                }
            }
        }

        if (left != null) { // left side,    works its way down
            for (int i=0; i<s+1; i++) {
                rootPoint.set(0, this.getHeightmapHeight(0,i), 0);
                leftPoint.set(-1, left.getHeightmapHeight(s-1,i), 0);
                rightPoint.set(1, this.getHeightmapHeight(1,i), 0);

                if (i == 0) { // top point
                    bottomPoint.set(0, this.getHeightmapHeight(0,i+1), 1);

                    if (top == null) {
                        averageNormalsTangents(null, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
                        setInBuffer(this.getMesh(), 0, normal, tangent, binormal);
                        setInBuffer(left.getMesh(), s, normal, tangent, binormal);
                    } else {
                        topPoint.set(0, top.getHeightmapHeight(0,s-1), -1);

                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
                        setInBuffer(this.getMesh(), 0, normal, tangent, binormal);
                        setInBuffer(left.getMesh(), s, normal, tangent, binormal);
                        setInBuffer(top.getMesh(), (s+1)*s, normal, tangent, binormal);

                        if (topLeft != null) {
                     //       setInBuffer(topLeft.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
                        }
                    }
                } else if (i == s) { // bottom point
                    topPoint.set(0, this.getHeightmapHeight(0,i-1), -1);

                    if (bottom == null) {
                        averageNormalsTangents(topPoint, rootPoint, leftPoint, null, rightPoint, normal, tangent, binormal);
                        setInBuffer(this.getMesh(), (s+1)*(s), normal, tangent, binormal);
                        setInBuffer(left.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
                    } else {
                        bottomPoint.set(0, bottom.getHeightmapHeight(0,1), 1);

                        averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
                        setInBuffer(this.getMesh(), (s+1)*(s), normal, tangent, binormal);
                        setInBuffer(left.getMesh(), (s+1)*(s+1)-1, normal, tangent, binormal);
                        setInBuffer(bottom.getMesh(), 0, normal, tangent, binormal);

                        if (bottomLeft != null) {
                     //       setInBuffer(bottomLeft.getMesh(), s, normal, tangent, binormal);
                        }
                    }
                } else { // all in the middle
                    topPoint.set(0, this.getHeightmapHeight(0,i-1), -1);
                    bottomPoint.set(0, this.getHeightmapHeight(0,i+1), 1);

                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
                    setInBuffer(this.getMesh(), (s+1)*(i), normal, tangent, binormal);
                    setInBuffer(left.getMesh(), (s+1)*(i+1)-1, normal, tangent, binormal);
                }
            }
        }

        if (top != null) { // top side,    works its way right
            for (int i=0; i<s+1; i++) {
                rootPoint.set(0, this.getHeightmapHeight(i,0), 0);
                topPoint.set(0, top.getHeightmapHeight(i,s-1), -1);
                bottomPoint.set(0, this.getHeightmapHeight(i,1), 1);

                if (i == 0) { // left corner
                    // handled by left side pass

                } else if (i == s) { // right corner

                    // handled by this patch when it does its right side

                } else { // all in the middle
                    leftPoint.set(-1, this.getHeightmapHeight(i-1,0), 0);
                    rightPoint.set(1, this.getHeightmapHeight(i+1,0), 0);
                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
                    setInBuffer(this.getMesh(), i, normal, tangent, binormal);
                    setInBuffer(top.getMesh(), (s+1)*(s)+i, normal, tangent, binormal);
                }
            }

        }

        if (bottom != null) { // bottom side,    works its way right
            for (int i=0; i<s+1; i++) {
                rootPoint.set(0, this.getHeightmapHeight(i,s), 0);
                topPoint.set(0, this.getHeightmapHeight(i,s-1), -1);
                bottomPoint.set(0, bottom.getHeightmapHeight(i,1), 1);

                if (i == 0) { // left
                    // handled by the left side pass

                } else if (i == s) { // right

                    // handled by the right side pass

                } else { // all in the middle
                    leftPoint.set(-1, this.getHeightmapHeight(i-1,s), 0);
                    rightPoint.set(1, this.getHeightmapHeight(i+1,s), 0);
                    averageNormalsTangents(topPoint, rootPoint, leftPoint, bottomPoint, rightPoint, normal, tangent, binormal);
                    setInBuffer(this.getMesh(), (s+1)*(s)+i, normal, tangent, binormal);
                    setInBuffer(bottom.getMesh(), i, normal, tangent, binormal);
                }
            }

        }
    }
Matches the normals along the edge of the patch with the neighbours.
Computes the normals for the right, bottom, left, and top edges of the
patch, and saves those normals in the neighbour's edges too.

Takes 4 points (if it has a neighbour on that side) for each
point on the edge of the patch:
             *
             |
         *---x---*
             |
             *
It works across the right side of the patch, from the top down to
the bottom. Then it works on the bottom side of the patch, from the
left to the right.
jme3-terrain/src/main/java/com/jme3/terrain/geomipmap/TerrainPatch.java