private static ZoneInfo LoadZone(BinaryReader reader) { var id = reader.ReadUInt32(); if (_zones[id] == null) { _zones[id] = new ZoneInfo(); } var zone = _zones[id]; zone.ID = id; zone.OffsetX = reader.ReadUInt32(); zone.OffsetY = reader.ReadUInt32(); // These are not really needed right now, and are just hints anyway UInt32 numNifs = reader.ReadUInt32(); UInt32 numFixtures = reader.ReadUInt32(); return(zone); }
public static OcclusionResult OcclusionQuery( ushort zoneId0, float x0, float y0, float z0, ushort zoneId1, float x1, float y1, float z1, ref Vector3 hitpoint) { OcclusionResult result; SegmentTestInfo info = new SegmentTestInfo(); long timeBegin = DebugEnable ? Timer.Value : 0; try { ZoneInfo zone = _zones[zoneId0]; if (zone == null || zone.Collision == null) { result = OcclusionResult.NotLoaded; } else if (!zone.Enabled) { return(OcclusionResult.NotEnabled); } else if (zoneId0 != zoneId1) { result = OcclusionResult.NotImplemented; } else { x0 = 65535.0f - x0; x1 = 65535.0f - x1; Vector3 p0 = new Vector3(x0, y0, z0), p1 = new Vector3(x1, y1, z1); if (SegmentTest(p0, p1, zone.Collision, zone.Collision.BSP, 0, ref info)) { bool hit = true; double nearest = GetDistance(p0, info.HitPoint); var hitPoint = new Vector3(info.HitPoint.X, info.HitPoint.Y, info.HitPoint.Z); hitpoint = info.HitPoint; int count = 0; //find the nearest to origin triangle hit while (hit) { var nextPoint = Lerp(info.HitPoint, p0, 0.01); hit = SegmentTest(p0, nextPoint, zone.Collision, zone.Collision.BSP, 0, ref info); if (hit && (info.HitPoint.X != hitPoint.X || info.HitPoint.Y != hitPoint.Y || info.HitPoint.Z != hitPoint.Z) && GetDistance(p0, info.HitPoint) < nearest) { hitpoint = info.HitPoint; } hitPoint = new Vector3(info.HitPoint.X, info.HitPoint.Y, info.HitPoint.Z); if (count > 100) { break; } count++; } result = OcclusionResult.Occluded; hitpoint.X = 65535.0f - hitpoint.X; } else { result = OcclusionResult.NotOccluded; } } } catch { result = OcclusionResult.InternalError; } if (DebugEnable) { long microseconds = (Timer.Value - timeBegin) * 1000000 / Timer.Frequency; float timePerTri = microseconds / (float)info.NumTrianglesTested; String msg = String.Format( "LOS Check: ({0}, {1}, {2}, {3}) -> ({4}, {5}, {6}, {7}) -> ", zoneId0, x0, y0, z0, zoneId1, x1, y1, z1); Console.Write(msg); Console.WriteLine(result.ToString() + " [nodes=" + info.NumNodesTested + ", triangles=" + info.NumTrianglesTested + ", μs=" + microseconds + ", μs/tri=" + timePerTri + "]"); } return(result); }
private static CollisionInfo LoadCollisionChunk(BinaryReader reader) { CollisionInfo collision = new CollisionInfo(); uint zoneID = reader.ReadUInt32(); // Read collision vertices uint vertexCount = reader.ReadUInt32(); collision.Vertices = new Vector3[vertexCount]; for (uint i = 0; i < vertexCount; i++) { collision.Vertices[i] = ReadVector3(reader); } // Read collision triangles uint triangleCount = reader.ReadUInt32(); uint indexSize = reader.ReadUInt32(); collision.Triangles = new TriangleInfo[triangleCount]; // int ii = 0; if (indexSize == 4) { for (uint i = 0; i < triangleCount; i++) { collision.Triangles[i] = new TriangleInfo() { i0 = reader.ReadUInt32(), i1 = reader.ReadUInt32(), i2 = reader.ReadUInt32(), fixture = reader.ReadUInt32() }; if (!collision.Fixtures.ContainsKey(collision.Triangles[i].fixture)) { collision.Fixtures[collision.Triangles[i].fixture] = new FixtureInfo(); } collision.Fixtures[collision.Triangles[i].fixture].Triangles.Add(i); } //for (uint i = 0; i <3 * triangleCount; i++) //{ // collision.Indices[i] = reader.ReadUInt32(); //} } else if (indexSize == 2) { throw new NotImplementedException(); } else { throw new Exception(); } if (_zones[zoneID] == null) { _zones[zoneID] = new ZoneInfo(); } _zones[zoneID].Collision = collision; return(collision); }