예제 #1
0
        public override IEnumerable <int> GetIndexFragmentClusterFileOfFile(File _file)
        {
            var listIndex = new List <int>();

            //Add index of all cluster to empty
            var file = _file.FragmentFiles.First();

            if (file != null)
            {
                for (var i = 0; i < Clusters.Count; i++)
                {
                    var cluster = Clusters[i];
                    if (cluster.Content == file)
                    {
                        listIndex.Add(i);
                        break;
                    }
                }
            }
            while (file.NextCluster != null)
            {
                listIndex.Add(Clusters.IndexOf(file.NextCluster));
                file = file.NextCluster.Content as ContentFileCluster;
            }
            return(listIndex);
        }
예제 #2
0
        private IEnumerable <int> GetIndexFragmentClusterFileOfFile(File _file)
        {
            var listIndex = new List <int> {
                Clusters.IndexOf(_file.StartCluster)
            };

            //Add index of all cluster to empty
            var file = _file.FragmentFiles.First();

            while (file.NextCluster != null)
            {
                listIndex.Add(Clusters.IndexOf(file.NextCluster));
                file = file.NextCluster.ClusterFile as FragmentClusterFile;
            }
            return(listIndex);
        }
예제 #3
0
        public void BuildClusterWeightsMatrix()
        {
            // Initializing WC matrix
            ClusterWeightsMatrix = new Matrix <double>(Clusters.Count);

            if (ClusterComparisons != null)
            {
                // For each cluster that has dependent clusters, we are finding dependent clusters weights
                foreach (var cluster in ClusterComparisons.Keys)
                {
                    // Index of cluster
                    var clusterIndex = Clusters.IndexOf(cluster);

                    // Dependent clusters weights
                    //double[] weights = _weightsResolutionStrategy.GetWeights(ClusterComparisons[cluster].ToPairwiseComparisonMatrix());
                    var      task = ClusterComparisons[cluster];
                    double[] weights;
                    if (task.Weights.Sum() == 0)
                    {
                        weights = ClusterComparisons[cluster].Resolve();
                    }
                    else
                    {
                        weights = task.Weights;
                    }

                    // Dependent clusters
                    var clusterDependents = (from d in ClusterDependencies
                                             where d.Master.Equals(cluster)
                                             select d.Dependent).ToArray();

                    // Combination of dependent cluster and it's weight
                    var clusterWeights = from i in Enumerable.Range(0, clusterDependents.Length)
                                         select new { Cluster = clusterDependents[i], Weight = weights[i] };

                    // For each combination of dependent cluster and it's weight
                    foreach (var clusterWeight in clusterWeights)
                    {
                        // We are finding those dependent cluster index in Clusters collection
                        var dependentClusterIndex = Clusters.IndexOf(clusterWeight.Cluster);

                        // Setting appropriate WC element with value of dependent cluster weight
                        ClusterWeightsMatrix[dependentClusterIndex, clusterIndex] = clusterWeight.Weight;
                    }
                }
            }
        }
예제 #4
0
        /// <summary>
        /// This method is the main entry point for initialising the K-Means algorithm.
        /// The results of the analysis are put into the Clusters List found as a
        /// member variable within this class.
        /// The method will continue running until there have been no detected
        /// changes. A change is defined as at least one event moving from one cluster
        /// to another.
        /// </summary>
        public void Analyse()
        {
            // Divide the Coordinates in K Clusters
            Clusters = Coordinates.Split(K);

            // Number of changes made within a pass
            int changes = 0;

            // Continuously recompute, until no changes were made.
            do
            {
                // Reset the number of changes made
                changes = 0;

                // Loop over all Clusters
                foreach (EventCollection cluster in Clusters)
                {
                    // Loop over each Coordinate
                    for (int i = 0; i < cluster.Count; i++)
                    {
                        // Grab the event
                        Event evt = cluster[i];

                        // Find the nearest cluster's index
                        int nearest = FindNearestCluster(Clusters, evt);

                        // Check to see if the point has moved and is not empty
                        if (nearest != Clusters.IndexOf(cluster) && cluster.Count > 1)
                        {
                            // Remove the event from the current location
                            cluster.Remove(evt);

                            // Insert previously removed event into the correct cluster
                            evt.Coordinate.ClusterId = nearest;
                            Clusters[nearest].Add(evt);

                            // A change has happened
                            changes++;
                        }
                    }
                }
            }while (changes > 0);
        }
