Ejemplo n.º 1
0
        public void DrawWallShadows(List <Vector2[]> walls, LightData pointLight)
        {
            GD.SetRenderTarget(ShadowTarg);
            var geom = ShadowGeometry.GenerateWallShadows(walls, pointLight);

            DrawShadows(geom, (pointLight.LightType == LightType.OUTDOORS)?2:0, pointLight);
        }
Ejemplo n.º 2
0
        public void DrawShadows(Tuple <GradVertex[], int[]> geom, int pass, LightData light)
        {
            var pointLight = light.LightPos;
            var effect     = this.GradEffect;

            effect.Parameters["Projection"].SetValue(Projection);
            GD.ScissorRectangle = DrawRect;
            GD.Clear(Color.Black);

            /*GD.SetRenderTarget(ShadowTarg);
             * if (!cleared)
             * {
             *  cleared = true;
             *  //GD.RasterizerState = new RasterizerState() { ScissorTestEnable = true, CullMode = CullMode.None };
             *  //GD.ScissorRectangle = new Rectangle((int)pointLight.X / 2 - 100, (int)pointLight.Y / 2 - 100, 200, 200);
             *  GD.Clear(Color.Black);
             * }*/
            effect.CurrentTechnique = effect.Techniques[0];
            EffectPassCollection passes = effect.Techniques[0].Passes;

            passes[pass].Apply();

            if (geom.Item1.Length > 0)
            {
                GD.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, geom.Item1, 0, geom.Item1.Length, geom.Item2, 0, geom.Item2.Length / 3);
            }
            //GD.SetRenderTarget(null);
        }
Ejemplo n.º 3
0
        public Matrix GetSunlightMat(LightData pointLight)
        {
            var mat = Matrix.Identity;

            //we have to build our own matrix here, which is weird
            //the y axis has to contribute to the other two axis, using the light direction.

            mat.M11 = 1; mat.M12 = 0; mat.M31 = pointLight.LightDir.X; //; //x axis.
            mat.M21 = 0; mat.M22 = 1; mat.M32 = pointLight.LightDir.Y; //light.LightDir.Y; //y axis.
            mat.M33 = 0;

            mat = Matrix.CreateScale(16, 16, 32 * pointLight.FalloffMultiplier) * mat;
            return(mat);
        }
Ejemplo n.º 4
0
        public void DrawObjShadows(List <Rectangle> objects, LightData pointLight)
        {
            GD.SetRenderTarget(ObjShadowTarg);
            Tuple <GradVertex[], int[]> geom;

            if (pointLight.LightType == LightType.ROOM)
            {
                geom = ShadowGeometry.GenerateObjShadows(objects.Where(x => x.Intersects(pointLight.LightBounds)).ToList(), pointLight);
            }
            else
            {
                geom = ShadowGeometry.GenerateObjShadows(objects, pointLight);
            }
            DrawShadows(geom, 1, pointLight);
        }
Ejemplo n.º 5
0
        public Matrix GetLightMat(LightData pointLight)
        {
            //point light projection onto a floor surface.
            //this can get a bit weird!
            //we need to create a frustrum that starts at the light's position, and with all edges on the edge of the lightmap

            var height = pointLight.Height; //lights are assumed to be in the middle

            var tan  = ((Blueprint.Width - borderSize) / 2f) / height;
            var fov  = (float)Math.Atan(tan);
            var lpos = new Vector2(pointLight.LightPos.X / 16f, pointLight.LightPos.Y / 16f);

            //return Matrix.CreateTranslation(-lpos.X, -lpos.Y, height) * Matrix.CreatePerspectiveFieldOfView(fov, 1, 0.01f, 3f) * Matrix.CreateTranslation(lpos.X, lpos.Y, 0);
            var mat = Matrix.CreateTranslation(-(lpos.X), -(lpos.Y), -height) * ProjFromTan(tan, 1, 0.01f, height) * Matrix.CreateScale(1, -1f, 1) * Matrix.CreateTranslation(lpos.X / (Blueprint.Width - borderSize) * 2 - 1f, -(lpos.Y / ((Blueprint.Height - borderSize) / 2f) - 1f), 0);

            return(mat);
        }
