Пример #1
0
        private void Activate()
        {
            this._active = true;

            this.HandCursor          = new Cursor(PdnResources.GetResourceStream("Cursors.PanToolCursor.cur"));
            this.HandCursorMouseDown = new Cursor(PdnResources.GetResourceStream("Cursors.PanToolCursorMouseDown.cur"));
            this.HandCursorInvalid   = new Cursor(PdnResources.GetResourceStream("Cursors.PanToolCursorInvalid.cur"));
            this.HandCursor          = Cursors.Hand;
            this.HandCursorMouseDown = Cursors.Arrow;
            this.HandCursorInvalid   = Cursors.Arrow;

            this._mouseDownCount = 0;
            this._savedTiles     = null;
            this._saveRegion     = null;

            this._scratchSurface = DocumentWorkspace.BorrowScratchSurface();
            //
            //                        Selection.Changing += new EventHandler(SelectionChangingHandler);
            //                        Selection.Changed += new EventHandler(SelectionChangedHandler);
            //                        HistoryStack.ExecutingHistoryMemento += new ExecutingHistoryMementoEventHandler(ExecutingHistoryMemento);
            //                        HistoryStack.ExecutedHistoryMemento += new ExecutedHistoryMementoEventHandler(ExecutedHistoryMemento);
            //                        HistoryStack.FinishedStepGroup += new EventHandler(FinishedHistoryStepGroup);

            this._trackingNub         = new MoveNubRenderer(this.RendererList);
            this._trackingNub.Visible = false;
            this._trackingNub.Size    = new SizeF(10, 10);
            this._trackingNub.Shape   = MoveNubShape.Compass;
            this.RendererList.Add(this._trackingNub, false);

            OnActivate();
        }
Пример #2
0
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);

            if (mouseDown)
            {
                return;
            }

            if (((e.Button & MouseButtons.Left) == MouseButtons.Left) ||
                ((e.Button & MouseButtons.Right) == MouseButtons.Right))
            {
                mouseDown   = true;
                mouseButton = e.Button;
                tracePoints = new List <Point>();
                bitmapLayer = (BitmapLayer)ActiveLayer;
                renderArgs  = new RenderArgs(bitmapLayer.Surface);

                if (clipRegion != null)
                {
                    clipRegion.Dispose();
                    clipRegion = null;
                }

                //                clipRegion = DocumentWorkspace. Selection.CreateRegion();
                //                renderArgs.Graphics.SetClip(clipRegion.GetRegionReadOnly(), CombineMode.Replace);
                OnMouseMove(e);
            }
        }
Пример #3
0
        protected override void OnDeactivate()
        {
            base.OnDeactivate();

            if (this.pencilToolCursor != null)
            {
                this.pencilToolCursor.Dispose();
                this.pencilToolCursor = null;
            }

            if (mouseDown)
            {
                Point lastTracePoint = (Point)tracePoints[tracePoints.Count - 1];
                OnMouseUp(new MouseEventArgs(mouseButton, 0, lastTracePoint.X, lastTracePoint.Y, 0));
            }

            this.savedRects  = null;
            this.tracePoints = null;
            this.bitmapLayer = null;

            if (this.renderArgs != null)
            {
                this.renderArgs.Dispose();
                this.renderArgs = null;
            }

            this.mouseDown = false;

            if (clipRegion != null)
            {
                clipRegion.Dispose();
                clipRegion = null;
            }
        }
Пример #4
0
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);

            if (mouseDown)
            {
                OnMouseMove(e);
                mouseDown = false;

                if (savedRects.Count > 0)
                {
                    Rectangle[]    savedScans   = this.savedRects.ToArray();
                    GeometryRegion saveMeRegion = Utility.RectanglesToRegion(savedScans);

                    //                    HistoryMemento ha = new BitmapHistoryMemento(Name, Image, DocumentWorkspace,
                    //                        ActiveLayerIndex, saveMeRegion, ScratchSurface);
                    //
                    //                    HistoryStack.PushNewMemento(ha);
                    saveMeRegion.Dispose();
                    this.savedRects.Clear();
                    ClearSavedMemory();
                }

                tracePoints = null;
            }
        }
