private static LosTreeType _LoadZone(Region region, Zone zone, string filename) { var(vertices, objects) = WavefrontObjFile.Load(zone, filename); if (vertices == null || vertices.Length == 0 || objects == null) { return(null); } var zoneMin = new Vector3(float.PositiveInfinity); var zoneMax = new Vector3(float.NegativeInfinity); foreach (var v in vertices) { if (v.Z <= 0 || v.Z > 65530) { continue; } zoneMin = Vector3.Min(zoneMin, v); zoneMax = Vector3.Max(zoneMax, v); } zoneMin.Z -= 500; zoneMax.Z += 500; var zoneTree = new LosTreeType(new AABoundingBox(zoneMin, zoneMax), 1); foreach (var faces in objects) { foreach (var(a, b, c) in faces) { zoneTree.AddObject(new Triangle(vertices, a, b, c)); } } if (log.IsDebugEnabled) { log.Debug($"[LosMgr] Zone {zone.ZoneSkinID} loaded: {objects.Count:N0} objects {objects.Select(o => o.Length).Sum():N0} faces {vertices.Length:N0} vertices"); } return(zoneTree); }
public static void Initialize() { LosTreeType.MaxObjectsPerNode = MAX_TRIANGLE_PER_TREE_NODE; Parallel.ForEach(WorldMgr.GetAllRegions(), region => { var tick = GameServer.Instance.TickCount; log.Debug($"loading region {region.Description} (id:{region.ID})..."); var zoneTriangles = new LosTreeType[region.Zones.Count]; lock (_regionTriangles) _regionTriangles.Add(region.ID, zoneTriangles); int i = 0; foreach (var zone in region.Zones) { zoneTriangles[i++] = _LoadZone(region, zone, Path.Combine("obj", $"zone{zone.ZoneSkinID:D3}.obj")); } if (log.IsDebugEnabled) { log.Debug($"[LosMgr] region {region.Description} (id:{region.ID}): {GameServer.Instance.TickCount - tick}ms"); } }); // just useful to do some tests, I keep it in case I want to implement a BVH version //StressTests(); }