Example #1
0
        public Cell(Macro.Cell macro, MicroMap map)
        {
            Macro          = macro;
            _map           = map;
            BlockPositions = Rasterization.ConvexToBlocks(macro.Contains, macro.Bounds);

            Bounds = (Bounds2i)macro.Bounds;

            var vertices = new List <Vector2i>(BlockPositions);

            foreach (var blockPosition in BlockPositions)
            {
                if (!vertices.Contains(blockPosition + Vector2i.Forward))
                {
                    vertices.Add(blockPosition + Vector2i.Forward);
                }
                if (!vertices.Contains(blockPosition + Vector2i.Right))
                {
                    vertices.Add(blockPosition + Vector2i.Right);
                }
                if (!vertices.Contains(blockPosition + Vector2i.One))
                {
                    vertices.Add(blockPosition + Vector2i.One);
                }
            }

            VertexPositions = vertices.ToArray();
        }
Example #2
0
 /// <summary>
 /// Paints a contiguous selection using a four-way flood fill, overwritting only those
 /// positions whose parquets match those initially found at the starting position.
 /// </summary>
 /// <param name="in_start">Where to start the fill.</param>
 public void PaintFloodFill(Point in_start)
 {
     PaintAtLocations(Rasterization.PlotFloodFill(in_start,
                                                  _currentRegion.GetDefinitionAtPosition(in_start),
                                                  _currentRegion.IsValidPosition,
                                                  Matches));
 }
        public void TestCellRasterization()
        {
            var v1 = new Vector2(1.2f, 1.5f);
            var v2 = new Vector2(0.55f, -1.55f);
            var v3 = new Vector2(-2.4f, -1.1f);
            var v4 = new Vector2(-0.5f, 2.3f);

            var h1 = new HalfPlane(v1, v2, Vector2.Zero);
            var h2 = new HalfPlane(v2, v3, Vector2.Zero);
            var h3 = new HalfPlane(v3, v4, Vector2.Zero);
            var h4 = new HalfPlane(v4, v1, Vector2.Zero);

            var isContains = new Predicate <Vector2>(p => HalfPlane.ContainsInConvex(p, new [] { h1, h2, h3, h4 }));

            var boundingBox   = new Box2(-2.4f, 2.3f, 1.2f, -1.55f);
            var result        = Rasterization.ConvexToBlocks(isContains, boundingBox);
            var correctAnswer = new[] { new Vector2i(0, 1), new Vector2i(0, 0), new Vector2i(0, -1), new Vector2i(0, -2),
                                        new Vector2i(-1, 1), new Vector2i(-1, 0), new Vector2i(-1, -1),
                                        new Vector2i(-2, 0), new Vector2i(-2, -1) };

            Assert.That(result, Is.EquivalentTo(correctAnswer));

            //Draw polygon
            //UnityEngine.Debug.DrawLine(v1, v2, Color.blue, 10);
            //UnityEngine.Debug.DrawLine(v2, v3, Color.blue, 10);
            //UnityEngine.Debug.DrawLine(v3, v4, Color.blue, 10);
            //UnityEngine.Debug.DrawLine(v4, v1, Color.blue, 10);

            //Draw bbox
            //DrawRectangle.ForDebug();
        }
Example #4
0
        public void PlotEmptyRectangleCompletesSquareOutlineTest()
        {
            const int upperLeftBound   = 1;
            const int lowerRightBound  = 9;
            var       upperLeftCorner  = new Vector2Int(upperLeftBound, upperLeftBound);
            var       lowerRightCorner = new Vector2Int(lowerRightBound, lowerRightBound);
            var       vectors          = Rasterization.PlotEmptyRectangle(upperLeftCorner, lowerRightCorner, a => { return(true); });

            for (var x = upperLeftBound; x <= lowerRightBound; x++)
            {
                var position = new Vector2Int(x, upperLeftBound);
                Assert.True(vectors.Remove(position));
                position = new Vector2Int(x, lowerRightBound);
                Assert.True(vectors.Remove(position));
            }
            for (var y = upperLeftBound + 1; y < lowerRightBound; y++)
            {
                var position = new Vector2Int(upperLeftBound, y);
                Assert.True(vectors.Remove(position));
                position = new Vector2Int(lowerRightBound, y);
                Assert.True(vectors.Remove(position));
            }

            Assert.Empty(vectors);
        }
