public bool IsMdxInstanceSelected(MDX.M2Info info, uint id) { if(mMdxResult == null) return false; return (mMdxResult.Model == info && mMdxResult.InstanceID == id); }
/// <summary> /// Loads the specified game model from the archives and deserializes it into an <see cref="MDX"/> model. /// </summary> /// <param name="fileReference">A reference to a model.</param> /// <returns>An object containing the model data pointed to by the reference.</returns> public static MDX LoadGameModel(FileReference fileReference) { if (fileReference == null) { throw new ArgumentNullException(nameof(fileReference)); } MDX model; try { byte[] fileData = fileReference.Extract(); model = new MDX(fileData); if (model.Version >= WarcraftVersion.Wrath) { // Load external skins var modelFilename = Path.GetFileNameWithoutExtension(fileReference.Filename); var modelDirectory = fileReference.FileDirectory.Replace(Path.DirectorySeparatorChar, '\\'); List <MDXSkin> skins = new List <MDXSkin>(); for (int i = 0; i < model.SkinCount; ++i) { var modelSkinPath = $"{modelDirectory}\\{modelFilename}{i:D2}.skin"; var skinData = fileReference.Context.Assets.ExtractFile(modelSkinPath); using (var ms = new MemoryStream(skinData)) { using (var br = new BinaryReader(ms)) { var skinIdentifier = new string(br.ReadChars(4)); if (skinIdentifier != "SKIN") { break; } skins.Add(br.ReadMDXSkin(model.Version)); } } } model.SetSkins(skins); } } catch (FileNotFoundException fex) { Log.Warn($"Failed to load the model \"{fileReference.FilePath}\": {fex}"); throw; } catch (InvalidFileSectorTableException fex) { Log.Warn($"Failed to load the model \"{fileReference.FilePath}\" due to an invalid sector table (\"{fex.Message}\")."); throw; } return(model); }
/// <summary> /// Initializes a new instance of the <see cref="RenderableGameModel"/> class. /// </summary> /// <param name="inModel">The model to render.</param> /// <param name="inPackageGroup">The package group the model belongs to.</param> /// <param name="shouldInitialize">Whether or not the model should be initialized right away.</param> public RenderableGameModel(MDX inModel, PackageGroup inPackageGroup, bool shouldInitialize) { this.Model = inModel; this.ModelPackageGroup = inPackageGroup; this.IsInitialized = false; if (shouldInitialize) { Initialize(); } }
public static Microsoft.AnalysisServices.AdomdServer.Set ParallelGenerate(Microsoft.AnalysisServices.AdomdServer.Set IterationSet, string SetExpression) { List <ParallelQueryThreadInfo> threadInfos = new List <ParallelQueryThreadInfo>(); string connectionString = "Data Source=" + Context.CurrentServerID + ";initial catalog=" + Context.CurrentDatabaseName + ";"; foreach (Microsoft.AnalysisServices.AdomdServer.Tuple t in IterationSet) { //build the text of current tuple string tupleText = "("; for (int n = 1; n <= t.Members.Count; n++) { tupleText += t.Members[n - 1].UniqueName; if (n < t.Members.Count) { tupleText += ","; } } tupleText += ")"; //build the object that will be passed to the worker thread ParallelQueryThreadInfo info = new ParallelQueryThreadInfo(); info.connectionString = connectionString; info.query = "with member measures.internalcalc as SetToStr(" + SetExpression + ") select measures.internalcalc on 0 from [" + Context.CurrentCube.Name + "] where(" + tupleText + ")"; info.autoEvent = new AutoResetEvent(false); threadInfos.Add(info); ThreadPool.QueueUserWorkItem(new WaitCallback(RunAQuery), info); } StringBuilder sFinalSet = new StringBuilder("{"); for (int i = 0; i < threadInfos.Count; i++) { //wait until they've finished while (!threadInfos[i].autoEvent.WaitOne(1000, false)) { Context.CheckCancelled(); } if (threadInfos[i].ex != null) { throw threadInfos[i].ex; } if (i > 0) { sFinalSet.Append(" + "); } sFinalSet.Append(threadInfos[i].returnValue); } sFinalSet.Append("}"); //union the sets they return return(MDX.StrToSet(sFinalSet.ToString())); }
/// <summary> /// Creates a renderable object from the specified <see cref="MDX"/> object, and the specified /// <see cref="FileReference"/> it is associated with. /// NOTE: This method *must* be called in the UI thread after the OpenGL context has been made current. /// The <see cref="IRenderable"/> constructors commonly make extensive use of OpenGL methods. /// </summary> /// <param name="gameModel">The model object.</param> /// <param name="fileReference">The reference it was constructed from.</param> /// <returns>An encapsulated renderable OpenGL object.</returns> public static IRenderable CreateRenderableGameModel(MDX gameModel, FileReference fileReference) { var warcraftContext = fileReference.Context as WarcraftGameContext; if (warcraftContext == null) { // TODO: This is bad practice. Refactor throw new ArgumentException("The given context must be a warcraft-typed context.", nameof(fileReference.Context)); } RenderableGameModel renderableModel = new RenderableGameModel(gameModel, warcraftContext, fileReference.FilePath); return(renderableModel); }
// ======================================================= // Pass a model file path as an argument to start the test // ======================================================= static void Main(string[] args) { if (!(args?.Length > 0)) { Console.WriteLine("Pass a model file path as an argument to start the test"); return; } var path = args[0]; if (!File.Exists(path)) { Console.WriteLine($"Path {path} not found"); return; } Console.WriteLine($"Loading from \"{path}\""); var mdx = new MDX(path); Console.WriteLine(); Console.WriteLine($"{nameof(mdx.Info.Name)}: {mdx.Info.Name}"); Console.WriteLine($"{nameof(mdx.Sequences)}: {mdx.Sequences?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.GlobalSequences)}: {mdx.GlobalSequences?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.Materials)}: {mdx.Materials?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.Textures)}: {mdx.Textures?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.TextureAnimations)}: {mdx.TextureAnimations?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.Geosets)}: {mdx.Geosets?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.GeosetAnimations)}: {mdx.GeosetAnimations?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.Bones)}: {mdx.Bones?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.Lights)}: {mdx.Lights?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.Helpers)}: {mdx.Helpers?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.Attachments)}: {mdx.Attachments?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.Pivots)}: {mdx.Pivots?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.ParticleEmitters)}: {mdx.ParticleEmitters?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.ParticleEmitters2)}: {mdx.ParticleEmitters2?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.RibbonEmitters)}: {mdx.RibbonEmitters?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.EventObjects)}: {mdx.EventObjects?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.Cameras)}: {mdx.Cameras?.Length ?? 0}"); Console.WriteLine($"{nameof(mdx.CollisionShapes)}: {mdx.CollisionShapes?.Length ?? 0}"); Console.WriteLine(); var newPath = Path.ChangeExtension(path, "new.mdx"); Console.WriteLine($"Saving to \"{newPath}\""); mdx.SaveTo(newPath); }
public static Microsoft.AnalysisServices.AdomdServer.Set ParallelUnion(string SetExpression1, string SetExpression2) { List <ParallelQueryThreadInfo> threadInfos = new List <ParallelQueryThreadInfo>(); string connectionString = "Data Source=" + Context.CurrentServerID + ";initial catalog=" + Context.CurrentDatabaseName + ";"; for (int n = 0; n < 2; n++) { //build the object that will be passed to the worker thread ParallelQueryThreadInfo info = new ParallelQueryThreadInfo(); info.connectionString = connectionString; if (n == 0) { info.query = "with member measures.internalcalc as SetToStr(" + SetExpression1 + ") select measures.internalcalc on 0 from [" + Context.CurrentCube.Name + "]"; } else { info.query = "with member measures.internalcalc as SetToStr(" + SetExpression2 + ") select measures.internalcalc on 0 from [" + Context.CurrentCube.Name + "]"; } info.autoEvent = new AutoResetEvent(false); threadInfos.Add(info); ThreadPool.QueueUserWorkItem(new WaitCallback(RunAQuery), info); } StringBuilder sFinalSet = new StringBuilder("{"); for (int i = 0; i < threadInfos.Count; i++) { //wait until they've finished while (!threadInfos[i].autoEvent.WaitOne(1000, false)) { Context.CheckCancelled(); } if (threadInfos[i].ex != null) { throw threadInfos[i].ex; } if (i > 0) { sFinalSet.Append(" + "); } sFinalSet.Append(threadInfos[i].returnValue); } sFinalSet.Append("}"); return(MDX.StrToSet(sFinalSet.ToString())); }
/// <summary> /// Initializes a new instance of the <see cref="RenderableGameModel"/> class. /// </summary> /// <param name="inModel">The model to render.</param> /// <param name="gameContext">The game context.</param> public RenderableGameModel(MDX inModel, WarcraftGameContext gameContext) { this.Model = inModel; this.GameContext = gameContext; this.ActorTransform = new Transform(); // Set a default display info for this model var displayInfo = GetSkinVariations().FirstOrDefault(); if (displayInfo != null) { this.CurrentDisplayInfo = displayInfo; } this.IsInitialized = false; }
/// <summary> /// Releases all resource used by the <see cref="RenderableGameModel"/> object. /// </summary> /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="RenderableGameModel"/>. The /// <see cref="Dispose"/> method leaves the <see cref="RenderableGameModel"/> in an unusable state. /// After calling <see cref="Dispose"/>, you must release all references to the /// <see cref="RenderableGameModel"/> so the garbage collector can reclaim the memory that the /// <see cref="RenderableGameModel"/> was occupying.</remarks> public void Dispose() { this.Model.Dispose(); this.Model = null; }
/// <summary> /// Initializes a new instance of the <see cref="RenderableGameModel"/> class. /// </summary> public RenderableGameModel(MDX inModel) { this.Model = inModel; }
/// <summary> /// Converts the given MDX model into an Assimp representation. /// </summary> /// <param name="model">The model.</param> /// <returns>The Assimp representation.</returns> public static Scene FromMDX(MDX model) { var scene = new Scene(); var rootNode = new Node(); scene.RootNode = rootNode; var modelNode = new Node(model.Name, rootNode); rootNode.Children.Add(modelNode); var defaultMaterial = new Material(); scene.Materials.Add(defaultMaterial); foreach (var skin in model.Skins) { var skinNode = new Node($"LOD_{model.Skins.ToList().IndexOf(skin)}", modelNode); modelNode.Children.Add(skinNode); var skinVerts = skin.VertexIndices.Select(i => model.Vertices[i]).ToArray(); foreach (var section in skin.Sections) { var mesh = new Mesh(); scene.Meshes.Add(mesh); mesh.MaterialIndex = scene.Materials.IndexOf(defaultMaterial); var modelBones = model.Bones.Skip(section.StartBoneIndex).Take(section.BoneCount); foreach (var modelBone in modelBones) { var bone = new Bone(); // TODO: Calculate offset matrices mesh.Bones.Add(bone); } var batchNode = new Node($"Section_{skin.Sections.ToList().IndexOf(section)}", skinNode); skinNode.Children.Add(batchNode); batchNode.MeshIndices.Add(scene.Meshes.IndexOf(mesh)); var skinVertexIndexes = new Span <ushort> ( skin.VertexIndices.ToArray(), section.StartVertexIndex, section.VertexCount ).ToArray(); mesh.UVComponentCount[0] = 2; mesh.UVComponentCount[1] = 2; for (var i = 0; i < skinVertexIndexes.Length; ++i) { var localIndex = skinVertexIndexes[i]; var vertex = skinVerts[localIndex]; mesh.Vertices.Add(new Vector3D(vertex.Position.X, vertex.Position.Y, vertex.Position.Z)); mesh.Normals.Add(new Vector3D(vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z)); mesh.TextureCoordinateChannels[0].Add(new Vector3D(vertex.UV1.X, vertex.UV1.Y, 0.0f)); mesh.TextureCoordinateChannels[1].Add(new Vector3D(vertex.UV2.X, vertex.UV2.Y, 0.0f)); if (mesh.HasBones) { for (var boneAttributeIndex = 0; boneAttributeIndex < 4; ++boneAttributeIndex) { var bone = mesh.Bones[vertex.BoneIndices[boneAttributeIndex]]; var weight = vertex.BoneWeights[boneAttributeIndex]; bone.VertexWeights.Add(new VertexWeight(i, weight)); } } } var triangleIndexes = new Span <ushort> ( skin.Triangles.ToArray(), section.StartTriangleIndex, section.TriangleCount ).ToArray(); mesh.SetIndices(triangleIndexes.Select(index => (int)index).ToArray(), 3); } } return(scene); }
/// <summary> /// Initializes a new instance of the <see cref="RenderableGameModel"/> class. /// </summary> /// <param name="inModel">The model to render.</param> /// <param name="gameContext">The game context.</param> /// <param name="modelPath">The full path of the model in the package group.</param> public RenderableGameModel(MDX inModel, WarcraftGameContext gameContext, string modelPath) : this(inModel, gameContext) { this.ModelPath = modelPath; }
/// <summary> /// Releases all resource used by the <see cref="RenderableGameModel"/> object. /// </summary> /// <remarks>Call <see cref="Dispose"/> when you are finished using the <see cref="RenderableGameModel"/>. The /// <see cref="Dispose"/> method leaves the <see cref="RenderableGameModel"/> in an unusable state. /// After calling <see cref="Dispose"/>, you must release all references to the /// <see cref="RenderableGameModel"/> so the garbage collector can reclaim the memory that the /// <see cref="RenderableGameModel"/> was occupying.</remarks> public void Dispose() { Model.Dispose(); Model = null; }
private static Set buildAsymmetricSet(params Member[] memberList) { Context.TraceEvent(100, 0, "AsymmetricSet: Starting"); // build a list of all the unique Hierarchies from the members in memberList. List <Hierarchy> hierList = new List <Hierarchy>(); foreach (Member m in memberList) { // Check that the member variable is correctly populated. If the user passes // in a non-existant member we get a member object whose properties are all // null or empty strings. if (m.UniqueName.Length > 0) { if (!hierList.Exists(delegate(Hierarchy h) { if (h.UniqueName == m.ParentLevel.ParentHierarchy.UniqueName) { return(true); } else { return(false); } })) { hierList.Add(m.ParentLevel.ParentHierarchy); } } } // SetBuilder & TupleBuilder are IDisposeable so we ensure they // are disposed by utilizing a using block. using (SetBuilder asymSet = new SetBuilder()) { foreach (Member paramMbr in memberList) { if (paramMbr.UniqueName.Length > 0) { // create a tuple for each member that was passed in, // combined with the default member from the other hierarchies. using (TupleBuilder tb = new TupleBuilder()) { foreach (Hierarchy h in hierList) // for each unique hierarchy { Hierarchy paramHier = paramMbr.ParentLevel.ParentHierarchy; if (paramHier.UniqueName == h.UniqueName) { //System.Diagnostics.Trace.WriteLine("Adding member " + paramMbr.UniqueName); tb.Add(paramMbr); } else { Member defMbr = MDX.StrToSet(h.DefaultMember).Tuples[0].Members[0]; //System.Diagnostics.Trace.WriteLine("Adding default member " + defMbr.UniqueName); tb.Add(defMbr); } } Tuple t = tb.ToTuple(); // if the members added to the TupleBuilder will result in a non-existant tuple // (eg. [Calendar Quarter 1] and [December]) the ToTuple method returns a Tuple // containing 0 members. If such a tuple is added to the SetBuilder, the // SetBuilder.ToSet will throw an exception if (t.Members.Count > 0) { asymSet.Add(tb.ToTuple()); } } // using tb } } //foreach paramMbr Context.TraceEvent(100, asymSet.Count, "AsymmetricSet: Finished (" + asymSet.Count.ToString() + " tuples generated)"); return(asymSet.ToSet()); } //using SetBuilder }
public void SelectMdxModel(MDX.MdxIntersectionResult result) { mMdxResult = result; mWmoResult = null; mSelectionBox.UpdateSelectionBox(result.Model.BoundingBox, result.InstanceData.ModelMatrix); if (mModelMover != null) mModelMover.ModelChanged -= mSelectionBox.UpdateMatrix; mModelMover = new MDX.M2ModelMover(result); mModelMover.ModelChanged += (matrix) => { mSelectionBox.UpdateMatrix(matrix); if (mCurrentSelection != null) mCurrentSelection.ModelPosition = new SlimDX.Vector3(matrix.M41, matrix.M42, matrix.M43); }; var modelOverlay = Game.GameManager.GraphicsThread.GetOverlay<UI.Overlays.ModelInfoOverlay>(); if (modelOverlay != null) modelOverlay.UpdateModel(result); else { modelOverlay = new UI.Overlays.ModelInfoOverlay(result); Game.GameManager.GraphicsThread.PushOverlay(modelOverlay); } ModelSelectionInfo info = new ModelSelectionInfo() { ModelName = result.Model.ModelPath, ModelMover = mModelMover, ModelPosition = new SlimDX.Vector3(result.InstanceData.ModelMatrix.M41, result.InstanceData.ModelMatrix.M42, result.InstanceData.ModelMatrix.M43) }; mCurrentSelection = info; if (ModelSelected != null) ModelSelected(info); }