Ejemplo n.º 6
0
        public void DrawWallShadows(List <Vector2[]> walls, LightData pointLight)
        {
            if (pointLight.LightType == LightType.OUTDOORS && WallComp != null)
            {
                CreateOutsideIfMissing();
                LightEffect.Parameters["shadowMap"].SetValue(OutsideShadowTarg);

                if (OutShadowFloor == pointLight.Level)
                {
                    return;
                }
                OutShadowFloor = pointLight.Level;
                GD.SetRenderTarget(OutsideShadowTarg);
                var rect = new Rectangle(DrawRect.X * 2, DrawRect.Y * 2, DrawRect.Width * 2, DrawRect.Height * 2);
                GD.ScissorRectangle = rect;
                GD.Clear(Color.Black);
                var effect = this.GradEffect;

                effect.Parameters["Projection"].SetValue(Projection);

                var mat = GetSunlightMat(pointLight);

                GD.BlendState = MaxBlendRed;

                WallComp.DrawLMap(GD, pointLight, Projection, mat);
                Blueprint.Terrain.DrawLMap(GD, pointLight, Projection, mat);
                Blueprint.RoofComp.DrawLMap(GD, pointLight, Projection, mat);

                effect.CurrentTechnique = effect.Techniques[0];
                EffectPassCollection passes = effect.Techniques[0].Passes;
                passes[2].Apply();

                if (WorldConfig.Current.UltraLighting)
                {
                    Draw3DObjShadows(pointLight, false);
                }
            }
            else
            {
                GD.SetRenderTarget(ShadowTarg);
                var geom = ShadowGeometry.GenerateWallShadows(walls, pointLight);
                GD.BlendState = AddBlendRed;
                DrawShadows(geom, (pointLight.LightType == LightType.OUTDOORS) ? 2 : 0, pointLight);
            }
        }
Ejemplo n.º 7
0
        public void DrawShadows(Tuple <GradVertex[], int[]> geom, int pass, LightData light)
        {
            var pointLight = light.LightPos;
            var effect     = this.GradEffect;

            effect.Projection   = Projection;
            GD.ScissorRectangle = DrawRect;
            GD.Clear(Color.Black);

            effect.CurrentTechnique = effect.Techniques[0];
            EffectPassCollection passes = effect.Techniques[0].Passes;

            passes[pass].Apply();

            if (geom.Item1.Length > 0)
            {
                GD.DrawUserIndexedPrimitives(PrimitiveType.TriangleList, geom.Item1, 0, geom.Item1.Length, geom.Item2, 0, geom.Item2.Length / 3);
            }
        }
Ejemplo n.º 8
0
 public void DrawObjShadows(List <Rectangle> objects, LightData pointLight)
 {
     GD.SetRenderTarget(ObjShadowTarg);
     if (WorldConfig.Current.UltraLighting)
     {
         Draw3DObjShadows(pointLight, true);
     }
     else
     {
         Tuple <GradVertex[], int[]> geom;
         if (pointLight.LightType == LightType.ROOM)
         {
             geom = ShadowGeometry.GenerateObjShadows(objects.Where(x => x.Intersects(pointLight.LightBounds)).ToList(), pointLight);
         }
         else
         {
             geom = ShadowGeometry.GenerateObjShadows(objects, pointLight);
         }
         GD.BlendState = MaxBlendGreen;
         DrawShadows(geom, 1, pointLight);
     }
 }
