Example #1
0
        public async Task <FragmentMap> GetFragmentMap(Enviroment enviroment, Camera camera)
        {
            var fragmentMap = new FragmentMap()
            {
                Fragments         = new FragmentInfo[camera.ScreenWidth * camera.ScreenHeight],
                LastPosIndex      = 0,
                NotEmptyPositions = new int[camera.ScreenWidth * camera.ScreenHeight]
            };

            var allPolys = enviroment.GetPrimitives()
                           .SelectMany(p => p.GetLocalPolys(camera))
                           .Where(p => this.Observed(p, camera));

            await Task.Run(() =>
            {
                Parallel.ForEach(allPolys, (p) => this.GetAllFragmentsFromPoly(p, camera, fragmentMap));
            });

            return(fragmentMap);
        }
Example #2
0
        private void InterpolationStep(
            int xStart,
            int xSteps,
            int xDir,
            Vector3 startUp,
            Vector3 startDown,
            Vector2 startTexUp,
            Vector2 startTexDown,
            Vector3 startNormalUp,
            Vector3 startNormalDown,
            float startProectionUp,
            float startProectionDown,
            Vector3 startUpDelta,
            Vector3 startDownDelta,
            Vector2 startTexUpDelta,
            Vector2 startTexDownDelta,
            Vector3 startNormalUpDelta,
            Vector3 startNormalDownDelta,
            float startProectionUpDelta,
            float startProectionDownDelta,
            Camera camera,
            FragmentMap fragmentMap)
        {
            for (int i = 0; i <= xSteps; i++)
            {
                Vector3 pos = startDown;
                Vector3 norm = startNormalDown;
                Vector2 tex = startTexDown;
                Vector3 delta, deltaNormal;
                Vector2 deltaTexture;

                if (startProectionUp > 0)
                {
                    int steps;
                    int up = (int)startProectionUp, down = (int)startProectionDown;
                    int diffU = camera.ScreenHeight - 1 - up;

                    if (diffU < 0)
                    {
                        up = camera.ScreenHeight - 1;
                    }

                    steps = up - down;
                    if (steps != 0)
                    {
                        delta        = (startUp - startDown) / steps;
                        deltaTexture = (startTexUp - startTexDown) / steps;
                        deltaNormal  = (startNormalUp - startNormalDown) / steps;
                    }
                    else
                    {
                        delta        = Vector3.Zero;
                        deltaNormal  = Vector3.Zero;
                        deltaTexture = Vector2.Zero;
                    }

                    if (down < 0)
                    {
                        pos   -= delta * down;
                        tex   -= deltaTexture * down;
                        norm  -= deltaNormal * down;
                        steps += down;
                        down   = 0;
                    }

                    int x = xStart + (i * xDir);
                    for (int g = 0; g <= steps; g++)
                    {
                        int y     = down + g;
                        int index = y * camera.ScreenWidth + x;

                        if (fragmentMap.Fragments[index] == null)
                        {
                            var frag = new FragmentInfo(
                                pos,
                                norm,
                                tex,
                                new Vector2(x, y))
                            {
                                Color = int.MaxValue
                            };
                            fragmentMap.Fragments[index] = frag;
                            Monitor.Enter(this.locker);
                            fragmentMap.NotEmptyPositions[fragmentMap.LastPosIndex] = index;
                            fragmentMap.LastPosIndex++;
                            Monitor.Exit(this.locker);
                        }
                        else if (fragmentMap.Fragments[index].Coordinate.Z > pos.Z)
                        {
                            var frag = new FragmentInfo(
                                pos,
                                norm,
                                tex,
                                new Vector2(x, y))
                            {
                                Color = int.MaxValue
                            };
                            fragmentMap.Fragments[index] = frag;
                        }

                        pos  += delta;
                        norm += deltaNormal;
                        tex  += deltaTexture;
                    }
                }

                startDown          += startDownDelta;
                startUp            += startUpDelta;
                startTexDown       += startTexDownDelta;
                startTexUp         += startTexUpDelta;
                startNormalDown    += startNormalDownDelta;
                startNormalUp      += startNormalUpDelta;
                startProectionDown += startProectionDownDelta;
                startProectionUp   += startProectionUpDelta;
            }
        }