Example #5
0
 /// <summary>
 /// Paints a contiguous selection using a four-way flood fill, overwritting only those
 /// positions whose parquets match those initially found at the starting position.
 /// </summary>
 /// <param name="in_start">Where to start the fill.</param>
 public void PaintFloodFill(Vector2Int in_start)
 {
     PaintAtLocations(Rasterization.PlotFloodFill(in_start,
                                                  _currentRegion.GetAllParquetsAtPosition(in_start),
                                                  _currentRegion.IsValidPosition,
                                                  Matches));
 }
Example #6
0
 public void DrawMesh(Rasterization rasterizer, VertexProcessor processor, Light l)
 {
     //Представление вершины в пространстве.
     for (int i = 0; i < indexes.Count; i += 3)
     {
         rasterizer.Triangle(processor.tr(vertexes[indexes[i]].position), processor.tr(vertexes[indexes[i + 1]].position),
                             processor.tr(vertexes[indexes[i + 2]].position), vertexes[indexes[i]], vertexes[indexes[i + 1]], vertexes[indexes[i + 2]], l, processor);
     }
 }
        public void TestLineRasterization()
        {
            var from      = (Vector2i) new Vector2(-3.52f, -4.14f);
            var to        = (Vector2i) new Vector2(-2.32f, -2.48f);
            var rasterize = Rasterization.lineNoDiag(from.X, from.Z, to.X, to.Z);

            //var rasterize = Rasterization.DDA((Vector2i)new Vector2(-3.52f, -4.14f), (Vector2i)new Vector2(-2.32f, -2.48f), true);
            //var rasterize = Rasterization.BresenhamInt((Vector2i)new Vector2(-3.52f, -4.14f), (Vector2i)new Vector2(-2.32f, -2.48f));
            Assert.That(rasterize, Is.EquivalentTo(new[] { new Vector2i(-4, -5), new Vector2i(-4, -4), new Vector2i(-3, -4), new Vector2i(-3, -3) }));
        }
Example #8
0
        public void PlotFloodFillTest()
        {
            const int location  = 1;
            const int target    = 0;
            var       fillLayer = new[, ]
            {
                { 1, 1, 1, 1, 1, 1 },
                { 1, 0, 0, 0, 0, 1 },
                { 1, 0, 2, 0, 0, 1 },
                { 1, 0, 0, 0, 0, 1 },
                { 1, 0, 0, 0, 0, 1 },
                { 1, 1, 1, 1, 1, 1 }
            };
            var start = new Vector2Int(location, location);

            bool IsVaild(Vector2Int in_position)
            {
                return(in_position.X >= 0 &&
                       in_position.X <= fillLayer.Length &&
                       in_position.Y >= 0 &&
                       in_position.Y <= fillLayer.Length);
            }

            bool Matches <T>(Vector2Int in_position, T in_matchAgainst) where T : struct
            {
                var matchAgainst = Convert.ToInt32(in_matchAgainst);

                return(fillLayer[in_position.Y, in_position.X] == matchAgainst);
            }

            int CountAllTargets(int[,] in_array)
            {
                var count = 0;

                foreach (var item in in_array)
                {
                    if (item == target)
                    {
                        count++;
                    }
                }

                return(count);
            }

            var vectors = Rasterization.PlotFloodFill(start, target, IsVaild, Matches);

            Assert.Equal(CountAllTargets(fillLayer), vectors.Count);
            foreach (var vector in vectors)
            {
                Assert.Equal(target, fillLayer[vector.Y, vector.X]);
            }
        }