Ejemplo n.º 9
0
        public void DrawWallShadows(List <Vector2[]> walls, LightData pointLight)
        {
            if (pointLight.LightType == LightType.OUTDOORS && WallComp != null)
            {
                CreateOutsideIfMissing();
                LightEffect.shadowMap = OutsideShadowTarg;

                if (OutShadowFloor == pointLight.Level)
                {
                    return;
                }
                OutShadowFloor = pointLight.Level;
                GD.SetRenderTarget(OutsideShadowTarg);
                var rect = new Rectangle(DrawRect.X * 2, DrawRect.Y * 2, DrawRect.Width * 2, DrawRect.Height * 2);
                GD.ScissorRectangle = rect;
                GD.Clear(Color.Black);
                var effect = this.GradEffect;

                effect.Projection = Projection;

                var mat = GetSunlightMat(pointLight);

                GD.BlendState = MaxBlendRed;

                WallComp.DrawLMap(GD, pointLight, Projection, mat);

                GD.BlendState = MaxBlendRed;
                Blueprint.Terrain.DrawLMap(GD, pointLight, Projection, mat);
                Blueprint.RoofComp.DrawLMap(GD, pointLight, Projection, mat);

                effect.CurrentTechnique = effect.Techniques[0];
                EffectPassCollection passes = effect.Techniques[0].Passes;
                passes[2].Apply();

                if (WorldConfig.Current.UltraLighting)
                {
                    Draw3DObjShadows(pointLight, false);
                }

                //blit outside shadows onto post target (for blur)

                if (OutsideShadowTargPost != null)
                {
                    var blend   = GD.BlendState;
                    var rast    = GD.RasterizerState;
                    var seffect = WorldContent.SpriteEffect;

                    //seffect.blurAmount = 0.7f / Blueprint.Width);
                    //seffect.blurAmount = 0.4f / Blueprint.Width);
                    //seffect.heightMultiplier = pointLight.FalloffMultiplier);

                    var blur   = (0.2f / Blueprint.Width) * (float)Math.Pow(pointLight.FalloffMultiplier, 0.8f);
                    var height = Math.Max(pointLight.FalloffMultiplier / 1.5f, 1);
                    var harden = 0.03f * (float)Math.Sqrt(pointLight.FalloffMultiplier);

                    //lower shadow target quality as blur size increases (to save on memory bandwidth)
                    if (pointLight.FalloffMultiplier > 6)
                    {
                        ShadowTargQualityDivider = 4;
                    }
                    if (pointLight.FalloffMultiplier > 3)
                    {
                        ShadowTargQualityDivider = 2;
                    }
                    else
                    {
                        ShadowTargQualityDivider = 1;
                    }

                    seffect.blurAmount       = new Vector2(blur, blur * 2 / 5f);
                    seffect.heightMultiplier = new Vector2(height, height * 5 / 2f);
                    seffect.hardenBias       = new Vector2(harden, harden * 0.5f);
                    seffect.noiseTexture     = TextureGenerator.GetUniformNoise(GD);

                    for (int i = 0; i < 4; i++)
                    {
                        seffect.SetTechnique((int)SpriteEffectTechniques.ShadowSeparableBlit1 + i);
                        RenderTarget2D tex;
                        if (i % 2 == 0)
                        {
                            GD.SetRenderTarget(OutsideShadowTargPost);
                            tex = OutsideShadowTarg;
                        }
                        else
                        {
                            GD.SetRenderTarget(OutsideShadowTarg);
                            tex = OutsideShadowTargPost;
                        }

                        ShadowTargBlit.Begin(blendState: (i == 1)? OpaqueBA : BlendState.Opaque, effect: seffect, samplerState: SamplerState.PointClamp);
                        ShadowTargBlit.Draw(tex, new Rectangle(0, 0, tex.Width, tex.Height), Color.White);
                        ShadowTargBlit.End();
                    }

                    /*
                     * ShadowTargBlit.Begin(blendState: BlendState.Opaque, effect: seffect);
                     * seffect.CurrentTechnique = seffect.Techniques["ShadowBlurBlit"];
                     * seffect.blurAmount = 0.7f / Blueprint.Width);
                     * seffect.heightMultiplier = pointLight.FalloffMultiplier);
                     * seffect.noiseTexture"]?.SetValue(TextureGenerator.GetUniformNoise(GD));
                     * ShadowTargBlit.Draw(OutsideShadowTarg, new Rectangle(0, 0, OutsideShadowTarg.Width, OutsideShadowTarg.Height), Color.White);
                     * ShadowTargBlit.End();
                     */

                    GD.SetRenderTarget(OutsideShadowTarg);
                    GD.RasterizerState = rast;
                    GD.BlendState      = blend;
                }
            }
            else
            {
                GD.SetRenderTarget(ShadowTarg);
                var geom = ShadowGeometry.GenerateWallShadows(walls, pointLight);
                GD.BlendState = AddBlendRed;
                DrawShadows(geom, (pointLight.LightType == LightType.OUTDOORS) ? 2 : 0, pointLight);
            }
        }
