public static WorldModelDefinition Read(Stream s) { var r = new BinaryReader(s); var ret = new WorldModelDefinition { MwidIndex = r.ReadUInt32(), UniqueId = r.ReadUInt32(), Position = Vector3Helper.Read(s), Rotation = Vector3Helper.Read(s), UpperExtents = Vector3Helper.Read(s), LowerExtents = Vector3Helper.Read(s), Flags = r.ReadUInt16(), DoodadSet = r.ReadUInt16() }; // discard some padding r.ReadUInt32(); return(ret); }
private void ReadDefinitions() { var chunk = Source.ObjectData.GetChunkByName("MODF"); if (chunk == null) { return; } const int definitionSize = 64; var definitionCount = (int)(chunk.Length / definitionSize); _definitions = new List <WorldModelDefinition>(definitionCount); var stream = chunk.GetStream(); for (int i = 0; i < definitionCount; i++) { _definitions.Add(WorldModelDefinition.Read(stream)); } }
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)); } } } }
public static WorldModelDefinition Read(Stream s) { var r = new BinaryReader(s); var ret = new WorldModelDefinition { MwidIndex = r.ReadUInt32(), UniqueId = r.ReadUInt32(), Position = Vector3Helper.Read(s), Rotation = Vector3Helper.Read(s), UpperExtents = Vector3Helper.Read(s), LowerExtents = Vector3Helper.Read(s), Flags = r.ReadUInt16(), DoodadSet = r.ReadUInt16() }; // discard some padding r.ReadUInt32(); return ret; }
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))); 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))); 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)); } } } }