protected override void ProcessInternal(ChunkedData subChunks) { if (!IsSane) return; var doodadReferencesChunk = subChunks.GetChunkByName("MCRD"); if (doodadReferencesChunk == null) return; var stream = doodadReferencesChunk.GetStream(); var reader = new BinaryReader(stream); var refCount = (int)(doodadReferencesChunk.Length/4); for (int i = 0; i < refCount; i++) { int index = reader.ReadInt32(); if (index < 0 || index >= _definitions.Count) continue; var doodad = _definitions[index]; if (_drawn.Contains(doodad.UniqueId)) continue; _drawn.Add(doodad.UniqueId); if (doodad.MmidIndex >= _paths.Count) continue; var path = _paths[(int) doodad.MmidIndex]; var model = Cache.Model.Get(path); if (model == null) { model = new Model(path); Cache.Model.Insert(path, model); } if (!model.IsCollidable) continue; // some weak heuristic to save memory allocation time if (Vertices == null) Vertices = new List<Vector3>((int)(refCount * model.Vertices.Length * 0.2)); if (Triangles == null) Triangles = new List<Triangle<uint>>((int)(refCount * model.Triangles.Length * 0.2)); InsertModelGeometry(doodad, model); } }
public static void InsertModelGeometry(List<Vector3> vertices, List<Triangle<uint>> triangles, WorldModelDefinition def, WorldModelRoot root) { var transformation = Transformation.GetTransformation(def); foreach (var group in root.Groups) { int vertOffset = vertices.Count; vertices.AddRange(group.Vertices.Select(vert => Vector3.Transform(vert, transformation).ToVector3())); for (int i = 0; i < group.Triangles.Length; i++) { // only include collidable tris if ((group.TriangleFlags[i] & 0x04) != 0 && group.TriangleMaterials[i] != 0xFF) continue; var tri = group.Triangles[i]; triangles.Add(new Triangle<uint>(TriangleType.Wmo, (uint) (tri.V0 + vertOffset), (uint) (tri.V1 + vertOffset), (uint) (tri.V2 + vertOffset))); } } if (def.DoodadSet >= 0 && def.DoodadSet < root.DoodadSets.Count) { var set = root.DoodadSets[def.DoodadSet]; var instances = new List<DoodadInstance>((int)set.CountInstances); for (uint i = set.FirstInstanceIndex; i < (set.CountInstances + set.FirstInstanceIndex); i++) { if (i >= root.DoodadInstances.Count) break; instances.Add(root.DoodadInstances[(int)i]); } foreach (var instance in instances) { var model = Cache.Model.Get(instance.File); if (model == null) { model = new Model(instance.File); Cache.Model.Insert(instance.File, model); } if (!model.IsCollidable) continue; var doodadTransformation = Transformation.GetWmoDoodadTransformation(instance, def); int vertOffset = vertices.Count; vertices.AddRange(model.Vertices.Select(vert => Vector3.Transform(vert, doodadTransformation).ToVector3())); foreach (var tri in model.Triangles) triangles.Add(new Triangle<uint>(TriangleType.Wmo, (uint) (tri.V0 + vertOffset), (uint) (tri.V1 + vertOffset), (uint) (tri.V2 + vertOffset))); } } foreach (var group in root.Groups) { if (!group.HasLiquidData) continue; for (int y = 0; y < group.LiquidDataHeader.Height; y++) { for (int x = 0; x < group.LiquidDataHeader.Width; x++) { if (!group.LiquidDataGeometry.ShouldRender(x, y)) continue; var vertOffset = (uint)vertices.Count; vertices.Add(GetLiquidVert(transformation, group.LiquidDataHeader.BaseLocation, group.LiquidDataGeometry.HeightMap[x, y], x, y)); vertices.Add(GetLiquidVert(transformation, group.LiquidDataHeader.BaseLocation, group.LiquidDataGeometry.HeightMap[x + 1, y], x + 1, y)); vertices.Add(GetLiquidVert(transformation, group.LiquidDataHeader.BaseLocation, group.LiquidDataGeometry.HeightMap[x, y + 1], x, y + 1)); vertices.Add(GetLiquidVert(transformation, group.LiquidDataHeader.BaseLocation, group.LiquidDataGeometry.HeightMap[x + 1, y + 1], x + 1, y + 1)); triangles.Add(new Triangle<uint>(TriangleType.Water, vertOffset, vertOffset + 2, vertOffset + 1)); triangles.Add(new Triangle<uint>(TriangleType.Water, vertOffset + 2, vertOffset + 3, vertOffset + 1)); } } } }
private void InsertModelGeometry(DoodadDefinition def, Model model) { var transformation = Transformation.GetTransformation(def); var vertOffset = (uint)Vertices.Count; foreach (var vert in model.Vertices) Vertices.Add(Vector3.Transform(vert, transformation)); foreach (var tri in model.Triangles) Triangles.Add(new Triangle<uint>(TriangleType.Doodad, tri.V0 + vertOffset, tri.V1 + vertOffset, tri.V2 + vertOffset)); }