Example #9
0
        public void DrawMesh(Rasterization rasterizer, VertexProcessor processor, Light l)
        {
            System.Console.WriteLine("Ilosc indeksow: " + indexes.Count);

            for (int i = 0; i < indexes.Count; i += 3)
            {
                rasterizer.Triangle(processor.tr(vertexes[indexes[i]].position), processor.tr(vertexes[indexes[i + 1]].position), processor.tr(vertexes[indexes[i + 2]].position), vertexes[indexes[i]], vertexes[indexes[i + 1]], vertexes[indexes[i + 2]], l, processor);
                stream.WriteLine("Indeks: " + indexes[i] + " " + indexes[i + 1] + " " + indexes[i + 2]);
                stream.WriteLine("Wierzchołki: " + vertexes[indexes[i]].position.ToString() + " | " + vertexes[indexes[i + 1]].position.ToString() + " | " + vertexes[indexes[i + 2]].position.ToString());
            }
            stream.Close();
        }
 public IEnumerable <Vector2i> GetBlocks()
 {
     for (int i = 1; i < Cell.Vertices.Length - 1; i++)
     {
         foreach (var pos in Rasterization.Triangle(Cell.Vertices[0], Cell.Vertices[i], Cell.Vertices[i + 1]))
         {
             if (Bounds.Contains(pos))
             {
                 yield return(pos);
             }
         }
     }
 }
        void OnDrawGizmos()
        {
            if (_handle1 && _handle2)
            {
                Gizmos.color = Color.white;
                Gizmos.DrawLine(_handle1.transform.position, _handle2.transform.position);

                //var p1 = new Vector2i(_handle1.transform.position.x, _handle1.transform.position.z);
                //var p2 = new Vector2i(_handle2.transform.position.x, _handle2.transform.position.z);
                var p1  = new Vector2(_handle1.transform.position.x, _handle1.transform.position.z);
                var p2  = new Vector2(_handle2.transform.position.x, _handle2.transform.position.z);
                var pi1 = (Vector2i)p1;
                var pi2 = (Vector2i)p2;

                //var points = Rasterization.DDA(p1, p2, true).ToArray();     Debug.Log("Rasterization.DDA conservative");
                var pointsDDA = Rasterization.DDA(p1, p2, false).ToArray();
                //var points = Rasterization.lineNoDiag(pi1.X, pi1.Z, pi2.X, pi2.Z).ToArray();  Debug.Log("Rasterization.lineNoDiag");
                var pointsBresInt   = Rasterization.BresenhamInt(pi1, pi2).ToArray();
                var pointsBresFloat = Rasterization.BresenhamFloat(p1.X, p1.Y, p2.X, p2.Y).ToArray();

                Assert.IsTrue(pointsDDA.Length == pointsDDA.Distinct().Count());
                Assert.IsTrue(pointsBresInt.Length == pointsBresInt.Distinct().Count());
                Assert.IsTrue(pointsBresFloat.Length == pointsBresFloat.Distinct().Count());

                if (counter % 20 < 10)
                {
                    foreach (var p in pointsDDA)
                    {
                        DrawRectangle.ForGizmo(new Bounds2i(p, 1, 1), Color.white);
                    }
                }

                /*
                 * else if (counter % 21 < 14)
                 *  foreach (var p in pointsBresInt)
                 *  DrawRectangle.ForGizmo(new Bounds2i(p, 1, 1), Color.red);
                 */

                else //if (counter % 21 >= 14)
                {
                    foreach (var p in pointsBresFloat)
                    {
                        DrawRectangle.ForGizmo(new Bounds2i(p, 1, 1), Color.green);
                    }
                }

                counter++;
            }
        }
Example #12
0
        public void PlotLineCompletesStraightHorizontalLineTest()
        {
            const int leftBound  = 1;
            const int rightBound = 10;
            var       leftEnd    = new Vector2Int(leftBound, 0);
            var       rightEnd   = new Vector2Int(rightBound, 0);
            var       vectors    = Rasterization.PlotLine(leftEnd, rightEnd, a => true);

            for (var x = leftBound; x <= rightBound; x++)
            {
                var position = new Vector2Int(x, 0);
                Assert.True(vectors.Remove(position));
            }

            Assert.Empty(vectors);
        }
Example #13
0
        public void PlotLineCompletesStraightVerticalLineTest()
        {
            const int upperBound = 1;
            const int lowerBound = 10;
            var       top        = new Vector2Int(0, upperBound);
            var       bottom     = new Vector2Int(0, lowerBound);
            var       vectors    = Rasterization.PlotLine(top, bottom, a => { return(true); });

            for (var y = upperBound; y <= lowerBound; y++)
            {
                var position = new Vector2Int(0, y);
                Assert.True(vectors.Remove(position));
            }

            Assert.Empty(vectors);
        }
        private IEnumerator FillTriangles()
        {
            for (int i = 0; i < indices.Length; i += 3)
            {
                var brush = crossBrushes[i / 3];
                var color = brush.Color;

                foreach (var pixel in Rasterization.FillTriangle(
                             vertices[indices[i]], vertices[indices[i + 1]], vertices[indices[i + 2]],
                             color, buffer, depth, 16, 0, 8, 0, 16))
                {
                    DrawCross(pixel.Item1, pixel.Item2, brush);
                    yield return(null);
                }
            }
        }