Пример #5
0
        public static GeometryRegion RectanglesToRegion(Rectangle[] rects, int startIndex, int length)
        {
            GeometryRegion region;

            if (length == 0)
            {
                region = GeometryRegion.CreateEmpty();
            }
            else
            {
                using (var path = new GeometryGraphicsPath())
                {
                    path.FillMode = FillMode.Winding;
                    if (startIndex == 0 && length == rects.Length)
                    {
                        path.AddRectangles(rects);
                    }
                    else
                    {
                        for (int i = startIndex; i < startIndex + length; ++i)
                        {
                            path.AddRectangle(rects[i]);
                        }
                    }

                    region = new GeometryRegion(path);
                    path.Dispose();
                }
            }

            return(region);
        }
Пример #6
0
 public void Invert(GeometryRegion region)
 {
     foreach (Rectangle rect in region.GetRegionScansReadOnlyInt())
     {
         Invert(rect);
     }
 }
Пример #7
0
 public void UnsafeSet(GeometryRegion region, bool newValue)
 {
     foreach (Rectangle rect in region.GetRegionScansReadOnlyInt())
     {
         UnsafeSet(rect, newValue);
     }
 }
Пример #8
0
 /// <summary>
 /// Causes a portion of the layer surface to be invalidated.
 /// </summary>
 /// <param name="roi">The region of interest to be invalidated.</param>
 public void Invalidate(GeometryRegion roi)
 {
     foreach (Rectangle rect in roi.GetRegionScansReadOnlyInt())
     {
         Invalidate(rect);
     }
 }
Пример #9
0
 public void ClearSavedRegion()
 {
     if (this._saveRegion != null)
     {
         this._saveRegion.Dispose();
         this._saveRegion = null;
     }
 }
Пример #10
0
 public void RestoreRegion(GeometryRegion region)
 {
     if (region != null)
     {
         var activeLayer = (BitmapLayer)ActiveLayer;
         activeLayer.Surface.CopySurface(this.ScratchSurface, region);
         activeLayer.Invalidate(region);
     }
 }
Пример #11
0
 public void RestoreSavedRegion()
 {
     if (this._saveRegion != null)
     {
         var activeLayer = (BitmapLayer)ActiveLayer;
         activeLayer.Surface.CopySurface(this.ScratchSurface, this._saveRegion);
         activeLayer.Invalidate(this._saveRegion);
         this._saveRegion.Dispose();
         this._saveRegion = null;
     }
 }
Пример #12
0
        /// <summary>
        /// Causes the layer to render a given region of interest (roi) to the given destination surface.
        /// </summary>
        /// <param name="args">Contains information about which objects to use for rendering</param>
        /// <param name="roi">The region to be rendered.</param>
        public void Render(RenderArgs args, GeometryRegion roi)
        {
            Rectangle roiBounds = roi.GetBoundsInt();

            if (!IsInBounds(roiBounds))
            {
                throw new ArgumentOutOfRangeException("roi");
            }

            Rectangle[] rects = roi.GetRegionScansReadOnlyInt();
            RenderImpl(args, rects);
        }
Пример #13
0
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this._saveRegion != null)
                {
                    this._saveRegion.Dispose();
                    this._saveRegion = null;
                }


                OnDisposed();
            }
        }
