public WalkCell(Poll topLeft, Poll topRight, Poll bottomRight, Poll bottomLeft, float pollSpacing, float playerHeight, float playerStepHeight, List <MathUtils.Cylinder> cylinders = null) { FillWalkPoints(topLeft, topRight, bottomRight, bottomLeft, pollSpacing, playerHeight, playerStepHeight, cylinders); }
void FillWalkPoints(Poll topLeft, Poll topRight, Poll bottomRight, Poll bottomLeft, float pollSpacing, float playerHeight, float playerStepHeight, List <MathUtils.Cylinder> cylinders) { List <Vector3> points = new List <Vector3>(8); List <float> tLeft = new List <float>(topLeft.yHeights); List <float> tRight = new List <float>(topRight.yHeights); List <float> bRight = new List <float>(bottomRight.yHeights); List <float> bLeft = new List <float>(bottomLeft.yHeights); short configuration = 0; float height = 0; short retConfig = 0; float retHeight = 0; short ConfigCount = 1; foreach (float p in tLeft) { points.Clear(); configuration = 0; height = 0; retConfig = 0; retHeight = 0; ConfigCount = 1; points.Add(topLeft.postition + Vector3.up * p); configuration += 8;// 8 = top left height = p; // 4 = top right (retConfig, retHeight) = HasPointInWalkGroup(ref tRight, topRight.postition, ref points, p, 4, playerStepHeight); configuration += retConfig; if (retConfig > 0) { ConfigCount++; } height += retHeight; // 2 = bottom right (retConfig, retHeight) = HasPointInWalkGroup(ref bRight, bottomRight.postition, ref points, p, 2, playerStepHeight); configuration += retConfig; if (retConfig > 0) { ConfigCount++; } height += retHeight; // 1 = bottom left (retConfig, retHeight) = HasPointInWalkGroup(ref bLeft, bottomLeft.postition, ref points, p, 1, playerStepHeight); configuration += retConfig; if (retConfig > 0) { ConfigCount++; } height += retHeight; height /= ConfigCount; if ((configuration & 4) != 4) { (retConfig, retHeight) = HasPointInWalkGroup(ref tRight, topRight.postition, ref points, height, 4, playerStepHeight); configuration += retConfig; if (retConfig > 0) { ConfigCount++; } height += retHeight; } if ((configuration & 2) != 2) { (retConfig, retHeight) = HasPointInWalkGroup(ref bRight, bottomRight.postition, ref points, height, 2, playerStepHeight); configuration += retConfig; if (retConfig > 0) { ConfigCount++; } height += retHeight; } if ((configuration & 1) != 1) { (retConfig, retHeight) = HasPointInWalkGroup(ref bLeft, bottomLeft.postition, ref points, height, 1, playerStepHeight); configuration += retConfig; if (retConfig > 0) { ConfigCount++; } height += retHeight; } if (configuration != 15) { configuration = Contains_A_BlockedWalkEdge(topLeft, topRight, bottomRight, bottomLeft, playerStepHeight, points, configuration); } if (points.Count > 2) { points.Add(topLeft.postition + Vector3.up * p); } walkGroups.Add(new WalkPointGroup(points.ToArray(), configuration, pollSpacing, playerHeight, playerStepHeight, cylinders)); } foreach (float p in tRight) { points.Clear(); configuration = 0; height = 0; retConfig = 0; retHeight = 0; ConfigCount = 1; points.Add(topRight.postition + Vector3.up * p); configuration += 4;// 4 = top right // 2 = bottom right (retConfig, retHeight) = HasPointInWalkGroup(ref bRight, bottomRight.postition, ref points, p, 2, playerStepHeight); configuration += retConfig; if (retConfig > 0) { ConfigCount++; } height += retHeight; // 1 = bottom left (retConfig, retHeight) = HasPointInWalkGroup(ref bLeft, bottomLeft.postition, ref points, p, 1, playerStepHeight); configuration += retConfig; if (retConfig > 0) { ConfigCount++; } height += retHeight; configuration = Contains_A_BlockedWalkEdge(topLeft, topRight, bottomRight, bottomLeft, playerStepHeight, points, configuration); if (points.Count > 2) { points.Add(topRight.postition + Vector3.up * p); } walkGroups.Add(new WalkPointGroup(points.ToArray(), configuration, pollSpacing, playerHeight, playerStepHeight, cylinders)); } foreach (float p in bRight) { points.Clear(); configuration = 0; height = 0; retConfig = 0; retHeight = 0; ConfigCount = 1; points.Add(bottomRight.postition + Vector3.up * p); configuration += 2;// 2 = bottom right // 1 = bottom left (retConfig, retHeight) = HasPointInWalkGroup(ref bLeft, bottomLeft.postition, ref points, p, 1, playerStepHeight); configuration += retConfig; if (retConfig > 0) { ConfigCount++; } height += retHeight; configuration = Contains_A_BlockedWalkEdge(topLeft, topRight, bottomRight, bottomLeft, playerStepHeight, points, configuration); if (points.Count > 2) { points.Add(bottomRight.postition + Vector3.up * p); } walkGroups.Add(new WalkPointGroup(points.ToArray(), configuration, pollSpacing, playerHeight, playerStepHeight, cylinders)); } foreach (float p in bLeft) { points.Clear(); configuration = 0; points.Add(bottomLeft.postition + Vector3.up * p); configuration += 1;// 1 = bottom left configuration = Contains_A_BlockedWalkEdge(topLeft, topRight, bottomRight, bottomLeft, playerStepHeight, points, configuration); walkGroups.Add(new WalkPointGroup(points.ToArray(), configuration, pollSpacing, playerHeight, playerStepHeight, cylinders)); } }
private static short Contains_A_BlockedWalkEdge(Poll topLeft, Poll topRight, Poll bottomRight, Poll bottomLeft, float playerStepHeight, List <Vector3> points, short configuration) { for (int i = 0; i < points.Count && configuration > 0; i++) { Vector3 v = points[i]; configuration = ContainsBlockedWalkPoint(topLeft, configuration, v); if (configuration < 0) { break; } configuration = ContainsBlockedWalkPoint(topRight, configuration, v); if (configuration < 0) { break; } configuration = ContainsBlockedWalkPoint(bottomRight, configuration, v); if (configuration < 0) { break; } configuration = ContainsBlockedWalkPoint(bottomLeft, configuration, v); } return(configuration); }
public void GenerateWalkGrid(float squareSize, int sideCount, float playerHeight, float stepHeight, float playerRadius, Vector3 pos) { if (squareSize <= 0.01 || sideCount < 1) { return; } pos.y = maxHeight; Poll[,] polls = new Poll[sideCount, sideCount]; float spacing = (1f / (sideCount - 1)) * squareSize; for (int x = 0; x < sideCount; x++) { for (int y = 0; y < sideCount; y++) { Vector3 point = pos + new Vector3(0 - (squareSize / 2) + x * spacing, 0, 0 - (squareSize / 2) + y * spacing); RaycastHit[] hits = Physics.RaycastAll(point, Vector3.down); hits = hits.OrderBy(v => v.point.y).Reverse().ToArray(); List <float> validPoints = new List <float>(); if (hits.Length != 0) { List <Collider> blockerCollider = new List <Collider>(); for (int h = 0; h < hits.Length; h++) { bool valid = true; RaycastHit hit = hits[h]; RaycastHit hit2; if (hit.collider.gameObject.layer == 8) { blockerCollider.Add(hit.collider); valid = false; } else { foreach (var c in blockerCollider) { if (IsPointInCollider(c, hit.point)) { valid = false; break; } } } if (valid && h != 0 && (hit.point.y + playerHeight > hits[h - 1].point.y || Physics.Raycast(hit.point, Vector3.up, out hit2, playerHeight))) { valid = false; } if (valid) { validPoints.Add(hit.point.y); } if (drawCross) { GL_Utils.DrawCrossNormal(hit.point + Vector3.up * 0.01f, hit.normal, valid ? Color.white : Color.red); } } if (drawRay) { GL_Utils.DrawLine(point, hits[hits.Length - 1].point, Color.green); } } polls[x, y] = new Poll(new Vector3(point.x, 0, point.z), validPoints); } } cellGrid = new CellGrid(polls, spacing, playerHeight, stepHeight, playerRadius); }