Example #15
0
        public void PlotLineCompletesDiagonalLineWithUnitSlopeTest()
        {
            const int upperLeftBound  = 1;
            const int lowerRightBound = 10;
            var       upperLeftEnd    = new Vector2Int(upperLeftBound, upperLeftBound);
            var       lowerRightEnd   = new Vector2Int(lowerRightBound, lowerRightBound);
            var       vectors         = Rasterization.PlotLine(upperLeftEnd, lowerRightEnd, a => { return(true); });

            for (var i = upperLeftBound; i <= lowerRightBound; i++)
            {
                var position = new Vector2Int(i, i);
                Assert.True(vectors.Remove(position));
            }

            Assert.Empty(vectors);
        }
Example #16
0
        public void PlotCircleCompletesMinimalOutlineTest()
        {
            const int location      = 3;
            const int radius        = 1;
            var       center        = new Vector2Int(location, location);
            var       aboveCenter   = new Vector2Int(location, location - 1);
            var       leftOfCenter  = new Vector2Int(location - 1, location);
            var       rightOfCenter = new Vector2Int(location + 1, location);
            var       belowCenter   = new Vector2Int(location, location + 1);

            var vectors = Rasterization.PlotCircle(center, radius, false, a => { return(true); });

            Assert.False(vectors.Remove(center));
            Assert.True(vectors.Remove(aboveCenter));
            Assert.True(vectors.Remove(leftOfCenter));
            Assert.True(vectors.Remove(rightOfCenter));
            Assert.True(vectors.Remove(belowCenter));
            Assert.Empty(vectors);
        }
        public IEnumerable <Vector2i> GetBlocks2()                   //Todo consider move to Rasterization class
        {
            var edges = new List <Vector2i>();

            foreach (var edge in Cell.Edges)
            {
                edges.AddRange(Rasterization.DDA(edge.Vertex1, edge.Vertex2, false));
            }

            var bounds = Bounds;

            edges = edges.Where(e => bounds.Contains(e)).Distinct().ToList();
            edges.Sort();

            for (int i = 0; i < edges.Count;)
            {
                if (i == edges.Count - 1)
                {
                    yield return(edges.Last());

                    yield break;
                }

                var z1 = edges[i].Z;
                var j  = i;
                while (j < edges.Count - 1 && edges[j + 1].Z == z1)
                {
                    j++;
                }

                for (var x = edges[i].X; x <= edges[j].X; x++)
                {
                    yield return(new Vector2i(x, z1));
                }

                i = j + 1;
            }

            //foreach (var vector2I in edges)
            //{
            //    yield return vector2I;
            //}
        }
Example #18
0
        public Vector3?GetRayMapIntersection(Ray ray)
        {
            var from   = new Vector2(ray.origin.x, ray.origin.z);
            var to     = new Vector2(ray.GetPoint(1000).x, ray.GetPoint(1000).z);
            var blocks = Rasterization.DDA(from, to, true);

            foreach (var blockPos in blocks)
            {
                if (_settings.LandBounds.Contains(blockPos))
                {
                    var   chunkPosition = Chunk.GetPosition(blockPos);
                    Chunk chunk;
                    if (Map.TryGetValue(chunkPosition, out chunk))
                    {
                        var localPos = Chunk.GetLocalPosition(blockPos);
                        var tr1      = new Vector3(blockPos.X, chunk.HeightMap[localPos.X, localPos.Z], blockPos.Z);
                        var tr2      = new Vector3(blockPos.X + 1, chunk.HeightMap[localPos.X + 1, localPos.Z], blockPos.Z);
                        var tr3      = new Vector3(blockPos.X, chunk.HeightMap[localPos.X, localPos.Z + 1], blockPos.Z + 1);
                        var tr4      = new Vector3(blockPos.X + 1, chunk.HeightMap[localPos.X + 1, localPos.Z + 1], blockPos.Z + 1);

                        Vector3 i;
                        var     ir = Intersections.LineTriangleIntersection(ray, tr1, tr2, tr3, out i);
                        if (ir == 1)
                        {
                            return(i);
                        }
                        else
                        {
                            ir = Intersections.LineTriangleIntersection(ray, tr2, tr3, tr4, out i);
                            if (ir == 1)
                            {
                                return(i);
                            }
                        }
                    }
                }
            }

            return(null);
        }