Пример #14
0
        public IGeometryModel ReadGeometry(int lod)
        {
            if (lod < 0 || lod >= ((IRenderGeometry)this).LodCount)
            {
                throw new ArgumentOutOfRangeException(nameof(lod));
            }

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

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

            foreach (var region in Regions)
            {
                var gRegion = new GeometryRegion {
                    SourceIndex = Regions.IndexOf(region), Name = region.Name
                };
                gRegion.Permutations.AddRange(region.Permutations.Where(p => p.SectionIndex >= 0).Select(p =>
                                                                                                         new GeometryPermutation
                {
                    SourceIndex = region.Permutations.IndexOf(p),
                    Name        = p.Name,
                    MeshIndex   = p.SectionIndex,
                    MeshCount   = 1
                }));

                if (gRegion.Permutations.Any())
                {
                    model.Regions.Add(gRegion);
                }
            }

            Func <int, int, int> mapNodeFunc = null;

            if (Flags.HasFlag(ModelFlags.UseLocalNodes))
            {
                mapNodeFunc = (si, i) => NodeMaps[si].Indices[i];
            }

            model.Meshes.AddRange(Halo3Common.GetMeshes(cache, ResourcePointer, Sections, (s, m) => m.BoundsIndex = 0, mapNodeFunc));

            CreateInstanceMeshes(model);

            return(model);
        }
Пример #15
0
        public IGeometryModel ReadGeometry(int lod)
        {
            if (lod < 0 || lod >= ((IRenderGeometry)this).LodCount)
            {
                throw new ArgumentOutOfRangeException(nameof(lod));
            }

            using (var reader = cache.CreateReader(cache.DefaultAddressTranslator))
            {
                var model = new GeometryModel(item.FileName())
                {
                    CoordinateSystem = CoordinateSystem.Default
                };

                model.Nodes.AddRange(Nodes);
                model.MarkerGroups.AddRange(MarkerGroups);

                var shaderRefs = Shaders.Select(s => s.ShaderReference);
                model.Materials.AddRange(Halo1Common.GetMaterials(shaderRefs, reader));

                foreach (var region in Regions)
                {
                    var gRegion = new GeometryRegion {
                        SourceIndex = Regions.IndexOf(region), Name = region.Name
                    };
                    gRegion.Permutations.AddRange(region.Permutations.Select(p =>
                                                                             new GeometryPermutation
                    {
                        SourceIndex = region.Permutations.IndexOf(p),
                        Name        = p.Name,
                        MeshIndex   = p.LodIndex(lod),
                        MeshCount   = 1
                    }));

                    model.Regions.Add(gRegion);
                }

                if (cache.CacheType == CacheType.Halo1Xbox)
                {
                    model.Meshes.AddRange(ReadXboxMeshes(reader));
                }
                else
                {
                    model.Meshes.AddRange(ReadPCMeshes(reader));
                }

                return(model);
            }
        }
Пример #16
0
        private void Deactivate()
        {
            this._active = false;

            //                        Selection.Changing -= new EventHandler(SelectionChangingHandler);
            //                        Selection.Changed -= new EventHandler(SelectionChangedHandler);
            //
            //                        HistoryStack.ExecutingHistoryMemento -= new ExecutingHistoryMementoEventHandler(ExecutingHistoryMemento);
            //                        HistoryStack.ExecutedHistoryMemento -= new ExecutedHistoryMementoEventHandler(ExecutedHistoryMemento);
            //                        HistoryStack.FinishedStepGroup -= new EventHandler(FinishedHistoryStepGroup);

            OnDeactivate();

            this.RendererList.Remove(this._trackingNub);
            this._trackingNub.Dispose();
            this._trackingNub = null;

            DocumentWorkspace.ReturnScratchSurface(this._scratchSurface);
            this._scratchSurface = null;

            if (this._saveRegion != null)
            {
                this._saveRegion.Dispose();
                this._saveRegion = null;
            }

            this._savedTiles = null;

            if (this.HandCursor != null)
            {
                this.HandCursor.Dispose();
                this.HandCursor = null;
            }

            if (this.HandCursorMouseDown != null)
            {
                this.HandCursorMouseDown.Dispose();
                this.HandCursorMouseDown = null;
            }

            if (this.HandCursorInvalid != null)
            {
                this.HandCursorInvalid.Dispose();
                this.HandCursorInvalid = null;
            }
        }
