bool GetBlocks(Vector3I *coords, ref int posCount, float x, float z,
                       int posY, ShadowData *data, ref int index)
        {
            int       blockX = Utils.Floor(x), blockZ = Utils.Floor(z);
            Vector3I  p        = new Vector3I(blockX, 0, blockZ);
            BlockInfo info     = game.BlockInfo;
            Vector3   Position = entity.Position;

            index = 0;

            // Check we have not processed this particular block already.
            if (Position.Y < 0)
            {
                return(false);
            }
            for (int i = 0; i < 4; i++)
            {
                if (coords[i] == p)
                {
                    return(false);
                }
                data[i] = new ShadowData();
            }
            coords[posCount] = p; posCount++;

            while (posY >= 0 && index < 4)
            {
                BlockID block = GetShadowBlock(blockX, posY, blockZ);
                posY--;

                byte draw = info.Draw[block];
                if (draw == DrawType.Gas || draw == DrawType.Sprite || info.IsLiquid(block))
                {
                    continue;
                }
                float blockY = posY + 1 + info.MaxBB[block].Y;
                if (blockY >= Position.Y + 0.01f)
                {
                    continue;
                }

                data[index].Block = block; data[index].Y = blockY;
                CalcAlpha(Position.Y, ref data[index]);
                index++;
                // Check if the casted shadow will continue on further down.
                if (info.MinBB[block].X == 0 && info.MaxBB[block].X == 1 &&
                    info.MinBB[block].Z == 0 && info.MaxBB[block].Z == 1)
                {
                    return(true);
                }
            }

            if (index < 4)
            {
                data[index].Block = game.World.Env.EdgeBlock; data[index].Y = 0;
                CalcAlpha(Position.Y, ref data[index]);
                index++;
            }
            return(true);
        }
Example #2
0
        static bool GetBlocks(int x, int y, int z, ShadowData *data, ref int index)
        {
            float posY = entity.Position.Y;

            index = 0;
            bool outside = x < 0 || z < 0 || x >= game.World.Width || z >= game.World.Length;

            while (y >= 0 && index < 4)
            {
                BlockID block;
                if (!outside)
                {
                    block = game.World.GetBlock(x, y, z);
                }
                else if (y == game.World.Env.EdgeHeight - 1)
                {
                    block = BlockInfo.Draw[game.World.Env.EdgeBlock] == DrawType.Gas ? Block.Air : Block.Bedrock;
                }
                else if (y == game.World.Env.SidesHeight - 1)
                {
                    block = BlockInfo.Draw[game.World.Env.SidesBlock] == DrawType.Gas ? Block.Air : Block.Bedrock;
                }
                else
                {
                    block = Block.Air;
                }
                y--;

                byte draw = BlockInfo.Draw[block];
                if (draw == DrawType.Gas || draw == DrawType.Sprite || BlockInfo.IsLiquid[block])
                {
                    continue;
                }
                float blockY = (y + 1) + BlockInfo.MaxBB[block].Y;
                if (blockY >= posY + 0.01f)
                {
                    continue;
                }

                data[index].Block = block; data[index].Y = blockY;
                CalcAlpha(posY, ref data[index]);
                index++;

                // Check if the casted shadow will continue on further down.
                if (BlockInfo.MinBB[block].X == 0 && BlockInfo.MaxBB[block].X == 1 &&
                    BlockInfo.MinBB[block].Z == 0 && BlockInfo.MaxBB[block].Z == 1)
                {
                    return(true);
                }
            }

            if (index < 4)
            {
                data[index].Block = game.World.Env.EdgeBlock; data[index].Y = 0;
                CalcAlpha(posY, ref data[index]);
                index++;
            }
            return(true);
        }
        public static unsafe FakeStruct LoadFromObject(Component com, DataBuffer buffer)
        {
            var img = com as Shadow;

            if (img == null)
            {
                return(null);
            }
            FakeStruct  fake = new FakeStruct(buffer, ShadowData.ElementSize);
            ShadowData *data = (ShadowData *)fake.ip;

            data->effectColor     = img.effectColor;
            data->effectDistance  = img.effectDistance;
            data->useGraphicAlpha = img.useGraphicAlpha;
            return(fake);
        }
Example #4
0
        static void DrawCircle(VertexP3fT2fC4b[] verts, ref int index,
                               ShadowData *data, int dataCount, float x, float z)
        {
            Vector3 min = BlockInfo.MinBB[data[0].Block], max = BlockInfo.MaxBB[data[0].Block];

            DrawCoords(verts, ref index, data[0], x + min.X, z + min.Z, x + max.X, z + max.Z);
            for (int i = 1; i < dataCount; i++)
            {
                Vector3 nMin = BlockInfo.MinBB[data[i].Block], nMax = BlockInfo.MaxBB[data[i].Block];
                DrawCoords(verts, ref index, data[i], x + min.X, z + nMin.Z, x + max.X, z + min.Z);
                DrawCoords(verts, ref index, data[i], x + min.X, z + max.Z, x + max.X, z + nMax.Z);

                DrawCoords(verts, ref index, data[i], x + nMin.X, z + nMin.Z, x + min.X, z + nMax.Z);
                DrawCoords(verts, ref index, data[i], x + max.X, z + nMin.Z, x + nMax.X, z + nMax.Z);
                min = nMin; max = nMax;
            }
        }
