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