Ejemplo n.º 10
0
        public LightData BuildOutdoorsLight(double tod)
        {
            DayOffset   = 0.25f;
            DayDuration = 0.60f;

            bool   night = false;
            double modTime;
            var    offStart = 1 - (DayOffset + DayDuration);

            if (tod < DayOffset)
            {
                modTime = (offStart + tod) * 0.5 / (1 - DayDuration);
                night   = true;
            }
            else if (tod > DayOffset + DayDuration)
            {
                modTime = (tod - (1 - offStart)) * 0.5 / (1 - DayDuration);
                night   = true;
            }
            else
            {
                modTime = (tod - DayOffset) * 0.5 / DayDuration;
            }

            var light = new LightData()
            {
                //LightPos = tilePos * 16,
                LightPos  = new Vector2(-1000, -1000),
                LightType = LightType.OUTDOORS
            };

            Matrix Transform = Matrix.Identity;

            Transform *= Matrix.CreateRotationY((float)((modTime + 0.5) * Math.PI * 2.0)); //Controls the rotation of the sun/moon around the city.
            Transform *= Matrix.CreateRotationZ((float)(Math.PI * (45.0 / 180.0)));        //Sun is at an angle of 45 degrees to horizon at it's peak. idk why, it's winter maybe? looks nice either way
            Transform *= Matrix.CreateRotationY((float)(Math.PI * 0.3));                   //Offset from front-back a little. This might need some adjusting for the nicest sunset/sunrise locations.

            var lightPos = new Vector3(0, 0, -3000);

            lightPos = Vector3.Transform(lightPos, Transform);
            var z = lightPos.Z;

            if (lightPos.Y < 0)
            {
                lightPos.Y *= -1;
            }

            SunVector = lightPos;
            SunVector.Normalize();
            Night = night;

            light.LightPos = new Vector2(lightPos.Z, -lightPos.X);
            light.LightDir = -light.LightPos;
            light.LightDir.Normalize();
            lightPos.Normalize();

            LightVec = new Vector3(lightPos.Z, 1f, -lightPos.X);
            Blueprint.Terrain.LightVec = LightVec;

            light.FalloffMultiplier = (float)Math.Sqrt(lightPos.X * lightPos.X + lightPos.Z * lightPos.Z) / lightPos.Y;

            if (modTime > 0.25)
            {
                modTime = 0.5 - modTime;
            }

            if (Math.Abs(modTime) < 0.05) //Near the horizon, shadows should gracefully fade out into the opposite shadows (moonlight/sunlight)
            {
                light.ShadowMultiplier = (float)((Math.Abs(modTime) * 20)) * 1f;
            }
            else
            {
                light.ShadowMultiplier = 1; //Shadow strength. Remember to change the above if you alter this.
            }
            if (night)
            {
                light.ShadowMultiplier *= 1.33f;
            }

            OutdoorsLight           = light;
            Blueprint.OutdoorsLight = light;

            return(light);
        }
Ejemplo n.º 11
0
 public RenderTarget2D DebugShadows(List <Rectangle> objects, LightData pointLight)
 {
     DrawObjShadows(objects, pointLight);
     return(ShadowTarg);
 }
Ejemplo n.º 12
0
 public RenderTarget2D DebugShadows(List <Vector2[]> walls, LightData pointLight)
 {
     DrawWallShadows(walls, pointLight);
     return(ShadowTarg);
 }