Example #19
0
 /// <summary>
 /// Paints currently selected parquets in a circle of the given radius around the given position.
 /// </summary>
 /// <param name="in_center">The circle's center.</param>
 /// <param name="in_radius">The circle's radius.</param>
 /// <param name="in_filled">
 /// If set to <c>true</c>, the circle will be filled in; otherwise,
 /// only the outline will be painted.
 /// </param>
 public void PaintCircle(Vector2Int in_center, int in_radius, bool in_filled)
 {
     PaintAtLocations(Rasterization.PlotCircle(in_center, in_radius, in_filled, _currentRegion.IsValidPosition));
 }
Example #20
0
 public void DrawMesh(Rasterization rasterizer, VertexProcessor processor)
 {
     throw new NotImplementedException();
 }
        public override void Save(SaveContext saveContext)
        {
            base.Save(saveContext);

            var utility = saveContext.Utility;

            utility.Write(MaterialFlags);

            utility.Write((uint)TextureCoordinatesConfig);
            utility.Write((uint)TranslucencyKind);

            // NOTE: These are inline, not pointered to
            MaterialColor.Save(saveContext);
            Rasterization.Save(saveContext);
            FragmentOperation.Save(saveContext);

            // Texture coordinates
            utility.Write(UsedTextureCoordinates);

            for (var i = 0; i < TextureCoords.Length; i++)
            {
                var tc = TextureCoords[i];

                utility.Write(tc.SourceCoordIndex);
                utility.Write((uint)tc.MappingType);
                utility.Write(tc.ReferenceCameraIndex);
                utility.Write((uint)tc.TransformType);
                tc.Scale.Write(utility);
                utility.Write(tc.Rotation);
                tc.Translation.Write(utility);
                utility.Write(tc.Flags);
                tc.Transform.Write(utility);
            }

            // Texture mappers
            for (var i = 0; i < TextureMappers.Length; i++)
            {
                saveContext.WritePointerPlaceholder(TextureMappers[i]);
            }

            saveContext.WritePointerPlaceholder(ShaderReference);

            saveContext.WritePointerPlaceholder(FragmentShader);

            utility.Write(ShaderProgramDescIndex);

            // NOT SUPPORTED
            utility.Write(ShaderParametersCount);
            utility.Write(ShaderParametersPointerTableOffset);
            if (ShaderParametersCount != 0 || ShaderParametersPointerTableOffset != 0)
            {
                throw new NotImplementedException($"ModelMaterial Save: Shader Parameters UNSUPPORTED");
            }


            utility.Write(LightSetIndex); // Reference??
            utility.Write(FogIndex);      // Reference??

            // NOTE -- See SPICA GfxMaterial.cs for computations involving these hash functions.
            // I ASSUME if I never change any values in the material these never need recomputed.
            // Let's try to get by without needing this support right now...
            utility.Write(MaterialFlagsHash);
            utility.Write(ShaderParamsHash);
            utility.Write(TextureCoordsHash);
            utility.Write(TextureSamplersHash);
            utility.Write(TextureMappersHash);
            utility.Write(MaterialColorsHash);
            utility.Write(RasterizationHash);
            utility.Write(FragLightHash);
            utility.Write(FragLightLUTHash);
            utility.Write(FragLightLUTSampHash);
            utility.Write(TextureEnvironmentHash);
            utility.Write(AlphaTestHash);
            utility.Write(FragOpHash);
            utility.Write(UniqueId);

            /////////////////////////////
            // Begin saving dependent data

            TextureMappers.SaveList(saveContext);
            saveContext.SaveAndMarkReference(ShaderReference);
            saveContext.SaveAndMarkReference(FragmentShader);
        }
        void OnDrawGizmos()
        {
            if (_h1 && _h2 && _h3 && _h4)
            {
                var center = (_h1.position + _h2.position + _h3.position + _h4.position) / 4;

                var h1 = new HalfPlane((Vector2)_h1.position, (Vector2)_h2.position, (Vector2)center);
                var h2 = new HalfPlane((Vector2)_h2.position, (Vector2)_h3.position, (Vector2)center);
                var h3 = new HalfPlane((Vector2)_h3.position, (Vector2)_h4.position, (Vector2)center);
                var h4 = new HalfPlane((Vector2)_h4.position, (Vector2)_h1.position, (Vector2)center);

                var containsCallCounter = 0;

                var isContains = new Predicate <Vector2>(delegate(Vector2 p)
                {
                    containsCallCounter++;
                    return(HalfPlane.ContainsInConvex(p, new [] { h1, h2, h3, h4 }));
                });
                var bounds = new Box2(
                    Mathf.Min(_h1.position.x, _h2.position.x, _h3.position.x, _h4.position.x),
                    Mathf.Max(_h1.position.z, _h2.position.z, _h3.position.z, _h4.position.z),
                    Mathf.Max(_h1.position.x, _h2.position.x, _h3.position.x, _h4.position.x),
                    Mathf.Min(_h1.position.z, _h2.position.z, _h3.position.z, _h4.position.z));

                //Draw test polygon
                Gizmos.color = Color.white;
                Gizmos.DrawLine(_h1.position, _h2.position);
                Gizmos.DrawLine(_h2.position, _h3.position);
                Gizmos.DrawLine(_h3.position, _h4.position);
                Gizmos.DrawLine(_h4.position, _h1.position);

                //Draw "world" bounds
                DrawRectangle.ForGizmo(bounds, Color.gray);

                if (Workmode == Mode.Blocks)
                {
                    //Draw block bounds
                    var blockBounds = (Bounds2i)bounds;

                    //Draw block centers inside bounds
                    foreach (var blockBound in blockBounds)
                    {
                        var blockCenter = BlockInfo.GetWorldCenter(blockBound);
                        DebugExtension.DrawPoint((Vector3)blockCenter, Color.white / 2, 0.1f);
                    }

                    var blocks = Rasterization.ConvexToBlocks(isContains, bounds);
                    Assert.IsTrue(blocks.Length == blocks.Distinct().Count());

                    //Draw rasterized blocks
                    foreach (var p in blocks)
                    {
                        DrawRectangle.ForGizmo(new Bounds2i(p, 1, 1), Color.green);
                    }
                }
                else
                {
                    var vertices = Rasterization.ConvexToVertices(isContains, bounds);
                    Assert.IsTrue(vertices.Length == vertices.Distinct().Count());

                    //Draw rasterized vertices
                    foreach (var p in vertices)
                    {
                        DebugExtension.DrawPoint(p, Color.green, 0.1f);
                    }
                }

                Debug.LogFormat("Contains calls count {0}", containsCallCounter);
            }
        }
 public void DrawMesh(Rasterization rasterizer, VertexProcessor processor)
 {
     //rasterizer.Triangle(processor.tr(vertices[0].position), processor.tr(vertices[1].position), processor.tr(vertices[2].position));
     //rasterizer.Triangle(vertices[0].position, vertices[1].position, vertices[2].position);
 }