Пример #17
0
        public IGeometryModel ReadGeometry(int lod)
        {
            if (lod < 0 || lod >= ((IRenderGeometry)this).LodCount)
            {
                throw new ArgumentOutOfRangeException(nameof(lod));
            }

            var model = new GeometryModel(Utils.GetFileName(item.FullPath))
            {
                CoordinateSystem = CoordinateSystem.Default
            };

            model.Nodes.AddRange(Nodes);
            model.MarkerGroups.AddRange(MarkerGroups);
            model.Bounds.AddRange(BoundingBoxes);
            model.Materials.AddRange(Halo5Common.GetMaterials(Materials));

            foreach (var region in Regions)
            {
                var gRegion = new GeometryRegion {
                    Name = region.Name
                };
                gRegion.Permutations.AddRange(region.Permutations.Where(p => p.SectionIndex >= 0).Select(p =>
                                                                                                         new GeometryPermutation
                {
                    Name      = p.Name,
                    MeshIndex = p.SectionIndex,
                    MeshCount = p.SectionCount
                }));

                if (gRegion.Permutations.Any())
                {
                    model.Regions.Add(gRegion);
                }
            }

            Func <int, int, int> mapNodeFunc = null;

            model.Meshes.AddRange(Halo5Common.GetMeshes(module, item, Sections, lod, s => 0, mapNodeFunc));

            CreateInstanceMeshes(model, lod);

            return(model);
        }
Пример #18
0
        protected override void OnPaint(PaintEventArgs e)
        {
            if (this._surface != null)
            {
                GeometryRegion clipRegion = null;
                Rectangle[]    rects      = this._realUpdateRects;

                if (rects == null)
                {
                    clipRegion = new GeometryRegion(e.Graphics.Clip, true);
                    clipRegion.Intersect(e.ClipRectangle);
                    rects = clipRegion.GetRegionScansReadOnlyInt();
                }

                if (this._justPaintWhite > 0)
                {
                    PtnGraphics.FillRectangles(e.Graphics, Color.White, rects);
                }
                else
                {
                    foreach (Rectangle rect in rects)
                    {
                        if (e.Graphics.IsVisible(rect))
                        {
                            var drawArg = new DrawArgs(e.Graphics, rect);
                            Draw(drawArg);
                        }
                    }
                }

                if (clipRegion != null)
                {
                    clipRegion.Dispose();
                }
            }

            if (this._justPaintWhite > 0)
            {
                --this._justPaintWhite;
            }

            base.OnPaint(e);
        }
Пример #19
0
        private void CreateInstanceMeshes(GeometryModel model)
        {
            if (InstancedGeometrySectionIndex < 0)
            {
                return;
            }

            /*
             * The render_model geometry instances have all their mesh data
             * in the same section and each instance has its own subset.
             * This function separates the subsets into separate sections
             * to make things easier for the model rendering and exporting
             */

            var gRegion = new GeometryRegion {
                Name = "Instances"
            };

            gRegion.Permutations.AddRange(GeometryInstances.Select(i =>
                                                                   new GeometryPermutation
            {
                SourceIndex    = GeometryInstances.IndexOf(i),
                Name           = i.Name,
                Transform      = i.Transform,
                TransformScale = i.TransformScale,
                MeshIndex      = InstancedGeometrySectionIndex + GeometryInstances.IndexOf(i),
                MeshCount      = 1
            }));

            model.Regions.Add(gRegion);

            var sourceMesh = model.Meshes[InstancedGeometrySectionIndex];

            model.Meshes.Remove(sourceMesh);

            var section = Sections[InstancedGeometrySectionIndex];

            for (int i = 0; i < GeometryInstances.Count; i++)
            {
                var subset = section.Subsets[i];
                var mesh   = new GeometryMesh
                {
                    IndexFormat   = sourceMesh.IndexFormat,
                    VertexWeights = VertexWeights.Rigid,
                    NodeIndex     = (byte)GeometryInstances[i].NodeIndex,
                    BoundsIndex   = 0
                };

                var strip = sourceMesh.Indicies.Skip(subset.IndexStart).Take(subset.IndexLength);

                var min = strip.Min();
                var max = strip.Max();
                var len = max - min + 1;

                mesh.Indicies = strip.Select(j => j - min).ToArray();
                mesh.Vertices = sourceMesh.Vertices.Skip(min).Take(len).ToArray();

                var submesh = section.Submeshes[subset.SubmeshIndex];
                mesh.Submeshes.Add(new GeometrySubmesh
                {
                    MaterialIndex = submesh.ShaderIndex,
                    IndexStart    = 0,
                    IndexLength   = mesh.Indicies.Length
                });

                model.Meshes.Add(mesh);
            }
        }