Ejemplo n.º 13
0
        public void Draw3DObjShadows(LightData pointLight, bool clear)
        {
            var effect = WorldContent.RCObject;

            //we doubled the shadow resolution, so this is different.
            var dr = DrawRect;

            GD.ScissorRectangle = new Rectangle(dr.X * 2, dr.Y * 2, dr.Width * 2, dr.Height * 2);
            GD.BlendState       = MaxBlendGreen;
            if (clear)
            {
                GD.Clear(Color.Black);
            }

            effect.SetTechnique(RCObjectTechniques.LMapDraw);
            EffectPassCollection passes = effect.Techniques[0].Passes;

            passes[0].Apply();

            var outside = pointLight.LightType == LightType.OUTDOORS;

            if (outside)
            {
                effect.ViewProjection = Matrix.CreateScale(1 / 3f, -1 / 9f, 1 / 3f) * Matrix.CreateRotationX((float)Math.PI / -2) * GetSunlightMat(pointLight) * Projection;
            }
            else
            {
                effect.ViewProjection = Matrix.CreateScale(1 / 3f, -1 / 3f, 1 / 3f) * Matrix.CreateRotationX((float)Math.PI / -2) * GetLightMat(pointLight);
            }

            var lp16 = pointLight.LightPos / 16f;
            var li16 = pointLight.LightSize / 16f;

            List <ObjectComponent> objs;

            if (outside)
            {
                objs = new List <ObjectComponent>();
                for (int i = 0; i < Blueprint.Rooms.Count; i++)
                {
                    var room = Blueprint.Rooms[i];
                    if (room.IsOutside && room.Base == i)
                    {
                        //add components from this room to obj list
                        objs.AddRange(Blueprint.Light[i].Components);
                    }
                }
            }
            else
            {
                objs = Blueprint.Light[pointLight.Room].Components;
            }

            foreach (var obj in objs)
            {
                if ((outside && obj.Level > pointLight.Level) || (Math.Abs(obj.Position.X - lp16.X) + Math.Abs(obj.Position.Y - lp16.Y) < li16))
                {
                    obj.DrawLMap(GD, pointLight.Level);
                }
            }
        }