Example #24
0
    private void LateUpdate()
    {
        var camera = GetComponent <Camera>();

        Profiler.BeginSample("ClearBuffers");
        if (pixelWidth != camera.pixelWidth || pixelHeight != camera.pixelHeight)
        {
            pixelWidth  = camera.pixelWidth;
            pixelHeight = camera.pixelHeight;
            int pixelCount = pixelWidth * pixelHeight;
            if (colorBuffer == null || colorBuffer.Length != pixelCount)
            {
                colorBuffer = new Color32[pixelCount];
            }
            if (depthBuffer == null || depthBuffer.Length != pixelCount)
            {
                depthBuffer = new float[pixelCount];
            }
        }
        else
        {
            while (bufferLock > 0)
            {
                Thread.SpinWait(4);
            }
        }
        Profiler.EndSample();

        // Race condition: if viewport was resized, we don't wait for buffer clear tasks to finish,
        // but if they were not scheduled by this point, they will clear the image being rendered!

        var worldToProjectionMatrix = camera.projectionMatrix * camera.worldToCameraMatrix;
        var worldToScreenMatrix     = Matrix4x4.TRS(
            new Vector3(pixelWidth * 0.5f, pixelHeight * 0.5f, 0), Quaternion.identity,
            new Vector3(pixelWidth * 0.5f, pixelHeight * 0.5f, 1)) * worldToProjectionMatrix;

        Vector4 p1 = worldToProjectionMatrix.GetRow(0);
        Vector4 p2 = worldToProjectionMatrix.GetRow(1);
        Vector4 p3 = worldToProjectionMatrix.GetRow(2);
        Vector4 p4 = worldToProjectionMatrix.GetRow(3);

        planes[0] = p4 + p3;
        planes[1] = p4 - p3;
        planes[2] = p4 + p1;
        planes[3] = p4 - p1;
        planes[4] = p4 + p2;
        planes[5] = p4 - p2;
        for (int i = 0; i < planes.Length; i++)
        {
            planes[i] /= ((Vector3)planes[i]).magnitude;
        }

        for (int r = 0; r < SoftwareRenderer.renderers.Count; r++)
        {
            var renderer  = SoftwareRenderer.renderers[r];
            var transform = renderer.transform;

            Profiler.BeginSample("Culling");
            Vector4 position4 = transform.position;
            position4.w = 1;
            if (Vector4.Dot(planes[0], position4) < -renderer.radius ||
                Vector4.Dot(planes[1], position4) < -renderer.radius ||
                Vector4.Dot(planes[2], position4) < -renderer.radius ||
                Vector4.Dot(planes[3], position4) < -renderer.radius ||
                Vector4.Dot(planes[4], position4) < -renderer.radius ||
                Vector4.Dot(planes[5], position4) < -renderer.radius)
            {
                renderer.gizmoColor = Color.red;
                Profiler.EndSample();
                continue;
            }
            else
            {
                renderer.gizmoColor = Color.green;
                Profiler.EndSample();
            }

            var       localToScreenMatrix = worldToScreenMatrix * transform.localToWorldMatrix;
            Vector3[] vertices            = renderer.vertices;
            if (vertexBuffer == null || vertexBuffer.Length < vertices.Length)
            {
                vertexBuffer = new Vector3[vertices.Length];
            }
            for (int i = 0; i < vertices.Length; i++)
            {
                vertexBuffer[i] = localToScreenMatrix.MultiplyPoint(vertices[i]);
            }

            // Optimization: get scale from localToWorldMatrix instead?
            Vector3 scale     = transform.lossyScale;
            float   flipFaces = Mathf.Sign(scale.x * scale.y * scale.z);

            Profiler.BeginSample("Drawing");
            int[]   triangles = renderer.triangles;
            Color32 color32   = renderer.color;
            for (int t = 0; t < triangles.Length;)
            {
                Vector3 a = vertexBuffer[triangles[t++]];
                Vector3 b = vertexBuffer[triangles[t++]];
                Vector3 c = vertexBuffer[triangles[t++]];

                if (a.z > -1 && a.z < 1 && b.z > -1 && b.z < 1 && c.z > -1 && c.z < 1 &&
                    Vector3.Cross(b - a, c - a).z *flipFaces < 0)
                {
                    Rasterization.FillTriangle(a, b, c, color32,
                                               colorBuffer, depthBuffer, pixelWidth, 0, pixelHeight, 0, pixelWidth);
                }
            }
            Profiler.EndSample();
        }
    }
