protected virtual void Dispose(bool disposing) { if (DoodadInstances != null) { foreach (var instance in DoodadInstances) { WorldFrame.Instance.M2Manager.RemoveInstance(instance.Hash, instance.Uuid); } DoodadInstances.Clear(); DoodadInstances = null; } if (TextureNames != null) { TextureNames.Clear(); TextureNames = null; } if (mTextures != null) { mTextures.Clear(); mTextures = null; } FullVertices = null; Continent = null; }
private void InitM2Models() { if (SeekChunk(mObjReader, Chunks.Mmdx) == false) return; var size = mObjReader.ReadInt32(); var bytes = mObjReader.ReadBytes(size); var fullString = Encoding.ASCII.GetString(bytes); var modelNames = fullString.Split('\0'); mDoodadNames.AddRange(modelNames.ToList()); var modelNameLookup = new Dictionary<int, string>(); var curOffset = 0; foreach (var name in modelNames) { modelNameLookup.Add(curOffset, name); curOffset += name.Length + 1; } if (SeekChunk(mObjReader, Chunks.Mmid) == false) return; size = mObjReader.ReadInt32(); mDoodadNameIds = mObjReader.ReadArray<int>(size / 4); if (SeekChunk(mObjReader, Chunks.Mddf) == false) return; size = mObjReader.ReadInt32(); mDoodadDefs = mObjReader.ReadArray<Mddf>(size / SizeCache<Mddf>.Size); var index = -1; foreach (var entry in mDoodadDefs) { ++index; if (entry.Mmid >= mDoodadNameIds.Length) continue; var nameId = mDoodadNameIds[entry.Mmid]; string modelName; if (modelNameLookup.TryGetValue(nameId, out modelName) == false) continue; var position = new Vector3(entry.Position.X, 64.0f * Metrics.TileSize - entry.Position.Z, entry.Position.Y); var rotation = new Vector3(360.0f - entry.Rotation.X, 360.0f - entry.Rotation.Z, entry.Rotation.Y - 90); var scale = entry.Scale / 1024.0f; var instance = WorldFrame.Instance.M2Manager.AddInstance(modelName, entry.UniqueId, position, rotation, new Vector3(scale)); DoodadInstances.Add(new M2Instance { Hash = modelName.ToUpperInvariant().GetHashCode(), Uuid = entry.UniqueId, BoundingBox = (instance != null ? instance.BoundingBox : new BoundingBox(new Vector3(float.MaxValue), new Vector3(float.MinValue))), RenderInstance = instance, MddfIndex = index }); } }
public int GetFreeM2Uuid() { if (DoodadInstances.Count >= (1 << 20) - 1) { return(-1); } var upper = IndexY * 64 + IndexX; var lower = DoodadInstances.Count + 1; while (DoodadInstances.Any(i => i.Uuid == ((upper << 20) | lower))) { ++lower; if (lower >= (1 << 20) - 1) { return(-1); } } return((upper << 20) | lower); }
public bool IsUuidAvailable(int uuid) { return(DoodadInstances.All(d => d.Uuid != uuid)); }
public virtual void Dispose() { DoodadInstances.Clear(); }
public override void AddDoodadInstance(int uuid, string modelName, BoundingBox box, Vector3 position, Vector3 rotation, float scale) { var mmidValue = 0; var nameFound = false; foreach (var s in mDoodadNames) { if (string.Equals(s, modelName, StringComparison.InvariantCultureIgnoreCase)) { nameFound = true; break; } mmidValue += s.Length + 1; } int mmidIndex; if (nameFound == false) { mmidValue = mDoodadNames.Sum(s => s.Length + 1); mmidIndex = mDoodadNameIds.Length; Array.Resize(ref mDoodadNameIds, mDoodadNameIds.Length + 1); mDoodadNameIds[mDoodadNameIds.Length - 1] = mmidValue; mDoodadNames.Add(modelName); } else { mmidIndex = -1; for (var i = 0; i < mDoodadNameIds.Length; ++i) { if (mDoodadNameIds[i] == mmidValue) { mmidIndex = i; break; } } if (mmidIndex < 0) { mmidIndex = mDoodadNameIds.Length; Array.Resize(ref mDoodadNameIds, mDoodadNameIds.Length + 1); mDoodadNameIds[mDoodadNameIds.Length - 1] = mmidValue; } } var mcrfValue = mDoodadDefs.Length; Array.Resize(ref mDoodadDefs, mDoodadDefs.Length + 1); mDoodadDefs[mDoodadDefs.Length - 1] = new Mddf { Position = new Vector3(position.X, position.Z, position.Y), Mmid = mmidIndex, Flags = 0, Scale = (ushort)(scale * 1024), UniqueId = uuid, Rotation = new Vector3(-rotation.X, 90 - rotation.Z, -rotation.Y) }; var instance = WorldFrame.Instance.M2Manager.AddInstance(modelName, uuid, position, rotation, new Vector3(scale)); DoodadInstances.Add(new M2Instance { Hash = modelName.ToUpperInvariant().GetHashCode(), Uuid = uuid, BoundingBox = (instance != null ? instance.BoundingBox : new BoundingBox(new Vector3(float.MaxValue), new Vector3(float.MinValue))), RenderInstance = instance, MddfIndex = mDoodadDefs.Length - 1 }); foreach (var chunk in mChunks) { if (chunk.BoundingBox.Contains(position) == ContainmentType.Contains) { chunk.AddDoodad(mcrfValue, box); } } mWasChanged = true; }