예제 #5
0
        public override IHierarchy Generate()
        {
            GroupHierarchy result = new GroupHierarchy()
            {
                Rank = this.Rank + 1
            };

            foreach (var SubCluster in Clusters)
            {
                Cluster similar = SubCluster.GetMostSimilar(GetNeighbours(SubCluster)).First();
                if (similar != null)
                {
                    result.AddCluster(Cluster.Combine(SubCluster, similar));
                }

                float progress = System.Convert.ToSingle((Clusters.IndexOf(SubCluster) + 1) / (double)Clusters.Count);
                Debug.WriteLine($"{progress}");
            }

            return(result);
        }
        public IGeometryModel ReadGeometry(int lod)
        {
            if (lod < 0 || lod >= ((IRenderGeometry)this).LodCount)
            {
                throw new ArgumentOutOfRangeException(nameof(lod));
            }

            var scenario = cache.TagIndex.GetGlobalTag("scnr").ReadMetadata <scenario>();
            var model    = new GeometryModel(item.FileName())
            {
                CoordinateSystem = CoordinateSystem.Default
            };

            var bspBlock = scenario.StructureBsps.First(s => s.BspReference.TagId == item.Id);
            var bspIndex = scenario.StructureBsps.IndexOf(bspBlock);

            var lightmap     = scenario.ScenarioLightmapReference.Tag.ReadMetadata <scenario_lightmap>();
            var lightmapData = lightmap.LightmapRefs[bspIndex].LightmapDataReference.Tag.ReadMetadata <scenario_lightmap_bsp_data>();

            model.Bounds.AddRange(lightmapData.BoundingBoxes);
            model.Materials.AddRange(Halo4Common.GetMaterials(Shaders));

            var clusterRegion = new GeometryRegion {
                Name = "Clusters"
            };

            clusterRegion.Permutations.AddRange(
                Clusters.Select((c, i) => new GeometryPermutation
            {
                SourceIndex = i,
                Name        = Clusters.IndexOf(c).ToString("D3", CultureInfo.CurrentCulture),
                MeshIndex   = c.SectionIndex,
                MeshCount   = 1
            })
                );
            model.Regions.Add(clusterRegion);

            if (!loadedInstances)
            {
                var resourceGestalt = cache.TagIndex.GetGlobalTag("zone").ReadMetadata <cache_file_resource_gestalt>();
                var entry           = resourceGestalt.ResourceEntries[InstancesResourcePointer.ResourceIndex];
                var address         = entry.ResourceFixups[entry.ResourceFixups.Count - 10].Offset & 0x0FFFFFFF;

                using (var ms = new MemoryStream(InstancesResourcePointer.ReadData(PageType.Auto)))
                    using (var reader = new EndianReader(ms, cache.ByteOrder))
                    {
                        var blockSize = cache.CacheType == CacheType.Halo4Beta ? 164 : 148;
                        for (int i = 0; i < GeometryInstances.Count; i++)
                        {
                            reader.Seek(address + blockSize * i, SeekOrigin.Begin);
                            GeometryInstances[i].TransformScale = reader.ReadSingle();
                            GeometryInstances[i].Transform      = new Matrix4x4
                            {
                                M11 = reader.ReadSingle(),
                                M12 = reader.ReadSingle(),
                                M13 = reader.ReadSingle(),

                                M21 = reader.ReadSingle(),
                                M22 = reader.ReadSingle(),
                                M23 = reader.ReadSingle(),

                                M31 = reader.ReadSingle(),
                                M32 = reader.ReadSingle(),
                                M33 = reader.ReadSingle(),

                                M41 = reader.ReadSingle(),
                                M42 = reader.ReadSingle(),
                                M43 = reader.ReadSingle(),
                            };
                            reader.Seek(10, SeekOrigin.Current);
                            GeometryInstances[i].SectionIndex = reader.ReadInt16();
                        }
                    }

                loadedInstances = true;
            }

            foreach (var instanceGroup in GeometryInstances.GroupBy(i => i.SectionIndex))
            {
                var section       = lightmapData.Sections[instanceGroup.Key];
                var sectionRegion = new GeometryRegion {
                    Name = Utils.CurrentCulture($"Instances {instanceGroup.Key:D3}")
                };
                sectionRegion.Permutations.AddRange(
                    instanceGroup.Select(i => new GeometryPermutation
                {
                    SourceIndex    = GeometryInstances.IndexOf(i),
                    Name           = i.Name,
                    Transform      = i.Transform,
                    TransformScale = i.TransformScale,
                    MeshIndex      = i.SectionIndex,
                    MeshCount      = 1
                })
                    );
                model.Regions.Add(sectionRegion);
            }

            model.Meshes.AddRange(Halo4Common.GetMeshes(cache, lightmapData.ResourcePointer, lightmapData.Sections, (s, m) =>
            {
                var index      = (short)lightmapData.Sections.IndexOf(s);
                m.BoundsIndex  = index >= lightmapData.BoundingBoxes.Count ? (short?)null : index;
                m.IsInstancing = index < lightmapData.BoundingBoxes.Count;
            }));

            return(model);
        }
        public IGeometryModel ReadGeometry(int lod)
        {
            if (lod < 0 || lod >= ((IRenderGeometry)this).LodCount)
            {
                throw new ArgumentOutOfRangeException(nameof(lod));
            }

            var model = new GeometryModel(item.FileName())
            {
                CoordinateSystem = CoordinateSystem.Default
            };

            model.Materials.AddRange(Halo2Common.GetMaterials(Shaders));

            #region Clusters
            var clusterRegion = new GeometryRegion {
                Name = "Clusters"
            };

            foreach (var section in Clusters.Where(s => s.VertexCount > 0))
            {
                var sectionIndex = Clusters.IndexOf(section);

                var data        = section.DataPointer.ReadData(section.DataSize);
                var baseAddress = section.HeaderSize + 8;

                using (var ms = new MemoryStream(data))
                    using (var reader = new EndianReader(ms, ByteOrder.LittleEndian))
                    {
                        var sectionInfo = reader.ReadObject <MeshResourceDetailsBlock>();

                        var submeshResource = section.Resources[0];
                        var indexResource   = section.Resources.FirstOrDefault(r => r.Type0 == 32);
                        var vertexResource  = section.Resources.FirstOrDefault(r => r.Type0 == 56 && r.Type1 == 0);
                        var uvResource      = section.Resources.FirstOrDefault(r => r.Type0 == 56 && r.Type1 == 1);
                        var normalsResource = section.Resources.FirstOrDefault(r => r.Type0 == 56 && r.Type1 == 2);

                        reader.Seek(baseAddress + submeshResource.Offset, SeekOrigin.Begin);
                        var submeshes = reader.ReadEnumerable <SubmeshDataBlock>(submeshResource.Size / 72).ToList();

                        var mesh = new GeometryMesh();

                        if (section.FaceCount * 3 == sectionInfo.IndexCount)
                        {
                            mesh.IndexFormat = IndexFormat.TriangleList;
                        }
                        else
                        {
                            mesh.IndexFormat = IndexFormat.TriangleStrip;
                        }

                        reader.Seek(baseAddress + indexResource.Offset, SeekOrigin.Begin);
                        mesh.Indicies = reader.ReadEnumerable <ushort>(sectionInfo.IndexCount).Select(i => (int)i).ToArray();

                        #region Vertices
                        mesh.Vertices = new IVertex[section.VertexCount];
                        var vertexSize = vertexResource.Size / section.VertexCount;
                        for (int i = 0; i < section.VertexCount; i++)
                        {
                            var vert = new WorldVertex();

                            reader.Seek(baseAddress + vertexResource.Offset + i * vertexSize, SeekOrigin.Begin);
                            vert.Position = new RealVector3D(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                            mesh.Vertices[i] = vert;
                        }

                        for (int i = 0; i < section.VertexCount; i++)
                        {
                            var vert = (WorldVertex)mesh.Vertices[i];

                            reader.Seek(baseAddress + uvResource.Offset + i * 8, SeekOrigin.Begin);
                            vert.TexCoords = new RealVector2D(reader.ReadSingle(), reader.ReadSingle());
                        }

                        for (int i = 0; i < section.VertexCount; i++)
                        {
                            var vert = (WorldVertex)mesh.Vertices[i];

                            reader.Seek(baseAddress + normalsResource.Offset + i * 12, SeekOrigin.Begin);
                            vert.Normal = new HenDN3(reader.ReadUInt32());
                        }
                        #endregion

                        var perm = new GeometryPermutation
                        {
                            SourceIndex = Clusters.IndexOf(section),
                            Name        = sectionIndex.ToString("D3", CultureInfo.CurrentCulture),
                            MeshIndex   = model.Meshes.Count,
                            MeshCount   = 1
                        };

                        foreach (var submesh in submeshes)
                        {
                            mesh.Submeshes.Add(new GeometrySubmesh
                            {
                                MaterialIndex = submesh.ShaderIndex,
                                IndexStart    = submesh.IndexStart,
                                IndexLength   = submesh.IndexLength
                            });
                        }

                        clusterRegion.Permutations.Add(perm);
                        model.Meshes.Add(mesh);
                    }
            }

            model.Regions.Add(clusterRegion);
            #endregion

            #region Instances
            foreach (var section in Sections.Where(s => s.VertexCount > 0))
            {
                var sectionIndex  = Sections.IndexOf(section);
                var sectionRegion = new GeometryRegion {
                    Name = Utils.CurrentCulture($"Instances {sectionIndex:D3}")
                };

                var data        = section.DataPointer.ReadData(section.DataSize);
                var baseAddress = section.HeaderSize + 8;

                using (var ms = new MemoryStream(data))
                    using (var reader = new EndianReader(ms, ByteOrder.LittleEndian))
                    {
                        var sectionInfo = reader.ReadObject <MeshResourceDetailsBlock>();

                        var submeshResource = section.Resources[0];
                        var indexResource   = section.Resources.FirstOrDefault(r => r.Type0 == 32);
                        var vertexResource  = section.Resources.FirstOrDefault(r => r.Type0 == 56 && r.Type1 == 0);
                        var uvResource      = section.Resources.FirstOrDefault(r => r.Type0 == 56 && r.Type1 == 1);
                        var normalsResource = section.Resources.FirstOrDefault(r => r.Type0 == 56 && r.Type1 == 2);

                        reader.Seek(baseAddress + submeshResource.Offset, SeekOrigin.Begin);
                        var submeshes = reader.ReadEnumerable <SubmeshDataBlock>(submeshResource.Size / 72).ToList();

                        var mesh = new GeometryMesh {
                            IsInstancing = true
                        };

                        if (section.FaceCount * 3 == sectionInfo.IndexCount)
                        {
                            mesh.IndexFormat = IndexFormat.TriangleList;
                        }
                        else
                        {
                            mesh.IndexFormat = IndexFormat.TriangleStrip;
                        }

                        reader.Seek(baseAddress + indexResource.Offset, SeekOrigin.Begin);
                        mesh.Indicies = reader.ReadEnumerable <ushort>(sectionInfo.IndexCount).Select(i => (int)i).ToArray();

                        #region Vertices
                        mesh.Vertices = new IVertex[section.VertexCount];
                        var vertexSize = vertexResource.Size / section.VertexCount;
                        for (int i = 0; i < section.VertexCount; i++)
                        {
                            var vert = new WorldVertex();

                            reader.Seek(baseAddress + vertexResource.Offset + i * vertexSize, SeekOrigin.Begin);
                            vert.Position = new RealVector3D(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle());

                            mesh.Vertices[i] = vert;
                        }

                        for (int i = 0; i < section.VertexCount; i++)
                        {
                            var vert = (WorldVertex)mesh.Vertices[i];

                            reader.Seek(baseAddress + uvResource.Offset + i * 8, SeekOrigin.Begin);
                            vert.TexCoords = new RealVector2D(reader.ReadSingle(), reader.ReadSingle());
                        }

                        for (int i = 0; i < section.VertexCount; i++)
                        {
                            var vert = (WorldVertex)mesh.Vertices[i];

                            reader.Seek(baseAddress + normalsResource.Offset + i * 12, SeekOrigin.Begin);
                            vert.Normal = new HenDN3(reader.ReadUInt32());
                        }
                        #endregion

                        var perms = GeometryInstances
                                    .Where(i => i.SectionIndex == sectionIndex)
                                    .Select(i => new GeometryPermutation
                        {
                            SourceIndex    = GeometryInstances.IndexOf(i),
                            Name           = i.Name,
                            Transform      = i.Transform,
                            TransformScale = i.TransformScale,
                            MeshIndex      = model.Meshes.Count,
                            MeshCount      = 1
                        }).ToList();

                        mesh.Submeshes.AddRange(
                            submeshes.Select(s => new GeometrySubmesh
                        {
                            MaterialIndex = s.ShaderIndex,
                            IndexStart    = s.IndexStart,
                            IndexLength   = s.IndexLength
                        })
                            );

                        sectionRegion.Permutations.AddRange(perms);
                        model.Meshes.Add(mesh);
                    }

                model.Regions.Add(sectionRegion);
            }
            #endregion

            return(model);
        }
예제 #8
0
        public IGeometryModel ReadGeometry(int lod)
        {
            if (lod < 0 || lod >= ((IRenderGeometry)this).LodCount)
            {
                throw new ArgumentOutOfRangeException(nameof(lod));
            }

            var scenario = cache.TagIndex.GetGlobalTag("scnr").ReadMetadata <scenario>();
            var model    = new GeometryModel(item.FileName())
            {
                CoordinateSystem = CoordinateSystem.Default
            };

            var bspBlock = scenario.StructureBsps.First(s => s.BspReference.TagId == item.Id);
            var bspIndex = scenario.StructureBsps.IndexOf(bspBlock);

            var lightmap     = scenario.ScenarioLightmapReference.Tag.ReadMetadata <scenario_lightmap>();
            var lightmapData = cache.CacheType < CacheType.MccHalo3U4
                ? lightmap.LightmapData.First(sldt => sldt.BspIndex == bspIndex)
                : lightmap.LightmapRefs.Select(sldt => sldt.Tag.ReadMetadata <scenario_lightmap_bsp_data>()).First(sldt => sldt.BspIndex == bspIndex);

            model.Bounds.AddRange(BoundingBoxes);
            model.Materials.AddRange(Halo3Common.GetMaterials(Shaders));

            var clusterRegion = new GeometryRegion {
                Name = "Clusters"
            };

            clusterRegion.Permutations.AddRange(
                Clusters.Select((c, i) => new GeometryPermutation
            {
                SourceIndex = i,
                Name        = Clusters.IndexOf(c).ToString("D3", CultureInfo.CurrentCulture),
                MeshIndex   = c.SectionIndex,
                MeshCount   = 1
            })
                );
            model.Regions.Add(clusterRegion);

            foreach (var instanceGroup in GeometryInstances.GroupBy(i => i.SectionIndex))
            {
                var section       = lightmapData.Sections[instanceGroup.Key];
                var sectionRegion = new GeometryRegion {
                    Name = Utils.CurrentCulture($"Instances {instanceGroup.Key:D3}")
                };
                sectionRegion.Permutations.AddRange(
                    instanceGroup.Select(i => new GeometryPermutation
                {
                    SourceIndex    = GeometryInstances.IndexOf(i),
                    Name           = i.Name,
                    Transform      = i.Transform,
                    TransformScale = i.TransformScale,
                    MeshIndex      = i.SectionIndex,
                    MeshCount      = 1
                })
                    );
                model.Regions.Add(sectionRegion);
            }

            model.Meshes.AddRange(Halo3Common.GetMeshes(cache, lightmapData.ResourcePointer, lightmapData.Sections, (s, m) =>
            {
                var index      = (short)lightmapData.Sections.IndexOf(s);
                m.BoundsIndex  = index >= BoundingBoxes.Count ? (short?)null : index;
                m.IsInstancing = index < BoundingBoxes.Count;
            }));

            return(model);
        }