private Shape3 ShadowPoly(Vector3 viewpoint, float viewDistance)
    {
        var obsShape = new Shape3 ();

        obsShape.AddVertex (rotationQ * new Vector3(sizeX * 0.5f, viewpoint.y, sizeZ * 0.5f) + position);
        obsShape.AddVertex (rotationQ * new Vector3(sizeX*0.5f, viewpoint.y, -sizeZ*0.5f) + position);
        obsShape.AddVertex (rotationQ * new Vector3(-sizeX*0.5f, viewpoint.y, -sizeZ*0.5f) + position);
        obsShape.AddVertex (rotationQ * new Vector3(-sizeX*0.5f, viewpoint.y, sizeZ*0.5f) + position);

        int first = 13; // bogus int for signalling uninitialization

        // Detect whether an edge should be projected,
        // or rather stick to the obstacle
        var projectedEdge = new bool[4];
        float farthest = 0;
        int count = 0;
        int i = 0;

        bool inside = obsShape.PointInside(viewpoint);

        foreach (Edge3Abs e in obsShape) {
            if ((e.a - viewpoint).magnitude > farthest)
                farthest = (e.a - viewpoint).magnitude;

            projectedEdge[i] = !(inside || !(Vector3.Cross(e.a - viewpoint, e.GetDiff()).y > 0));

            if (!projectedEdge[i]) {
                count++;
                if (first == 13)
                    first = i;
                if (first == (i + 1) % 4)
                    first = i;
            }

            i++;
        }

        if (viewDistance > farthest)
            farthest = viewDistance;
        farthest *= 2f;

        int v = 0;
        var shape = new Shape3 ();
        if (count == 4) {
            IEnumerator obsShapeRH = obsShape.GetReverseEnumerator();
            while(obsShapeRH.MoveNext()) {
                var e = (Edge3Abs)obsShapeRH.Current;
                //shape.addVertex ((e.a - viewpoint).normalized * farthest + viewpoint);
                shape.AddVertex (e.a);
            }
        } else {

            for (int j = first; j < 4 + first; j++) {
                if (projectedEdge [j % 4]) {
                    // Should add an edge from unprojected to projected
                    if (!projectedEdge [((j - 1) % 4 + 4) % 4]) {
                            shape.AddVertex ((obsShape [j % 4] - viewpoint).normalized * farthest + viewpoint);
                    }
                    shape.AddVertex((obsShape [(j + 1) % 4] - viewpoint).normalized * farthest + viewpoint);
                } else {
                    if (v == 0) {
                        shape.AddVertex (obsShape [j % 4]);
                        shape.AddVertex (obsShape [(j + 1) % 4]);
                        v = 2;
                    } else {
                        shape.AddVertex (obsShape [(j + 1) % 4]);
                    }
                }
            }

        }
        shape.Offset(3);
        return shape;
    }