public void CheckAllCollides(float x, float y, float z, TriangleCollection paintI) { TriangleCollection tc = GetChunkAt(x, y); TriangleMatrix tm = tc.GetTriangleMatrix(); ICollection <int> ts = tm.GetAllCloseTo(x, y, 15.0f); Vector s0; Vector s1; s0.x = x; s0.y = y; s0.z = z; foreach (int t in ts) //for(int t = 0 ; t<tc.GetNumberOfTriangles(); t++) { Vector vertex0; Vector vertex1; Vector vertex2; Vector intersect; tc.GetTriangleVertices(t, out vertex0.x, out vertex0.y, out vertex0.z, out vertex1.x, out vertex1.y, out vertex1.z, out vertex2.x, out vertex2.y, out vertex2.z); s1.x = (vertex0.x + vertex1.x + vertex2.x) / 3; s1.y = (vertex0.y + vertex1.y + vertex2.y) / 3; s1.z = (vertex0.z + vertex1.z + vertex2.z) / 3 - 0.1f; //paintI.AddMarker(s1.x, s1.y, s1.z + 0.1f); if (Utils.SegmentTriangleIntersect(s0, s1, vertex0, vertex1, vertex2, out intersect)) { if (paintI != null) { // AddVisible(paintI, intersect.x, intersect.y, intersect.z); } // blocked! } } }
public float GetMaxZ(float x, float y) { TriangleCollection tc = GetChunkAt(x, y); ICollection <int> ts; ts = null; if (UseMatrix) { TriangleMatrix tm = tc.GetTriangleMatrix(); ts = tm.GetAllCloseTo(x, y, 0); } float best_z = float.MinValue; foreach (int t in ts) { Vector vertex0; Vector vertex1; Vector vertex2; int t_flags, sequence; tc.GetTriangleVertices(t, out vertex0.x, out vertex0.y, out vertex0.z, out vertex1.x, out vertex1.y, out vertex1.z, out vertex2.x, out vertex2.y, out vertex2.z, out t_flags, out sequence); if (vertex0.z > best_z) { best_z = vertex0.z; } if (vertex1.z > best_z) { best_z = vertex1.z; } if (vertex2.z > best_z) { best_z = vertex2.z; } } return(best_z); }
public bool IsCloseToModel(float x, float y, float z, float range) { TriangleCollection tc = GetChunkAt(x, y); TriangleMatrix tm = tc.GetTriangleMatrix(); foreach (int t in tm.GetAllCloseTo(x, y, range)) { Vector vertex0; Vector vertex1; Vector vertex2; int t_flags, sequence; tc.GetTriangleVertices(t, out vertex0.x, out vertex0.y, out vertex0.z, out vertex1.x, out vertex1.y, out vertex1.z, out vertex2.x, out vertex2.y, out vertex2.z, out t_flags, out sequence); //check triangle is part of a model if ((t_flags & TriangleFlagObject) != 0 || (t_flags & TriangleFlagModel) != 0) { float minHeight = 0.1f; float height = 2; //and the vertex is close to the char if ( (vertex0.z > z + minHeight && vertex0.z < z + height) || (vertex1.z > z + minHeight && vertex1.z < z + height) || (vertex2.z > z + minHeight && vertex2.z < z + height) ) { return(true); } } } return(false); }
public bool FindStandableAt1(float x, float y, float min_z, float max_z, out float z0, out int flags, float toonHeight, float toonSize, bool IgnoreGradient, int[] allowedFlags) { TriangleCollection tc = GetChunkAt(x, y); ICollection <int> ts, tsm, tst; float minCliffD = 0.5f; ts = null; if (UseOctree) { TriangleOctree ot = tc.GetOctree(); tst = ts = ot.FindTrianglesInBox(x - minCliffD, y - minCliffD, min_z, x + minCliffD, y + minCliffD, max_z); } if (UseMatrix) { TriangleMatrix tm = tc.GetTriangleMatrix(); tsm = ts = tm.GetAllCloseTo(x, y, 1.0f); } Vector s0, s1; s0.x = x; s0.y = y; s0.z = min_z; s1.x = x; s1.y = y; s1.z = max_z; float best_z = -1E30f; int best_flags = 0; bool found = false; foreach (int t in ts) { Vector vertex0; Vector vertex1; Vector vertex2; Vector intersect; int t_flags, sequence; tc.GetTriangleVertices(t, out vertex0.x, out vertex0.y, out vertex0.z, out vertex1.x, out vertex1.y, out vertex1.z, out vertex2.x, out vertex2.y, out vertex2.z, out t_flags, out sequence); if (allowedFlags == null || allowedFlags.Contains(t_flags)) { Vector normal; Utils.GetTriangleNormal(vertex0, vertex1, vertex2, out normal); float angle_z = (float)Math.Sin(45.0 / 360.0 * Math.PI * 2); // if (Utils.abs(normal.z) > angle_z) { if (Utils.SegmentTriangleIntersect(s0, s1, vertex0, vertex1, vertex2, out intersect)) { if (intersect.z > best_z) { if (!IsSpotBlocked(intersect.x, intersect.y, intersect.z, toonHeight, toonSize)) { best_z = intersect.z; best_flags = t_flags; found = true; } } } } } } if (found) { Vector up, dn, tmp; up.z = best_z + 2; dn.z = best_z - 5; bool[] nearCliff = { true, true, true, true }; bool allGood = true; foreach (int t in ts) { Vector vertex0; Vector vertex1; Vector vertex2; tc.GetTriangleVertices(t, out vertex0.x, out vertex0.y, out vertex0.z, out vertex1.x, out vertex1.y, out vertex1.z, out vertex2.x, out vertex2.y, out vertex2.z); float[] dx = { minCliffD, -minCliffD, 0, 0 }; float[] dy = { 0, 0, minCliffD, -minCliffD }; // Check if it is close to a "cliff" allGood = true; for (int i = 0; i < 4; i++) { if (nearCliff[i]) { up.x = dn.x = x + dx[i]; up.y = dn.y = y + dy[i]; if (Utils.SegmentTriangleIntersect(up, dn, vertex0, vertex1, vertex2, out tmp)) { nearCliff[i] = false; } } allGood &= !nearCliff[i]; } if (allGood) { break; } } allGood = true; for (int i = 0; i < 4; i++) { allGood &= !nearCliff[i]; } if (!allGood) { z0 = best_z; flags = best_flags; return(false); // too close to cliff } } z0 = best_z; flags = best_flags; return(found); }
public bool FindStandableAt2(double xx, double yy, float min_z, float max_z, out float z0, out int flags, float toonHeight, float toonSize, bool IgnoreGradient) { float x = (float)xx; float y = (float)yy; TriangleCollection tc = GetChunkAt(x, y); ICollection <int> ts, tsm, tst; float minCliffD = 0.5f; ts = null; if (UseOctree) { TriangleOctree ot = tc.GetOctree(); tst = ts = ot.FindTrianglesInBox(x - minCliffD, y - minCliffD, min_z, x + minCliffD, y + minCliffD, max_z); } if (UseMatrix) { TriangleMatrix tm = tc.GetTriangleMatrix(); tsm = ts = tm.GetAllCloseTo(x, y, 2.0f); } Vector s0, s1, s2, s3, s4, s5, s6, s7, s8, s9; s0.x = x; s0.y = y; s0.z = min_z; s1.x = x; s1.y = y; s1.z = max_z; float gap = (float)0.2; s2.x = x + gap; s2.y = y; s2.z = min_z; s3.x = x + gap; s3.y = y; s3.z = max_z; s4.x = x - gap; s4.y = y; s4.z = min_z; s5.x = x - gap; s5.y = y; s5.z = max_z; s6.x = x; s6.y = y + gap; s6.z = min_z; s7.x = x; s7.y = y + gap; s7.z = max_z; s8.x = x; s8.y = y - gap; s8.z = min_z; s9.x = x; s9.y = y - gap; s9.z = max_z; float best_z = -1E30f; int best_flags = 0; bool found = false; //logger.WriteLine(string.Format("x: {0} y: {1} min_z: {2} max_z: {3}", x, y, min_z, max_z)); foreach (int t in ts) { Vector vertex0; Vector vertex1; Vector vertex2; Vector intersect; int t_flags, sequence; tc.GetTriangleVertices(t, out vertex0.x, out vertex0.y, out vertex0.z, out vertex1.x, out vertex1.y, out vertex1.z, out vertex2.x, out vertex2.y, out vertex2.z, out t_flags, out sequence); // logger.WriteLine(string.Format("x: {0},{1},{2} y: {3},{4},{5} z: {6},{7},{8}",vertex0.x,vertex1.x,vertex2.x,vertex0.y,vertex1.y,vertex2.y,vertex0.z,vertex1.z,vertex2.z)); Vector normal; Utils.GetTriangleNormal(vertex0, vertex1, vertex2, out normal); float angle_z = (float)Math.Sin(40.0 / 360.0 * Math.PI * 2); // if (Utils.abs(normal.z) > angle_z || IgnoreGradient) { bool hasIntersected = false; hasIntersected = Utils.SegmentTriangleIntersect(s0, s1, vertex0, vertex1, vertex2, out intersect); if (!hasIntersected) { hasIntersected = Utils.SegmentTriangleIntersect(s2, s3, vertex0, vertex1, vertex2, out intersect); } if (!hasIntersected) { hasIntersected = Utils.SegmentTriangleIntersect(s4, s5, vertex0, vertex1, vertex2, out intersect); } if (!hasIntersected) { hasIntersected = Utils.SegmentTriangleIntersect(s6, s7, vertex0, vertex1, vertex2, out intersect); } if (!hasIntersected) { hasIntersected = Utils.SegmentTriangleIntersect(s8, s9, vertex0, vertex1, vertex2, out intersect); } if (hasIntersected) { if (intersect.z > best_z) { if (!IsSpotBlocked(intersect.x, intersect.y, intersect.z, toonHeight, toonSize)) { logger.WriteLine("new best z:" + intersect.z.ToString()); best_z = intersect.z; best_flags = t_flags; found = true; } } else { //logger.WriteLine("not best"); } } else { //logger.WriteLine("Utils.SegmentTriangleIntersect false"); } } else { //logger.WriteLine(string.Format("utils.abs(normal.z) {0} > angle_z {1}", Utils.abs(normal.z), angle_z)); } } if (found) { Vector up, dn, tmp; up.z = best_z + 2; dn.z = best_z - 5; bool[] nearCliff = { true, true, true, true }; bool allGood = true; foreach (int t in ts) { Vector vertex0; Vector vertex1; Vector vertex2; tc.GetTriangleVertices(t, out vertex0.x, out vertex0.y, out vertex0.z, out vertex1.x, out vertex1.y, out vertex1.z, out vertex2.x, out vertex2.y, out vertex2.z); float[] dx = { minCliffD, -minCliffD, 0, 0 }; float[] dy = { 0, 0, minCliffD, -minCliffD }; // Check if it is close to a "cliff" allGood = true; for (int i = 0; i < 4; i++) { if (nearCliff[i]) { up.x = dn.x = x + dx[i]; up.y = dn.y = y + dy[i]; if (Utils.SegmentTriangleIntersect(up, dn, vertex0, vertex1, vertex2, out tmp)) { nearCliff[i] = false; } } allGood &= !nearCliff[i]; } if (allGood) { break; } } allGood = true; for (int i = 0; i < 4; i++) { allGood &= !nearCliff[i]; } if (!allGood) { z0 = best_z; flags = best_flags; return(false); // too close to cliff } } z0 = best_z; flags = best_flags; return(found); }
public bool IsStepBlocked(float x0, float y0, float z0, float x1, float y1, float z1, float toonHeight, float toonSize, TriangleCollection paintI) { TriangleCollection tc = GetChunkAt(x0, y0); float dx = x0 - x1; float dy = y0 - y1; float dz = z0 - z1; float stepLength = (float)Math.Sqrt(dx * dx + dy * dy + dz * dz); // 1: check steepness // TODO // 2: check is there is a big step float mid_x = (x0 + x1) / 2.0f; float mid_y = (y0 + y1) / 2.0f; float mid_z = (z0 + z1) / 2.0f; float mid_z_hit = 0; float mid_dz = Math.Abs(stepLength); //if (mid_dz < 1.0f) mid_dz = 1.0f; int mid_flags = 0; if (FindStandableAt(mid_x, mid_y, mid_z - mid_dz, mid_z + mid_dz, out mid_z_hit, out mid_flags, toonHeight, toonSize)) { float dz0 = Math.Abs(z0 - mid_z_hit); float dz1 = Math.Abs(z1 - mid_z_hit); // Console.WriteLine("z0 " + z0 + " z1 " + z1 + " dz0 " + dz0+ " dz1 " + dz1 ); if (dz0 > stepLength / 2.0 && dz0 > 1.0) { return(true); // too steep } if (dz1 > stepLength / 2.0 && dz1 > 1.0) { return(true); // too steep } } else { // bad! return(true); } ICollection <int> ts, tsm, tst; ts = null; if (UseOctree) { TriangleOctree ot = tc.GetOctree(); tst = ts = ot.FindTrianglesInBox(Utils.min(x0, x1), Utils.min(y0, y1), Utils.min(z0, z1), Utils.max(x0, x1), Utils.max(y0, y1), Utils.max(z0, z1)); } if (UseMatrix) { TriangleMatrix tm = tc.GetTriangleMatrix(); tsm = ts = tm.GetAllInSquare(Utils.min(x0, x1), Utils.min(y0, y1), Utils.max(x0, x1), Utils.max(y0, y1)); } // 3: check collision with objects Vector from, from_up, from_low; Vector to, to_up, to_low; from.x = x0; from.y = y0; from.z = z0 + toonSize; //+0.5 to.x = x1; to.y = y1; to.z = z1 + toonSize; from_up = new Vector(from); from_up.z = z0 + toonHeight - toonSize; to_up = new Vector(to); to_up.z = z1 + toonHeight - toonSize; //diagonal if (CheckForCollision(tc, ts, ref from, ref to_up)) { return(true); } //diagonal if (CheckForCollision(tc, ts, ref from_up, ref to)) { return(true); } //head height // if (CheckForCollision(tc, ts, ref from_up, ref to_up)) { return true; } //close to the ground from_low = new Vector(from); from_low.z = z0 + 0.2f; to_low = new Vector(to); to_low.z = z1 + 0.2f; if (CheckForCollision(tc, ts, ref from_low, ref to_low)) { return(true); } float ddx, ddy; GetNormal(x0, y0, x1, y1, out ddx, out ddy, 0.2f); from_low.x += ddy; from_low.y += ddx; to_low.x += ddy; to_low.y += ddx; if (CheckForCollision(tc, ts, ref from_low, ref to_low)) { return(true); } from_low.x -= 2 * ddy; from_low.y -= 2 * ddx; to_low.x -= 2 * ddy; to_low.y -= 2 * ddx; if (CheckForCollision(tc, ts, ref from_low, ref to_low)) { return(true); } return(false); }
public bool IsStepBlocked(float x0, float y0, float z0, float x1, float y1, float z1, float toonHeight, float toonSize, TriangleCollection paintI) { TriangleCollection tc = GetChunkAt(x0, y0); ICollection <int> ts, tsm, tst; ts = null; if (UseOctree) { TriangleOctree ot = tc.GetOctree(); tst = ts = ot.FindTrianglesInBox(Utils.min(x0, x1), Utils.min(y0, y1), Utils.min(z0, z1), Utils.max(x0, x1), Utils.max(y0, y1), Utils.max(z0, z1)); } if (UseMatrix) { TriangleMatrix tm = tc.GetTriangleMatrix(); tsm = ts = tm.GetAllInSquare(Utils.min(x0, x1), Utils.min(y0, y1), Utils.max(x0, x1), Utils.max(y0, y1)); } bool coll = false; Vector from, from_up; Vector to, to_up; from.x = x0; from.y = y0; from.z = z0 + toonSize; from_up.x = x0; from_up.y = y0; from_up.z = z0 + toonHeight - toonSize; to.x = x1; to.y = y1; to.z = z1 + toonSize; to_up.x = x1; to_up.y = y1; to_up.z = z1 + toonHeight - toonSize; foreach (int t in ts) //for(int t = 0 ; t<tc.GetNumberOfTriangles(); t++) { Vector vertex0; Vector vertex1; Vector vertex2; Vector intersect; tc.GetTriangleVertices(t, out vertex0.x, out vertex0.y, out vertex0.z, out vertex1.x, out vertex1.y, out vertex1.z, out vertex2.x, out vertex2.y, out vertex2.z); if (Utils.SegmentTriangleIntersect(from, to_up, vertex0, vertex1, vertex2, out intersect) || Utils.SegmentTriangleIntersect(from_up, to, vertex0, vertex1, vertex2, out intersect)) { if (paintI != null) { //paintI.AddMarker(intersect.x, intersect.y, intersect.z); } //Console.WriteLine("Collided at " + intersect); coll = true; return(true); // blocked! } } return(coll); }
public bool IsStepBlocked(float x0, float y0, float z0, float x1, float y1, float z1, float toonHeight, float toonSize, TriangleCollection paintI) { TriangleCollection tc = GetChunkAt(x0, y0); float dx = x0 - x1; float dy = y0 - y1; float dz = z0 - z1; var stepLength = (float)Math.Sqrt(dx * dx + dy * dy + dz + dz); // 1: check steepness // TODO // 2: check is there is a big step float mid_x = (x0 + x1) / 2.0f; float mid_y = (y0 + y1) / 2.0f; float mid_z = (z0 + z1) / 2.0f; float mid_z_hit = 0; float mid_dz = Math.Abs(stepLength); //if (mid_dz < 1.0f) mid_dz = 1.0f; int mid_flags = 0; if (FindStandableAt(mid_x, mid_y, mid_z - mid_dz, mid_z + mid_dz, out mid_z_hit, out mid_flags, toonHeight, toonSize)) { float dz0 = Math.Abs(z0 - mid_z_hit); float dz1 = Math.Abs(z1 - mid_z_hit); // PathGraph.Log("z0 " + z0 + " z1 " + z1 + " dz0 " + dz0+ " dz1 " + dz1 ); if (dz0 > stepLength / 2.0 && dz0 > 1.0) { return(true); // too steep } if (dz1 > stepLength / 2.0 && dz1 > 1.0) { return(true); // too steep } } else { // bad! return(true); } ICollection <int> ts, tsm, tst; ts = null; if (UseOctree) { TriangleOctree ot = tc.GetOctree(); tst = ts = ot.FindTrianglesInBox(Utils.min(x0, x1), Utils.min(y0, y1), Utils.min(z0, z1), Utils.max(x0, x1), Utils.max(y0, y1), Utils.max(z0, z1)); } if (UseMatrix) { TriangleMatrix tm = tc.GetTriangleMatrix(); tsm = ts = tm.GetAllInSquare(Utils.min(x0, x1), Utils.min(y0, y1), Utils.max(x0, x1), Utils.max(y0, y1)); } // 3: check collision with objects bool coll = false; Vector from, from_up; Vector to, to_up; from.x = x0; from.y = y0; from.z = z0 + toonSize; from_up.x = x0; from_up.y = y0; from_up.z = z0 + toonHeight - toonSize; to.x = x1; to.y = y1; to.z = z1 + toonSize; to_up.x = x1; to_up.y = y1; to_up.z = z1 + toonHeight - toonSize; foreach (int t in ts) //for(int t = 0 ; t<tc.GetNumberOfTriangles(); t++) { Vector vertex0; Vector vertex1; Vector vertex2; Vector intersect; tc.GetTriangleVertices(t, out vertex0.x, out vertex0.y, out vertex0.z, out vertex1.x, out vertex1.y, out vertex1.z, out vertex2.x, out vertex2.y, out vertex2.z); if (Utils.SegmentTriangleIntersect(from, to_up, vertex0, vertex1, vertex2, out intersect) || Utils.SegmentTriangleIntersect(from_up, to, vertex0, vertex1, vertex2, out intersect)) { if (paintI != null) { //paintI.AddMarker(intersect.x, intersect.y, intersect.z); } //PathGraph.Log("Collided at " + intersect); coll = true; return(true); // blocked! } } return(coll); }