Ejemplo n.º 14
0
        public static Tuple <GradVertex[], int[]> GenerateShadows(IEnumerable <Vector2[]> volumes, LightData light, List <Vector3> ctrWidths, List <Rectangle> rectGeom)
        {
            DistanceMult = 5000f;
            var pointLight = light.LightPos;
            var mat_cw     = Matrix.CreateRotationZ(WallPenumbra);
            var mat_ccw    = Matrix.CreateRotationZ(-WallPenumbra);
            var vertices   = new List <GradVertex>();
            var indices    = new List <int>();
            var j          = 0;
            var basicDesc  = new EllipseDesc();
            var hc         = Color.White * 0.5f;
            var p          = WallPenumbra * 2;

            foreach (var pts in volumes)
            {
                //find sides closest to point
                float distM;
                if (light.LightType == LightType.OUTDOORS && ctrWidths == null)
                {
                    distM = 32f * light.FalloffMultiplier;
                }
                else
                {
                    distM = DistanceMult;
                }
                var baseIdx = vertices.Count;
                //var pts = ClockwiseLine(wall, pointLight);
                //var pts = ClosestPtsClockwise(wall, pointLight);

                //through project the points on each side with angle offsets.

                var mid = (pts[0] + pts[2]) / 2;

                Vector2 leftNorm, midNorm, rightNorm, leftFac, midFac, rightFac;
                if (light.LightType == LightType.OUTDOORS)
                {
                    leftNorm = midNorm = rightNorm = light.LightDir;
                }
                else
                {
                    leftNorm  = pts[0] - pointLight; leftNorm.Normalize();
                    midNorm   = mid - pointLight; midNorm.Normalize();
                    rightNorm = pts[2] - pointLight; rightNorm.Normalize();
                }

                leftFac = leftNorm * distM; rightFac = rightNorm * distM; midFac = midNorm * distM;

                EllipseDesc ellipse;
                if (ctrWidths != null)
                {
                    //distance * obj2height / (lightheight - obj2height)
                    var   ctW  = ctrWidths[j++];
                    var   mid2 = new Vector2(ctW.X, ctW.Y);
                    float height;
                    if (light.LightType == LightType.OUTDOORS)
                    {
                        height = 16 * light.FalloffMultiplier;
                    }
                    else
                    {
                        height = (mid2 - pointLight).Length() * 16 / ((16 * 3) - 16);
                    }
                    var midNorm2 = mid2 - pointLight; midNorm2.Normalize();
                    var largeDim = (ctW.Z + height) * midNorm2;
                    var smallDim = new Vector2(largeDim.Y, -largeDim.X);
                    smallDim.Normalize();
                    smallDim *= ctW.Z;
                    ellipse   = new EllipseDesc {
                        pos = mid2, dimensions = new Vector4(smallDim, largeDim.X, largeDim.Y)
                    };
                }
                else if (light.LightType == LightType.OUTDOORS)
                {
                    //wall linear falloff
                    var perp = (pts[2] - pts[0]);
                    var px   = perp.Y;
                    perp.Y = -perp.X;
                    perp.X = px;
                    perp.Normalize();

                    var midN2 = light.LightDir;

                    var dot = Vector2.Dot(perp, midN2);
//if (Math.Abs(dot) < 0.35) continue;
                    var length = distM * (dot);
                    var spos   = pts[0];// - ((dot>0)?perp:(-perp))*2;
                    perp   *= length;
                    ellipse = new EllipseDesc {
                        pos = spos, dimensions = new Vector4(length * length, 0, perp.X, perp.Y)
                    };
                }
                else
                {
                    ellipse = basicDesc;
                }

                //rotate the left and right norms to make the new penumbras
                var leftpen1 = pts[0] + Vector2.Transform(leftFac, mat_ccw);
                var leftpen2 = pts[0] + Vector2.Transform(leftFac, mat_cw);

                var rightpen1 = pts[2] + Vector2.Transform(rightFac, mat_ccw);
                var rightpen2 = pts[2] + Vector2.Transform(rightFac, mat_cw);


                //------ filled points ------

                //three cases. left and right penubras intersect at some point, in which case we make 2 triangles.
                //if they diverge, make 4 triangles.
                //penumbras contain each other. use one and center at half the target color.

                //y = mx + c

                var dist1 = (pts[0] - pointLight).LengthSquared();
                var dist2 = (pts[2] - pointLight).LengthSquared();
                if (dist1 > dist2)
                {
                    //is penumbra 1 inside 2?
                    if (Vector2.Dot(Vector2.Normalize(pts[0] - pts[2]), rightNorm) > PenCos)
                    {
                        //yes
                        //continue;
                        var conectr = pts[2] + rightNorm;
                        vertices.Add(GradVertex.ConeVert(pts[2], pts[2], conectr, Color.TransparentBlack, hc, p / 2, ellipse));
                        vertices.Add(GradVertex.ConeVert(rightpen1, pts[2], conectr, Color.TransparentBlack, hc, p / 2, ellipse));
                        vertices.Add(GradVertex.ConeVert(rightpen2, pts[2], conectr, Color.TransparentBlack, hc, p / 2, ellipse));
                        for (int i = 0; i < 3; i++)
                        {
                            indices.Add(baseIdx + i);
                        }
                        continue;
                    }
                }
                else
                {
                    //is penumbra 2 inside 1?
                    if (Vector2.Dot(Vector2.Normalize(pts[2] - pts[0]), leftNorm) > PenCos)
                    {
                        //yes
                        //continue;
                        var conectr = pts[0] + leftNorm;
                        vertices.Add(GradVertex.ConeVert(pts[0], pts[0], conectr, Color.TransparentBlack, hc, p, ellipse));
                        vertices.Add(GradVertex.ConeVert(leftpen1, pts[0], conectr, Color.TransparentBlack, hc, p, ellipse));
                        vertices.Add(GradVertex.ConeVert(leftpen2, pts[0], conectr, Color.TransparentBlack, hc, p, ellipse));
                        for (int i = 0; i < 3; i++)
                        {
                            indices.Add(baseIdx + i);
                        }
                        continue;
                    }
                }

                var midBack = pts[1] + midFac;
                //continue;
                var a    = leftpen2 - pts[0];
                var b    = (rightpen1 - pts[2]);
                var negX = -b.X;
                b.X = b.Y;
                b.Y = negX;
                var c = pts[2] - pts[0];
                var t = Vector2.Dot(c, b) / Vector2.Dot(a, b);

                if (t < 0)
                {
                    vertices.Add(GradVertex.SolidVert(pts[0], Color.White, ellipse));
                    vertices.Add(GradVertex.SolidVert(pts[1], Color.White, ellipse));
                    vertices.Add(GradVertex.SolidVert(pts[2], Color.White, ellipse));

                    vertices.Add(GradVertex.SolidVert(leftpen2, Color.White, ellipse));
                    vertices.Add(GradVertex.SolidVert(midBack, Color.White, ellipse));
                    vertices.Add(GradVertex.SolidVert(rightpen1, Color.White, ellipse));

                    indices.Add(baseIdx); indices.Add(baseIdx + 2); indices.Add(baseIdx + 1);     //half of rectangle
                    indices.Add(baseIdx); indices.Add(baseIdx + 3); indices.Add(baseIdx + 2);     //extension 1
                    indices.Add(baseIdx + 3); indices.Add(baseIdx + 4); indices.Add(baseIdx + 2); //extension 2
                    indices.Add(baseIdx + 4); indices.Add(baseIdx + 5); indices.Add(baseIdx + 2); //extension 3
                    baseIdx += 6;

                    //penumbras

                    vertices.Add(GradVertex.ConeVert(pts[0], pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(leftpen1, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(leftpen2, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse));

                    vertices.Add(GradVertex.ConeVert(pts[2], pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(rightpen1, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(rightpen2, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse));

                    for (int i = 0; i < 6; i++)
                    {
                        indices.Add(baseIdx + i);
                    }
                }
                else
                {
                    var inter   = pts[0] + a * t;
                    var distant = mid + Vector2.Normalize(inter - pointLight) * distM;
                    vertices.Add(GradVertex.SolidVert(pts[0], Color.White, ellipse));
                    vertices.Add(GradVertex.SolidVert(pts[0] + a * t, Color.White, ellipse));
                    vertices.Add(GradVertex.SolidVert(pts[2], Color.White, ellipse));
                    vertices.Add(GradVertex.SolidVert(pts[1], Color.White, ellipse));

                    indices.Add(baseIdx); indices.Add(baseIdx + 1); indices.Add(baseIdx + 2);
                    indices.Add(baseIdx); indices.Add(baseIdx + 2); indices.Add(baseIdx + 3); //half of rectangle

                    baseIdx += 4;

                    //penumbras: each penumbra becomes two tris as they intersect

                    vertices.Add(GradVertex.ConeVert(pts[0], pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(leftpen1, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(inter, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(distant, pts[0], leftpen2, Color.TransparentBlack, Color.White, p, ellipse));

                    vertices.Add(GradVertex.ConeVert(pts[2], pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(rightpen2, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(inter, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse));
                    vertices.Add(GradVertex.ConeVert(distant, pts[2], rightpen1, Color.TransparentBlack, Color.White, p, ellipse));

                    indices.Add(baseIdx); indices.Add(baseIdx + 1); indices.Add(baseIdx + 2);
                    indices.Add(baseIdx + 1); indices.Add(baseIdx + 3); indices.Add(baseIdx + 2);

                    baseIdx += 4;
                    indices.Add(baseIdx); indices.Add(baseIdx + 1); indices.Add(baseIdx + 2);
                    indices.Add(baseIdx + 1); indices.Add(baseIdx + 3); indices.Add(baseIdx + 2);
                }
            }

            return(new Tuple <GradVertex[], int[]>(vertices.ToArray(), indices.ToArray()));
        }
Ejemplo n.º 15
0
        public static Tuple <GradVertex[], int[]> GenerateWallShadows(List <Vector2[]> walls, LightData pointLight)
        {
            var projWalls = walls.Select(x => ClockwiseLine(x, pointLight.LightPos));

            return(GenerateShadows(projWalls, pointLight, null, null));
        }
Ejemplo n.º 16
0
        public static Tuple <GradVertex[], int[]> GenerateObjShadows(List <Rectangle> walls, LightData pointLight)
        {
            List <Rectangle> topDown   = new List <Rectangle>();
            List <Vector2[]> projWalls = new List <Vector2[]>();
            List <Vector3>   ctrWidths = new List <Vector3>();

            foreach (var i in walls)
            {
                if (i.Contains(pointLight.LightPos))
                {
                    topDown.Add(i);
                }
                else
                {
                    projWalls.Add(ClosestPtsClockwise(i, pointLight.LightPos));
                    var ctr = i.Center;
                    ctrWidths.Add(new Vector3(ctr.X, ctr.Y, (float)Math.Sqrt(i.Width * i.Width + i.Height * i.Height) / 2.5f));
                }
            }
            return(GenerateShadows(projWalls, pointLight, ctrWidths.ToList(), topDown));
        }