Пример #20
0
        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.Nodes.AddRange(Nodes);
            model.MarkerGroups.AddRange(MarkerGroups);
            model.Bounds.AddRange(BoundingBoxes);
            model.Materials.AddRange(Halo2.Halo2Common.GetMaterials(Shaders));

            foreach (var region in Regions)
            {
                var gRegion = new GeometryRegion {
                    SourceIndex = Regions.IndexOf(region), Name = region.Name
                };
                gRegion.Permutations.AddRange(region.Permutations.Select(p =>
                                                                         new GeometryPermutation
                {
                    SourceIndex = region.Permutations.IndexOf(p),
                    Name        = p.Name,
                    MeshIndex   = p.LodArray[lod],
                    MeshCount   = 1
                }));

                model.Regions.Add(gRegion);
            }

            foreach (var section in Sections)
            {
                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))
                    {
                        reader.ReadInt32(); //hklb
                        var sectionInfo = reader.ReadObject <MeshResourceDetailsBlock>();

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

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

                        var mesh = new GeometryMesh {
                            BoundsIndex = 0,
                        };

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

                        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();

                        var nodeMap = new byte[0];
                        if (nodeMapResource != null)
                        {
                            reader.Seek(baseAddress + nodeMapResource.Offset, SeekOrigin.Begin);
                            nodeMap = reader.ReadBytes(sectionInfo.NodeMapCount);
                        }

                        #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 Halo2.Vertex();

                            reader.Seek(baseAddress + vertexResource.Offset + i * vertexSize, SeekOrigin.Begin);
                            vert.Position = new UInt16N4((ushort)(reader.ReadInt16() - short.MinValue), (ushort)(reader.ReadInt16() - short.MinValue), (ushort)(reader.ReadInt16() - short.MinValue), 0);
                            ReadBlendData(reader, section, mesh, vert, nodeMap);

                            mesh.Vertices[i] = vert;
                        }

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

                            reader.Seek(baseAddress + uvResource.Offset + i * 4, SeekOrigin.Begin);
                            vert.TexCoords = new UInt16N2((ushort)(reader.ReadInt16() - short.MinValue), (ushort)(reader.ReadInt16() - short.MinValue));
                        }

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

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

                        model.Meshes.Add(mesh);
                    }
            }

            return(model);
        }