Example #25
0
 /// <summary>
 /// Paints currently selected parquets in a rectangle between the given positions.
 /// </summary>
 /// <param name="in_upperLeft">The upper left corner of the rectangle.</param>
 /// <param name="in_lowerRight">The lower right corner of the rectangle.</param>
 /// <param name="in_filled">
 /// If set to <c>true</c>, the rectangle will be filled in; otherwise,
 /// only the outline will be painted.
 /// </param>
 public void PaintRectangle(Vector2Int in_upperLeft, Vector2Int in_lowerRight, bool in_filled)
 {
     PaintAtLocations(in_filled
         ? Rasterization.PlotFilledRectangle(in_upperLeft, in_lowerRight, _currentRegion.IsValidPosition)
         : Rasterization.PlotEmptyRectangle(in_upperLeft, in_lowerRight, _currentRegion.IsValidPosition));
 }
Example #26
0
 /// <summary>
 /// Paints currently selected parquets along a line between the given positions.
 /// </summary>
 /// <param name="in_start">The line's start.</param>
 /// <param name="in_end">The line's end.</param>
 public void PaintLine(Vector2Int in_start, Vector2Int in_end)
 {
     PaintAtLocations(Rasterization.PlotLine(in_start, in_end, _currentRegion.IsValidPosition));
 }