Example #3
0
        private void GetAllFragmentsFromPoly(Poly poly, Camera camera, FragmentMap fragmentMap)
        {
            var v1p = camera.ScreenProection(poly.v1.Position);
            var v2p = camera.ScreenProection(poly.v2.Position);
            var v3p = camera.ScreenProection(poly.v3.Position);

            if (v1p.X > v2p.X)
            {
                var w = v1p; v1p = v2p; v2p = w; var v = poly.v1; poly.v1 = poly.v2; poly.v2 = v;
            }
            if (v2p.X > v3p.X)
            {
                var w = v2p; v2p = v3p; v3p = w; var v = poly.v2; poly.v2 = poly.v3; poly.v3 = v;
            }
            if (v1p.X > v2p.X)
            {
                var w = v1p; v1p = v2p; v2p = w; var v = poly.v1; poly.v1 = poly.v2; poly.v2 = v;
            }

            int x1 = (int)v1p.X;
            int x2 = (int)v2p.X;
            int x3 = (int)v3p.X;

            int x12 = x2 - x1;
            int x13 = x3 - x1;
            int x32 = x3 - x2;

            Vector3 u, d, du, dd, nu, nd, dnu, dnd;
            Vector2 tu, td, dtu, dtd;
            float   pu, pd, dpu, dpd;
            int     rDiff;

            if (x2 > 0 && x1 < camera.ScreenWidth)
            {
                u  = poly.v1.Position;
                d  = poly.v1.Position;
                tu = poly.v1.TextureCoord;
                td = poly.v1.TextureCoord;
                nu = poly.v1.Normal;
                nd = poly.v1.Normal;
                pu = v1p.Y;
                pd = v1p.Y;

                if (x12 != 0)
                {
                    dpu = (v2p.Y - v1p.Y) / x12;
                    dpd = (v3p.Y - v1p.Y) / x13;

                    if (dpu > dpd)
                    {
                        du  = (poly.v2.Position - poly.v1.Position) / x12;
                        dtu = (poly.v2.TextureCoord - poly.v1.TextureCoord) / x12;
                        dnu = (poly.v2.Normal - poly.v1.Normal) / x12;

                        dd  = (poly.v3.Position - poly.v1.Position) / x13;
                        dtd = (poly.v3.TextureCoord - poly.v1.TextureCoord) / x13;
                        dnd = (poly.v3.Normal - poly.v1.Normal) / x13;
                    }
                    else
                    {
                        var t = dpu; dpu = dpd; dpd = t;

                        du  = (poly.v3.Position - poly.v1.Position) / x13;
                        dtu = (poly.v3.TextureCoord - poly.v1.TextureCoord) / x13;
                        dnu = (poly.v3.Normal - poly.v1.Normal) / x13;

                        dd  = (poly.v2.Position - poly.v1.Position) / x12;
                        dtd = (poly.v2.TextureCoord - poly.v1.TextureCoord) / x12;
                        dnd = (poly.v2.Normal - poly.v1.Normal) / x12;
                    }
                }
                else
                {
                    dpu = 0;
                    dpd = 0;
                    dtu = Vector2.Zero;
                    dtd = Vector2.Zero;
                    dnu = Vector3.Zero;
                    dnd = Vector3.Zero;
                    du  = Vector3.Zero;
                    dd  = Vector3.Zero;
                }

                rDiff = camera.ScreenWidth - 1 - x2;

                if (rDiff < 0)
                {
                    x12 += rDiff;
                }

                if (x1 < 0)
                {
                    x12 += x1;
                    u   -= du * x1;
                    d   -= dd * x1;
                    tu  -= dtu * x1;
                    td  -= dtd * x1;
                    nu  -= dnu * x1;
                    nd  -= dnd * x1;
                    pu  -= dpu * x1;
                    pd  -= dpd * x1;
                    x1   = 0;
                }

                this.InterpolationStep(x1, x12, 1,
                                       u, d, tu, td, nu, nd, pu, pd, du, dd, dtu,
                                       dtd, dnu, dnd, dpu,
                                       dpd, camera, fragmentMap);
            }

            if (x2 < camera.ScreenWidth && x3 > 0)
            {
                u  = poly.v3.Position;
                d  = poly.v3.Position;
                tu = poly.v3.TextureCoord;
                td = poly.v3.TextureCoord;
                nu = poly.v3.Normal;
                nd = poly.v3.Normal;
                pu = v3p.Y;
                pd = v3p.Y;

                if (x32 != 0)
                {
                    dpu = (v2p.Y - v3p.Y) / x32;
                    dpd = (v1p.Y - v3p.Y) / x13;

                    if (dpu > dpd)
                    {
                        du  = (poly.v2.Position - poly.v3.Position) / x32;
                        dtu = (poly.v2.TextureCoord - poly.v3.TextureCoord) / x32;
                        dnu = (poly.v2.Normal - poly.v3.Normal) / x32;

                        dd  = (poly.v1.Position - poly.v3.Position) / x13;
                        dtd = (poly.v1.TextureCoord - poly.v3.TextureCoord) / x13;
                        dnd = (poly.v1.Normal - poly.v3.Normal) / x13;
                    }
                    else
                    {
                        var t = dpu; dpu = dpd; dpd = t;

                        du  = (poly.v1.Position - poly.v3.Position) / x13;
                        dtu = (poly.v1.TextureCoord - poly.v3.TextureCoord) / x13;
                        dnu = (poly.v1.Normal - poly.v3.Normal) / x13;

                        dd  = (poly.v2.Position - poly.v3.Position) / x32;
                        dtd = (poly.v2.TextureCoord - poly.v3.TextureCoord) / x32;
                        dnd = (poly.v2.Normal - poly.v3.Normal) / x32;
                    }
                }
                else
                {
                    dpu = 0;
                    dpd = 0;
                    dtu = Vector2.Zero;
                    dtd = Vector2.Zero;
                    dnu = Vector3.Zero;
                    dnd = Vector3.Zero;
                    du  = Vector3.Zero;
                    dd  = Vector3.Zero;
                }

                if (x2 < 0)
                {
                    x32 += x2;
                    x2   = 0;
                }

                rDiff = camera.ScreenWidth - 1 - x3;

                if (rDiff < 0)
                {
                    x32 += rDiff;
                    u   -= du * rDiff;
                    d   -= dd * rDiff;
                    tu  -= dtu * rDiff;
                    td  -= dtd * rDiff;
                    nu  -= dnu * rDiff;
                    nd  -= dnd * rDiff;
                    pu  -= dpu * rDiff;
                    pd  -= dpd * rDiff;
                    x3   = camera.ScreenWidth - 1;
                }

                this.InterpolationStep(x3, x32, -1, u, d,
                                       tu, td, nu, nd,
                                       pu, pd, du, dd, dtu, dtd, dnu, dnd,
                                       dpu, dpd, camera, fragmentMap);
            }
        }