Пример #21
0
        public IGeometryModel ReadGeometry(int lod)
        {
            if (lod < 0 || lod >= ((IRenderGeometry)this).LodCount)
            {
                throw new ArgumentOutOfRangeException(nameof(lod));
            }

            using (var reader = cache.CreateReader(cache.DefaultAddressTranslator))
            {
                var model = new GeometryModel(item.FileName())
                {
                    CoordinateSystem = CoordinateSystem.Default
                };

                var shaderRefs = Lightmaps.SelectMany(m => m.Materials)
                                 .Where(m => m.ShaderReference.TagId >= 0)
                                 .GroupBy(m => m.ShaderReference.TagId)
                                 .Select(g => g.First().ShaderReference)
                                 .ToList();

                var shaderIds = shaderRefs.Select(r => r.TagId).ToList();

                model.Materials.AddRange(Halo1Common.GetMaterials(shaderRefs, reader));

                reader.Seek(SurfacePointer.Address, SeekOrigin.Begin);
                var indices = reader.ReadEnumerable <ushort>(SurfaceCount * 3).ToArray();

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

                int sectionIndex = 0;
                foreach (var section in Lightmaps)
                {
                    if (section.Materials.Count == 0)
                    {
                        continue;
                    }

                    var localIndices = new List <int>();
                    var vertices     = new List <WorldVertex>();
                    var submeshes    = new List <IGeometrySubmesh>();

                    var gPermutation = new GeometryPermutation
                    {
                        SourceIndex = Lightmaps.IndexOf(section),
                        Name        = sectionIndex.ToString("D3", CultureInfo.CurrentCulture),
                        MeshIndex   = sectionIndex,
                        MeshCount   = 1
                    };

                    foreach (var submesh in section.Materials)
                    {
                        reader.Seek(submesh.VertexPointer.Address, SeekOrigin.Begin);

                        submeshes.Add(new GeometrySubmesh
                        {
                            MaterialIndex = (short)shaderIds.IndexOf(submesh.ShaderReference.TagId),
                            IndexStart    = localIndices.Count,
                            IndexLength   = submesh.SurfaceCount * 3
                        });

                        localIndices.AddRange(
                            indices.Skip(submesh.SurfaceIndex * 3)
                            .Take(submesh.SurfaceCount * 3)
                            .Select(i => i + vertices.Count)
                            );

                        var vertsTemp = reader.ReadEnumerable <WorldVertex>(submesh.VertexCount).ToList();
                        vertices.AddRange(vertsTemp);
                    }

                    gRegion.Permutations.Add(gPermutation);

                    model.Meshes.Add(new GeometryMesh
                    {
                        IndexFormat   = IndexFormat.TriangleList,
                        VertexWeights = VertexWeights.None,
                        Indicies      = localIndices.ToArray(),
                        Vertices      = vertices.ToArray(),
                        Submeshes     = submeshes
                    });

                    sectionIndex++;
                }

                model.Regions.Add(gRegion);

                return(model);
            }
        }
Пример #22
0
 /// <summary>
 /// Allows you to find the bounding box for a Region object without requiring
 /// the presence of a Graphics object.
 /// (Region.GetBounds takes a Graphics instance as its only parameter.)
 /// </summary>
 /// <param name="region">The region you want to find a bounding box for.</param>
 /// <returns>A RectangleF structure that surrounds the Region.</returns>
 public static Rectangle GetRegionBounds(GeometryRegion region)
 {
     Rectangle[] rects = region.GetRegionScansReadOnlyInt();
     return(GetRegionBounds(rects, 0, rects.Length));
 }
