void GetCrossPoint() { if (crossPoints == null) { crossPoints = new List <FrustrumPoint>(); } crossPoints.Clear(); Matrix_VP = cam.projectionMatrix * cam.worldToCameraMatrix; Matrix_I_VP = Matrix_VP.inverse; for (int i = 0; i < 12; i++) { FrustrumPoint crossPoint = new FrustrumPoint(); if (IsSegmentIntersectOcean(segments[i, 0], segments[i, 1], OceanLevel, ref crossPoint)) { crossPoints.Add(crossPoint); } } //为了留出裕度,统统向外扩张5% Vector4 middle = Vector4.zero; foreach (var p in crossPoints) { middle += p.worldPos; } middle /= crossPoints.Count; for (int i = 0; i < crossPoints.Count; i++) { crossPoints[i].worldPos = (crossPoints[i].worldPos - middle) * (1 + outScale) + middle; } }
void Resort4Point(ref List <FrustrumPoint> list) { Vector3 s1 = (Vector3)(crossPoints[1].worldPos - crossPoints[0].worldPos); Vector3 s2 = (Vector3)(crossPoints[2].worldPos - crossPoints[1].worldPos); Vector3 d1 = Vector3.Cross(s1, s2); //第一次交换,保证前3点次序 if (d1.y < 0) { FrustrumPoint t = crossPoints[1]; crossPoints[1] = crossPoints[2]; crossPoints[2] = t; } s1 = (Vector3)(crossPoints[2].worldPos - crossPoints[1].worldPos); s2 = (Vector3)(crossPoints[3].worldPos - crossPoints[2].worldPos); Vector3 s3 = (Vector3)(crossPoints[0].worldPos - crossPoints[3].worldPos); Vector3 s4 = (Vector3)(crossPoints[1].worldPos - crossPoints[0].worldPos); d1 = Vector3.Cross(s1, s2); Vector3 d2 = Vector3.Cross(s2, s3); Vector3 d3 = Vector3.Cross(s3, s4); //第二次交换,保证4点次序 if (d1.y * d2.y < 0) { FrustrumPoint t = crossPoints[2]; crossPoints[2] = crossPoints[1]; crossPoints[1] = t; } else if (d2.y * d3.y < 0) { FrustrumPoint t = crossPoints[3]; crossPoints[3] = crossPoints[2]; crossPoints[2] = t; } //最后判断是否正面朝上 s1 = (Vector3)(crossPoints[2].worldPos - crossPoints[1].worldPos); s2 = (Vector3)(crossPoints[3].worldPos - crossPoints[2].worldPos); d1 = Vector3.Cross(s1, s2); if (d1.y < 0) { FrustrumPoint t = crossPoints[3]; crossPoints[3] = crossPoints[0]; crossPoints[0] = t; t = crossPoints[2]; crossPoints[2] = crossPoints[1]; crossPoints[1] = t; } }
private bool IsSegmentIntersectOcean(int p1, int p2, float OceanLevel, ref FrustrumPoint crossPoint) { Vector4 a = cameraToWorld(frustrumCorner[p1]); Vector4 b = cameraToWorld(frustrumCorner[p2]); if ((a.y - OceanLevel) * (b.y - OceanLevel) > 0) { return(false); //同侧无交点 } var p = (OceanLevel - a.y) / (b.y - a.y); crossPoint = new FrustrumPoint(); crossPoint.worldPos = new Vector4( a.x + p * (b.x - a.x), OceanLevel, a.z + p * (b.z - a.z), 1); crossPoint.localPos = worldToCamera(crossPoint.worldPos); return(true); }