Example #5
0
        void DrawCircle(VertexPos3fTex2fCol4b[] verts, ref int index,
                        ShadowData *data, int dataCount, float x, float z)
        {
            x = Utils.Floor(x); z = Utils.Floor(z);
            BlockInfo info = game.BlockInfo;
            Vector3   min = info.MinBB[data[0].Block], max = info.MaxBB[data[0].Block];

            DrawCoords(verts, ref index, data[0], x + min.X, z + min.Z, x + max.X, z + max.Z);
            for (int i = 1; i < dataCount; i++)
            {
                Vector3 nMin = info.MinBB[data[i].Block], nMax = info.MaxBB[data[i].Block];
                DrawCoords(verts, ref index, data[i], x + min.X, z + nMin.Z, x + max.X, z + min.Z);
                DrawCoords(verts, ref index, data[i], x + min.X, z + max.Z, x + max.X, z + nMax.Z);

                DrawCoords(verts, ref index, data[i], x + nMin.X, z + nMin.Z, x + min.X, z + nMax.Z);
                DrawCoords(verts, ref index, data[i], x + max.X, z + nMin.Z, x + nMax.X, z + nMax.Z);
                min = nMin; max = nMax;
            }
        }
Example #6
0
        internal void Draw()
        {
            EntityShadow mode = game.Entities.ShadowMode;
            Vector3      Position = entity.Position;
            float        posX = Position.X, posZ = Position.Z;
            int          posY = Math.Min((int)Position.Y, game.World.Height - 1);
            int          index = 0, vb = 0;

            radius = 7f * Math.Min(entity.ModelScale, 1) * entity.Model.ShadowScale;

            VertexP3fT2fC4b[] verts = null;
            int         posCount = 0, dataCount = 0;
            Vector3I *  coords = stackalloc Vector3I[4];
            ShadowData *data   = stackalloc ShadowData[4];

            for (int i = 0; i < 4; i++)
            {
                coords[i] = new Vector3I(int.MinValue);
                data[i]   = new ShadowData();
            }

            if (mode == EntityShadow.SnapToBlock)
            {
                vb = game.Graphics.texVb; verts = game.Graphics.texVerts;
                if (!GetBlocks(coords, ref posCount, posX, posZ, posY, data, ref dataCount))
                {
                    return;
                }

                float x1 = Utils.Floor(posX), z1 = Utils.Floor(posZ);
                DraqSquareShadow(verts, ref index, data[0].Y, 220, x1, z1);
            }
            else
            {
                vb = game.ModelCache.vb; verts = game.ModelCache.vertices;

                float x = posX - radius / 16f, z = posZ - radius / 16f;
                if (GetBlocks(coords, ref posCount, x, z, posY, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x, z);
                }

                x = Math.Max(posX - radius / 16f, Utils.Floor(posX + radius / 16f));
                if (GetBlocks(coords, ref posCount, x, z, posY, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x, z);
                }

                z = Math.Max(posZ - radius / 16f, Utils.Floor(posZ + radius / 16f));
                if (GetBlocks(coords, ref posCount, x, z, posY, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x, z);
                }

                x = posX - radius / 16f;
                if (GetBlocks(coords, ref posCount, x, z, posY, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x, z);
                }
            }

            if (index == 0)
            {
                return;
            }
            CheckShadowTexture(game.Graphics);

            if (!boundShadowTex)
            {
                game.Graphics.BindTexture(shadowTex);
                boundShadowTex = true;
            }
            game.Graphics.UpdateDynamicIndexedVb(DrawMode.Triangles, vb, verts, index);
        }
Example #7
0
        internal static void Draw(Game game, Entity entity)
        {
            ShadowComponent.game   = game;
            ShadowComponent.entity = entity;

            Vector3 Position = entity.Position;

            if (Position.Y < 0)
            {
                return;
            }

            float posX = Position.X, posZ = Position.Z;
            int   posY = Math.Min((int)Position.Y, game.World.MaxY);
            int   index = 0, vb = 0;

            float baseRadius = 7f * Math.Min(entity.ModelScale.Y, 1) * entity.Model.ShadowScale;

            radius  = baseRadius / 16.0f;
            uvScale = 16.0f / (baseRadius * 2);

            VertexP3fT2fC4b[] verts = null;
            int         dataCount   = 0;
            ShadowData *data        = stackalloc ShadowData[4];

            if (game.Entities.ShadowMode == EntityShadow.SnapToBlock)
            {
                vb = game.Graphics.texVb; verts = game.Graphics.texVerts;
                int x1 = Utils.Floor(posX), z1 = Utils.Floor(posZ);

                if (!GetBlocks(x1, posY, z1, data, ref dataCount))
                {
                    return;
                }
                DrawSquareShadow(verts, ref index, data[0].Y, x1, z1);
            }
            else
            {
                vb = game.ModelCache.vb; verts = game.ModelCache.vertices;
                int x1 = Utils.Floor(posX - radius), z1 = Utils.Floor(posZ - radius);
                int x2 = Utils.Floor(posX + radius), z2 = Utils.Floor(posZ + radius);

                if (GetBlocks(x1, posY, z1, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x1, z1);
                }
                if (x1 != x2 && GetBlocks(x2, posY, z1, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x2, z1);
                }
                if (z1 != z2 && GetBlocks(x1, posY, z2, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x1, z2);
                }
                if (x1 != x2 && z1 != z2 && GetBlocks(x2, posY, z2, data, ref dataCount) && data[0].A > 0)
                {
                    DrawCircle(verts, ref index, data, dataCount, x2, z2);
                }
            }

            if (index == 0)
            {
                return;
            }
            CheckShadowTexture(game.Graphics);

            if (!boundShadowTex)
            {
                game.Graphics.BindTexture(shadowTex);
                boundShadowTex = true;
            }
            game.Graphics.UpdateDynamicVb_IndexedTris(vb, verts, index);
        }