Пример #23
0
        public void SaveRegion(GeometryRegion saveMeRegion, Rectangle saveMeBounds)
        {
            var activeLayer = (BitmapLayer)ActiveLayer;

            if (_savedTiles == null)
            {
                _savedTiles = new BitVector2D(
                    (activeLayer.Width + SaveTileGranularity - 1) / SaveTileGranularity,
                    (activeLayer.Height + SaveTileGranularity - 1) / SaveTileGranularity);

                _savedTiles.Clear(false);
            }

            Rectangle regionBounds;

            if (saveMeRegion == null)
            {
                regionBounds = saveMeBounds;
            }
            else
            {
                regionBounds = saveMeRegion.GetBoundsInt();
            }

            Rectangle bounds = Rectangle.Union(regionBounds, saveMeBounds);

            bounds.Intersect(activeLayer.Bounds);

            int leftTile   = bounds.Left / SaveTileGranularity;
            int topTile    = bounds.Top / SaveTileGranularity;
            int rightTile  = (bounds.Right - 1) / SaveTileGranularity;
            int bottomTile = (bounds.Bottom - 1) / SaveTileGranularity;

            for (int tileY = topTile; tileY <= bottomTile; ++tileY)
            {
                Rectangle rowAccumBounds = Rectangle.Empty;

                for (int tileX = leftTile; tileX <= rightTile; ++tileX)
                {
                    if (!_savedTiles.Get(tileX, tileY))
                    {
                        Rectangle tileBounds = new Rectangle(tileX * SaveTileGranularity, tileY * SaveTileGranularity,
                                                             SaveTileGranularity, SaveTileGranularity);

                        tileBounds.Intersect(activeLayer.Bounds);

                        if (rowAccumBounds == Rectangle.Empty)
                        {
                            rowAccumBounds = tileBounds;
                        }
                        else
                        {
                            rowAccumBounds = Rectangle.Union(rowAccumBounds, tileBounds);
                        }

                        _savedTiles.Set(tileX, tileY, true);
                    }
                    else
                    {
                        if (rowAccumBounds != Rectangle.Empty)
                        {
                            using (Surface dst = ScratchSurface.CreateWindow(rowAccumBounds),
                                   src = activeLayer.Surface.CreateWindow(rowAccumBounds))
                            {
                                dst.CopySurface(src);
                            }

                            rowAccumBounds = Rectangle.Empty;
                        }
                    }
                }

                if (rowAccumBounds != Rectangle.Empty)
                {
                    using (Surface dst = ScratchSurface.CreateWindow(rowAccumBounds),
                           src = activeLayer.Surface.CreateWindow(rowAccumBounds))
                    {
                        dst.CopySurface(src);
                    }

                    rowAccumBounds = Rectangle.Empty;
                }
            }

            if (this._saveRegion != null)
            {
                this._saveRegion.Dispose();
                this._saveRegion = null;
            }

            if (saveMeRegion != null)
            {
                this._saveRegion = saveMeRegion.Clone();
            }
        }
