void PlaceSelf() { List<List<Vector3>> floorParts = floor.GetPartialFloorRects(false).ToList(); List<Vector3> outerWall = floor.GetCircumferance(false).ToList(); int outerWallsLength = outerWall.Count; bool validated = false; while (!validated) { List<Vector3> compartment = floorParts[Random.Range(0, floorParts.Count)]; Vector3 v1 = compartment[1] - compartment[0]; Vector3 v2 = compartment[2] - compartment[1]; //Vector3 c = compartment.Aggregate(Vector3.zero, (sum, e) => sum + e) / compartment.Count; Vector3 pt = compartment[0] + Random.value * v1 + Random.value * v2; validated = true; for (int i=0; i<outerWallsLength; i++) { float d = ProcGenHelpers.GetMinDist(pt, outerWall[i], outerWall[(i + 1) % outerWallsLength]); if (d < proximityThreshold) { Debug.Log("Invalid"); validated = false; break; } } if (validated) { transform.position = pt; } } GetComponentInParent<RotateMe>().rotating = false; PlayerController.Instance.Spawn(transform); }
//List<Vector3> outsideTriFail = new List<Vector3>(); public List <Vector3> TraceSurface(int tri, Vector3 thirdVert, Vector3 intercept, Vector3 normal, Dictionary <int, List <Vector3> > allIntercepts, out List <Ray> rayTrain, float proximityOfInterceptThreshold = 0.01f, int searchDepth = 20) { List <Vector3> traceLine = new List <Vector3>(); Vector3 orginalIntercept = intercept; //Vector3 originalNorm = myTriNormals[tri]; rayTrain = new List <Ray>(); Ray r; if (ProcGenHelpers.InterceptionRay(normal, intercept, myTriNormals[tri], out r)) { r.direction = Mathf.Sign(Vector3.Dot(thirdVert - intercept, r.direction)) * r.direction; while (tri >= 0) { rayTrain.Add(new Ray(r.origin, r.direction)); int v = tri * 3; Vector3 vertA = myVerts[myTris[v]]; Vector3 vertB = myVerts[myTris[v + 1]]; Vector3 vertC = myVerts[myTris[v + 2]]; int hitEdge; //TODO: Sensitive as edge condition in some rotations Vector3 rayHit = ProcGenHelpers.RayHitEdge(vertA, vertB, vertC, r, out hitEdge); if (hitEdge == -1) { /* * outsideTriFail.Clear(); * outsideTriFail.Add(vertA); * outsideTriFail.Add(vertB); * outsideTriFail.Add(vertC); * Debug.LogError(string.Format("Intercept {0} was not in the reported triangle {2} (trace length = {1}, normal = {3})!", intercept, traceLine.Count(), tri, normal)); * Debug.Log(string.Format("{0} {1} {2} ray {3} -> ({4}, {5}, {6}) missed", vertA, vertB, vertC, r.origin, r.direction.x, r.direction.y, r.direction.z)); * Debug.Log(string.Format("Norm calc {0} Norm pre calc {1}, Other Norm {2}, Ray direction {3}", * Vector3.Cross(vertB - vertA, vertC - vertA), originalNorm, normal, Vector3.Cross(originalNorm, normal))); * outsideTriFail.Clear(); * outsideTriFail.Add(vertA); * outsideTriFail.Add(vertB); * outsideTriFail.Add(vertC); */ traceLine.Clear(); tri = -1; Debug.LogError(string.Format("Intercept {0} was not in the reported triangle {2} (trace length = {1}, normal = {3})!", intercept, traceLine.Count(), tri, normal)); float t1; float t2; bool val = ProcGenHelpers.LineSegmentInterceptIn3D(vertB, vertC, r, 0.01f, out t1, out t2); Debug.LogError(string.Format("t1 {0} t2 {1} dist {2} {3}, {4}", t1, t2, Vector3.Distance(vertB + (vertC - vertB).normalized * t1, r.GetPoint(t2)), val, (vertC - vertB).magnitude)); } else { if (allIntercepts.Keys.Contains(tri)) { List <Vector3> hitIntercepts = allIntercepts[tri] .Where(v1 => Vector3.SqrMagnitude(v1 - orginalIntercept) > proximityOfInterceptThreshold) .Select(v2 => new { vert = v2, dist = ProcGenHelpers.GetMinDist(v2, intercept, rayHit) }) .Where(e => e.dist < proximityOfInterceptThreshold) //TODO: Potentially order by proximity to intercept .Select(e => e.vert).ToList(); if (hitIntercepts.Count > 0) { //Debug.Log(string.Format("Found path connecting intercepts {0} - {1}", orginalIntercept, hitIntercepts[0])); traceLine.Add(hitIntercepts[0]); return(traceLine); } else { /* * Debug.Log(string.Format("No close intercept on {0} ({1} - {2}), closest: {3}", * tri, * intercept, rayHit, * allIntercepts[tri] * //.Where(v1 => Vector3.SqrMagnitude(v1 - orginalIntercept) > proximityOfInterceptThreshold) * .Select(v2 => new { * vert = v2, * dist = ProcGenHelpers.GetMinDist(v2, intercept, rayHit) * }) * .OrderBy(e => e.dist) * //TODO: Potentially order by proximity to intercept * .Select(e => e.vert).FirstOrDefault().magnitude * )); */ } } else { //Debug.Log("No intercept in tri " + tri); } if (traceLine.Contains(rayHit)) { Debug.LogError("Going back over myself"); return(traceLine); } else { //Debug.Log("Hit tri edge at " + rayHit); traceLine.Add(rayHit); } int nextTri = GetNeighbourTri(myTris[v + hitEdge], myTris[v + (hitEdge + 1) % 3], tri); if (nextTri != -1) { intercept = rayHit; if (ProcGenHelpers.InterceptionRay(normal, intercept, myTriNormals[nextTri], out r)) { int idThirdVert = GetMissingVert(nextTri, myTris[v + hitEdge], myTris[v + (hitEdge + 1) % 3]); Vector3 d3 = myVerts[idThirdVert] - intercept; float sign = Mathf.Sign(Vector3.Dot(d3, r.direction)); /*Debug.Log(string.Format("{3} ({9}) -> {4} ({10}): {0} - {1}, {2} ({5}, {6}) [{7} {8}]", * myTris[v + hitEdge], myTris[v + (hitEdge + 1) % 3], idThirdVert, * tri, nextTri, * r.direction, sign, * myVerts[idThirdVert], intercept, * myTriNormals[tri], myTriNormals[nextTri] * ));*/ r.direction = sign * r.direction; tri = nextTri; //Debug.Log("Found next tri"); } else { Debug.LogError("The identified next tri didn't intercept cutting Tri"); tri = -1; } } else { Debug.LogError("No neighbour"); } } if (traceLine.Count() >= searchDepth) { Debug.LogWarning("Aborted trace because reached search depth"); traceLine.Clear(); return(traceLine); } } } traceLine.Clear(); Debug.Log("Found strange line that started in " + orginalIntercept); return(traceLine); }