Пример #24
0
        private void DrawShadow(Graphics g, Rectangle clipRect)
        {
            if (this.occludingControl != null)
            {
                // Draw the outline rectangle
                var outlineRect = new Rectangle(new Point(0, 0), this.occludingControl.Size);

                outlineRect         = occludingControl.RectangleToScreen(outlineRect);
                outlineRect         = RectangleToClient(outlineRect);
                outlineRect.X      -= 1;
                outlineRect.Y      -= 1;
                outlineRect.Width  += 2;
                outlineRect.Height += 2;

                g.DrawLines(
                    Pens.Black,
                    new Point[]
                {
                    new Point(outlineRect.Left, outlineRect.Top),
                    new Point(outlineRect.Right, outlineRect.Top),
                    new Point(outlineRect.Right, outlineRect.Bottom),
                    new Point(outlineRect.Left, outlineRect.Bottom),
                    new Point(outlineRect.Left, outlineRect.Top)
                });

                using (var backRegion = new GeometryRegion(clipRect))
                {
                    var occludingRect = new Rectangle(0, 0, this.occludingControl.Width, this.occludingControl.Height);
                    occludingRect = this.occludingControl.RectangleToScreen(occludingRect);
                    occludingRect = RectangleToClient(occludingRect);
                    backRegion.Exclude(occludingRect);
                    backRegion.Exclude(outlineRect);

                    using (Brush backBrush = new SolidBrush(this.BackColor))
                    {
                        g.FillRegion(backBrush, backRegion.GetRegionReadOnly());
                    }
                }

                Rectangle edgeRect = new Rectangle(0, 0, this._roundedEdgeUl.Width, this._roundedEdgeUr.Height);

                Rectangle ulEdgeRect = new Rectangle(outlineRect.Left - 3, outlineRect.Top - 3, this._roundedEdgeUl.Width, this._roundedEdgeUl.Height);
                Rectangle urEdgeRect = new Rectangle(outlineRect.Right - 3, outlineRect.Top - 3, this._roundedEdgeUr.Width, this._roundedEdgeUr.Height);
                Rectangle llEdgeRect = new Rectangle(outlineRect.Left - 3, outlineRect.Bottom - 3, this._roundedEdgeLl.Width, this._roundedEdgeLl.Height);
                Rectangle lrEdgeRect = new Rectangle(outlineRect.Right - 3, outlineRect.Bottom - 3, this._roundedEdgeLr.Width, this._roundedEdgeLr.Height);

                g.DrawImage(this._roundedEdgeUl, ulEdgeRect, edgeRect, GraphicsUnit.Pixel);
                g.DrawImage(this._roundedEdgeUr, urEdgeRect, edgeRect, GraphicsUnit.Pixel);
                g.DrawImage(this._roundedEdgeLl, llEdgeRect, edgeRect, GraphicsUnit.Pixel);
                g.DrawImage(this._roundedEdgeLr, lrEdgeRect, edgeRect, GraphicsUnit.Pixel);

                Color c1 = Color.FromArgb(95, Color.Black);
                Color c2 = Color.FromArgb(47, Color.Black);
                Color c3 = Color.FromArgb(15, Color.Black);

                Pen p1 = new Pen(c1);
                Pen p2 = new Pen(c2);
                Pen p3 = new Pen(c3);

                // Draw top soft edge
                g.DrawLine(p1, ulEdgeRect.Right, outlineRect.Top - 1, urEdgeRect.Left - 1, outlineRect.Top - 1);
                g.DrawLine(p2, ulEdgeRect.Right, outlineRect.Top - 2, urEdgeRect.Left - 1, outlineRect.Top - 2);
                g.DrawLine(p3, ulEdgeRect.Right, outlineRect.Top - 3, urEdgeRect.Left - 1, outlineRect.Top - 3);

                // Draw bottom soft edge
                g.DrawLine(p1, llEdgeRect.Right, outlineRect.Bottom + 0, lrEdgeRect.Left - 1, outlineRect.Bottom + 0);
                g.DrawLine(p2, llEdgeRect.Right, outlineRect.Bottom + 1, lrEdgeRect.Left - 1, outlineRect.Bottom + 1);
                g.DrawLine(p3, llEdgeRect.Right, outlineRect.Bottom + 2, lrEdgeRect.Left - 1, outlineRect.Bottom + 2);

                // Draw left soft edge
                g.DrawLine(p1, outlineRect.Left - 1, ulEdgeRect.Bottom, outlineRect.Left - 1, llEdgeRect.Top - 1);
                g.DrawLine(p2, outlineRect.Left - 2, ulEdgeRect.Bottom, outlineRect.Left - 2, llEdgeRect.Top - 1);
                g.DrawLine(p3, outlineRect.Left - 3, ulEdgeRect.Bottom, outlineRect.Left - 3, llEdgeRect.Top - 1);

                // Draw right soft edge
                g.DrawLine(p1, outlineRect.Right + 0, urEdgeRect.Bottom, outlineRect.Right + 0, lrEdgeRect.Top - 1);
                g.DrawLine(p2, outlineRect.Right + 1, urEdgeRect.Bottom, outlineRect.Right + 1, lrEdgeRect.Top - 1);
                g.DrawLine(p3, outlineRect.Right + 2, urEdgeRect.Bottom, outlineRect.Right + 2, lrEdgeRect.Top - 1);

                p1.Dispose();
                p1 = null;

                p2.Dispose();
                p2 = null;

                p3.Dispose();
                p3 = null;
            }

            if (this.betaTagString != null)
            {
                Color        betaTagColor = Color.FromArgb(this.betaTagOpacity, SystemColors.WindowText);
                Brush        betaTagBrush = new SolidBrush(betaTagColor);
                StringFormat sf           = (StringFormat)StringFormat.GenericTypographic.Clone();

                sf.Alignment     = StringAlignment.Center;
                sf.LineAlignment = StringAlignment.Near;

                g.DrawString(
                    this.betaTagString,
                    this.Font,
                    betaTagBrush,
                    ClientRectangle.Width / 2,
                    1,
                    sf);

                sf.Dispose();
                sf = null;

                betaTagBrush.Dispose();
                betaTagBrush = null;
            }
        }
        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);
        }
Пример #27
0
 public void Apply(Surface surface, GeometryRegion roi)
 {
     Apply(surface, roi.GetRegionScansReadOnlyInt());
 }
Пример #28
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);
        }