public int ReadFrom(byte[] Buffer, int StartIndex = 0)
        {
            int cursor = StartIndex;

            ServerID = BitConverter.ToInt16(Buffer, cursor);
            cursor  += TypeSizes.SHORT;

            FloorTexture = BitConverter.ToUInt16(Buffer, cursor);
            cursor      += TypeSizes.SHORT;

            CeilingTexture = BitConverter.ToUInt16(Buffer, cursor);
            cursor        += TypeSizes.SHORT;

            TextureX = BitConverter.ToInt16(Buffer, cursor);
            cursor  += TypeSizes.SHORT;

            TextureY = BitConverter.ToInt16(Buffer, cursor);
            cursor  += TypeSizes.SHORT;

            FloorHeight = (Real)BitConverter.ToInt16(Buffer, cursor);
            cursor     += TypeSizes.SHORT;

            CeilingHeight = (Real)BitConverter.ToInt16(Buffer, cursor);
            cursor       += TypeSizes.SHORT;

            Light1 = Buffer[cursor];
            cursor++;

            Flags   = new RooSectorFlags(BitConverter.ToUInt32(Buffer, cursor));
            cursor += TypeSizes.INT;

            if (HasSpeed)
            {
                Speed = Buffer[cursor];
                cursor++;
            }

            // Check for attached subinfo
            if (Flags.IsSlopedFloor)
            {
                SlopeInfoFloor = new RooSectorSlopeInfo(RooVersion, Buffer, cursor);
                cursor        += SlopeInfoFloor.ByteLength;
            }
            if (Flags.IsSlopedCeiling)
            {
                SlopeInfoCeiling = new RooSectorSlopeInfo(RooVersion, Buffer, cursor);
                cursor          += SlopeInfoCeiling.ByteLength;
            }

            return(cursor - StartIndex);
        }
        public unsafe void ReadFrom(ref byte *Buffer)
        {
            ServerID = *((short *)Buffer);
            Buffer  += TypeSizes.SHORT;

            FloorTexture = *((ushort *)Buffer);
            Buffer      += TypeSizes.SHORT;

            CeilingTexture = *((ushort *)Buffer);
            Buffer        += TypeSizes.SHORT;

            TextureX = *((short *)Buffer);
            Buffer  += TypeSizes.SHORT;

            TextureY = *((short *)Buffer);
            Buffer  += TypeSizes.SHORT;

            FloorHeight = (Real)(*((short *)Buffer));
            Buffer     += TypeSizes.SHORT;

            CeilingHeight = (Real)(*((short *)Buffer));
            Buffer       += TypeSizes.SHORT;

            Light1 = Buffer[0];
            Buffer++;

            Flags   = new RooSectorFlags(*((uint *)Buffer));
            Buffer += TypeSizes.INT;

            if (HasSpeed)
            {
                Speed = Buffer[0];
                Buffer++;
            }

            // Check for attached subinfo
            if (Flags.IsSlopedFloor)
            {
                SlopeInfoFloor = new RooSectorSlopeInfo(RooVersion, ref Buffer);
            }

            if (Flags.IsSlopedCeiling)
            {
                SlopeInfoCeiling = new RooSectorSlopeInfo(RooVersion, ref Buffer);
            }
        }
 /// <summary>
 /// Calculates the z coordinate of a point given by it's x,y components and
 /// a plane equation in slopeinfo.
 /// </summary>
 /// <param name="SlopeInfo"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <returns>Height of the point in legacy client FINENESS (1:1024)</returns>
 public static Real CalculateSlopeHeight(RooSectorSlopeInfo SlopeInfo, Real x, Real y)
 {
     return((-SlopeInfo.A * x - SlopeInfo.B * y - SlopeInfo.D) / SlopeInfo.C);
 }
Exemple #4
0
        /// <summary>
        /// Creates RenderInfo data (containing points and uv coordinates).
        /// Note: Z component is the height.
        /// </summary>
        /// <param name="IsFloor">Whether to create for floor or ceiling</param>
        /// <param name="Scale">Optional additional scale to apply.</param>
        /// <returns></returns>
        public RenderInfo GetRenderInfo(bool IsFloor, Real Scale = 1.0f)
        {
            // get possible slopeinfo either for floor or ceiling
            RooSectorSlopeInfo slopeInfo = null;

            if (IsFloor)
            {
                slopeInfo = Sector.SlopeInfoFloor;
            }
            if (!IsFloor)
            {
                slopeInfo = Sector.SlopeInfoCeiling;
            }

            // initialize renderinfo keeping points and uv coordinates
            RenderInfo RI = new RenderInfo(Vertices.Count);

            V3[] P  = RI.P;
            V2[] UV = RI.UV;

            // initialize some more vars
            V3   intersectTop  = new V3(0, 0, 0);
            V3   intersectLeft = new V3(0, 0, 0);
            int  left          = 0;
            int  top           = 0;
            Real inv64         = 1.0f / (Real)(64 << 4);
            Real oneOverC      = 0.0f;

            // find most top left vertex and get its coordinates
            if (slopeInfo != null)
            {
                left     = (int)slopeInfo.X0;
                top      = (int)slopeInfo.Y0;
                oneOverC = 1.0f / slopeInfo.C;
            }
            else
            {
                for (int i = 0; i < Vertices.Count; i++)
                {
                    if (Vertices[i].X < left)
                    {
                        left = Vertices[i].X;
                    }

                    if (Vertices[i].Y < top)
                    {
                        top = Vertices[i].Y;
                    }
                }
            }

            // Start UV calculation
            for (int count = 0; count < Vertices.Count; count++)
            {
                // fill in point coordinates
                // this time we use the z as z and flip y/z (mogre!) when triangulating
                // instead of changing all the following ported code
                if (slopeInfo != null)
                {
                    P[count].X = (Real)Vertices[count].X;
                    P[count].Y = (Real)Vertices[count].Y;
                    P[count].Z = (-slopeInfo.A * P[count].X - slopeInfo.B * P[count].Y - slopeInfo.D) * oneOverC;
                }
                else
                {
                    P[count].X = (Real)Vertices[count].X;
                    P[count].Y = (Real)Vertices[count].Y;

                    if (IsFloor)
                    {
                        P[count].Z = (Real)(Sector.FloorHeight * 16.0f);
                    }
                    else
                    {
                        P[count].Z = (Real)(Sector.CeilingHeight * 16.0f);
                    }
                }

                Real U, temp;

                // start uv
                if (slopeInfo != null)
                {
                    V3   vectorU = new V3(0, 0, 0);
                    V3   vectorV = new V3(0, 0, 0);
                    V3   vector  = new V3(0, 0, 0);
                    Real distance;

                    // calc distance from top line (vector u)
                    U = ((P[count].X - slopeInfo.P0.X) * (slopeInfo.P1.X - slopeInfo.P0.X)) +
                        ((P[count].Z - slopeInfo.P0.Z) * (slopeInfo.P1.Z - slopeInfo.P0.Z)) +
                        ((P[count].Y - slopeInfo.P0.Y) * (slopeInfo.P1.Y - slopeInfo.P0.Y));

                    temp = ((slopeInfo.P1.X - slopeInfo.P0.X) * (slopeInfo.P1.X - slopeInfo.P0.X)) +
                           ((slopeInfo.P1.Z - slopeInfo.P0.Z) * (slopeInfo.P1.Z - slopeInfo.P0.Z)) +
                           ((slopeInfo.P1.Y - slopeInfo.P0.Y) * (slopeInfo.P1.Y - slopeInfo.P0.Y));

                    if (temp == 0)
                    {
                        temp = 1.0f;
                    }

                    U /= temp;

                    intersectTop.X = slopeInfo.P0.X + U * (slopeInfo.P1.X - slopeInfo.P0.X);
                    intersectTop.Z = slopeInfo.P0.Z + U * (slopeInfo.P1.Z - slopeInfo.P0.Z);
                    intersectTop.Y = slopeInfo.P0.Y + U * (slopeInfo.P1.Y - slopeInfo.P0.Y);

                    UV[count].X = (Real)System.Math.Sqrt(
                        (P[count].X - intersectTop.X) * (P[count].X - intersectTop.X) +
                        (P[count].Z - intersectTop.Z) * (P[count].Z - intersectTop.Z) +
                        (P[count].Y - intersectTop.Y) * (P[count].Y - intersectTop.Y));

                    // calc distance from left line (vector v)
                    U = ((P[count].X - slopeInfo.P0.X) * (slopeInfo.P2.X - slopeInfo.P0.X)) +
                        ((P[count].Z - slopeInfo.P0.Z) * (slopeInfo.P2.Z - slopeInfo.P0.Z)) +
                        ((P[count].Y - slopeInfo.P0.Y) * (slopeInfo.P2.Y - slopeInfo.P0.Y));

                    temp = ((slopeInfo.P2.X - slopeInfo.P0.X) * (slopeInfo.P2.X - slopeInfo.P0.X)) +
                           ((slopeInfo.P2.Z - slopeInfo.P0.Z) * (slopeInfo.P2.Z - slopeInfo.P0.Z)) +
                           ((slopeInfo.P2.Y - slopeInfo.P0.Y) * (slopeInfo.P2.Y - slopeInfo.P0.Y));

                    if (temp == 0)
                    {
                        temp = 1.0f;
                    }

                    U /= temp;

                    intersectLeft.X = slopeInfo.P0.X + U * (slopeInfo.P2.X - slopeInfo.P0.X);
                    intersectLeft.Z = slopeInfo.P0.Z + U * (slopeInfo.P2.Z - slopeInfo.P0.Z);
                    intersectLeft.Y = slopeInfo.P0.Y + U * (slopeInfo.P2.Y - slopeInfo.P0.Y);

                    UV[count].Y = (Real)System.Math.Sqrt(
                        (P[count].X - intersectLeft.X) * (P[count].X - intersectLeft.X) +
                        (P[count].Z - intersectLeft.Z) * (P[count].Z - intersectLeft.Z) +
                        (P[count].Y - intersectLeft.Y) * (P[count].Y - intersectLeft.Y));

                    UV[count].X += (Sector.TextureY << 4) / 2.0f;
                    UV[count].Y += (Sector.TextureX << 4) / 2.0f;

                    vectorU.X = slopeInfo.P1.X - slopeInfo.P0.X;
                    vectorU.Z = slopeInfo.P1.Z - slopeInfo.P0.Z;
                    vectorU.Y = slopeInfo.P1.Y - slopeInfo.P0.Y;

                    distance = (Real)System.Math.Sqrt((vectorU.X * vectorU.X) + (vectorU.Y * vectorU.Y));

                    if (distance == 0)
                    {
                        distance = 1.0f;
                    }

                    vectorU.X /= distance;
                    vectorU.Z /= distance;
                    vectorU.Y /= distance;

                    vectorV.X = slopeInfo.P2.X - slopeInfo.P0.X;
                    vectorV.Z = slopeInfo.P2.Z - slopeInfo.P0.Z;
                    vectorV.Y = slopeInfo.P2.Y - slopeInfo.P0.Y;

                    distance = (Real)System.Math.Sqrt((vectorV.X * vectorV.X) + (vectorV.Y * vectorV.Y));

                    if (distance == 0)
                    {
                        distance = 1.0f;
                    }

                    vectorV.X /= distance;
                    vectorV.Z /= distance;
                    vectorV.Y /= distance;

                    vector.X = P[count].X - slopeInfo.P0.X;
                    vector.Y = P[count].Y - slopeInfo.P0.Y;

                    distance = (Real)System.Math.Sqrt((vector.X * vector.X) + (vector.Y * vector.Y));

                    if (distance == 0)
                    {
                        distance = 1.0f;
                    }

                    vector.X /= distance;
                    vector.Y /= distance;

                    if (((vector.X * vectorU.X) +
                         (vector.Y * vectorU.Y)) <= 0)
                    {
                        UV[count].Y = -UV[count].Y;
                    }

                    if (((vector.X * vectorV.X) +
                         (vector.Y * vectorV.Y)) > 0)
                    {
                        UV[count].X = -UV[count].X;
                    }
                }
                else
                {
                    UV[count].X = (Real)System.Math.Abs(Vertices[count].Y - top) - (Sector.TextureY << 4);
                    UV[count].Y = (Real)System.Math.Abs(Vertices[count].X - left) - (Sector.TextureX << 4);
                }

                UV[count].X *= inv64;
                UV[count].Y *= inv64;

                // apply additional userscale
                P[count] *= Scale;
            }

            // Calculate the normal
            if (slopeInfo != null)
            {
                // if the sector is sloped, we get the normal from slopeinfo
                RI.Normal.X = slopeInfo.A;
                RI.Normal.Y = slopeInfo.B;
                RI.Normal.Z = slopeInfo.C;

                RI.Normal.Normalize();
            }
            else if (IsFloor)
            {
                // default normal for non sloped floor
                RI.Normal.X = 0.0f;
                RI.Normal.Y = 0.0f;
                RI.Normal.Z = 1.0f;
            }
            else
            {
                // default normal for non sloped ceilings
                RI.Normal.X = 0.0f;
                RI.Normal.Y = 0.0f;
                RI.Normal.Z = -1.0f;
            }

            return(RI);
        }
Exemple #5
0
        /// <summary>
        /// Updates the P, UV and Normal properties for either floor or ceiling.
        /// Fills in current 3D data for the subsector vertices.
        /// Note: Z component is the height here.
        /// </summary>
        /// <param name="IsFloor">Whether to create for floor or ceiling</param>
        /// <param name="Scale">Optional additional scale to apply.</param>
        public void UpdateVertexData(bool IsFloor, Real Scale = 1.0f)
        {
            const Real INV64 = 1.0f / (Real)(64 << 4);  // from old code..

            V3 normal;

            V3[] p        = new V3[Vertices.Count];
            V2[] uv       = new V2[Vertices.Count];
            Real left     = 0;
            Real top      = 0;
            Real oneOverC = 0.0f;

            RooSectorSlopeInfo slopeInfo =
                (IsFloor) ? Sector.SlopeInfoFloor : Sector.SlopeInfoCeiling;

            /*****************************************************************/

            // find most top left vertex and get its coordinates
            if (slopeInfo != null)
            {
                left     = (int)slopeInfo.X0;
                top      = (int)slopeInfo.Y0;
                oneOverC = 1.0f / slopeInfo.C;
            }
            else
            {
                for (int i = 0; i < Vertices.Count; i++)
                {
                    if (Vertices[i].X < left)
                    {
                        left = Vertices[i].X;
                    }

                    if (Vertices[i].Y < top)
                    {
                        top = Vertices[i].Y;
                    }
                }
            }

            /*****************************************************************/

            for (int count = 0; count < Vertices.Count; count++)
            {
                // 1: Fill in vertex coordinates
                if (slopeInfo != null)
                {
                    p[count].X = Vertices[count].X;
                    p[count].Y = Vertices[count].Y;
                    p[count].Z = (-slopeInfo.A * p[count].X - slopeInfo.B * p[count].Y - slopeInfo.D) * oneOverC;
                }
                else
                {
                    p[count].X = Vertices[count].X;
                    p[count].Y = Vertices[count].Y;
                    p[count].Z = (IsFloor) ? (Sector.FloorHeight * 16.0f) : (Sector.CeilingHeight * 16.0f);
                }

                // 2.1: UV with slope
                if (slopeInfo != null)
                {
                    V3   intersectTop;
                    V3   intersectLeft;
                    V3   vectorU;
                    V3   vectorV;
                    V3   vector;
                    Real distance;
                    Real U, temp;

                    // calc distance from top line (vector u)
                    U = ((p[count].X - slopeInfo.P0.X) * (slopeInfo.P1.X - slopeInfo.P0.X)) +
                        ((p[count].Z - slopeInfo.P0.Z) * (slopeInfo.P1.Z - slopeInfo.P0.Z)) +
                        ((p[count].Y - slopeInfo.P0.Y) * (slopeInfo.P1.Y - slopeInfo.P0.Y));

                    temp = ((slopeInfo.P1.X - slopeInfo.P0.X) * (slopeInfo.P1.X - slopeInfo.P0.X)) +
                           ((slopeInfo.P1.Z - slopeInfo.P0.Z) * (slopeInfo.P1.Z - slopeInfo.P0.Z)) +
                           ((slopeInfo.P1.Y - slopeInfo.P0.Y) * (slopeInfo.P1.Y - slopeInfo.P0.Y));

                    if (temp == 0.0f)
                    {
                        temp = 1.0f;
                    }

                    U /= temp;

                    intersectTop.X = slopeInfo.P0.X + U * (slopeInfo.P1.X - slopeInfo.P0.X);
                    intersectTop.Z = slopeInfo.P0.Z + U * (slopeInfo.P1.Z - slopeInfo.P0.Z);
                    intersectTop.Y = slopeInfo.P0.Y + U * (slopeInfo.P1.Y - slopeInfo.P0.Y);

                    uv[count].X = (Real)System.Math.Sqrt(
                        (p[count].X - intersectTop.X) * (p[count].X - intersectTop.X) +
                        (p[count].Z - intersectTop.Z) * (p[count].Z - intersectTop.Z) +
                        (p[count].Y - intersectTop.Y) * (p[count].Y - intersectTop.Y));

                    // calc distance from left line (vector v)
                    U = ((p[count].X - slopeInfo.P0.X) * (slopeInfo.P2.X - slopeInfo.P0.X)) +
                        ((p[count].Z - slopeInfo.P0.Z) * (slopeInfo.P2.Z - slopeInfo.P0.Z)) +
                        ((p[count].Y - slopeInfo.P0.Y) * (slopeInfo.P2.Y - slopeInfo.P0.Y));

                    temp = ((slopeInfo.P2.X - slopeInfo.P0.X) * (slopeInfo.P2.X - slopeInfo.P0.X)) +
                           ((slopeInfo.P2.Z - slopeInfo.P0.Z) * (slopeInfo.P2.Z - slopeInfo.P0.Z)) +
                           ((slopeInfo.P2.Y - slopeInfo.P0.Y) * (slopeInfo.P2.Y - slopeInfo.P0.Y));

                    if (temp == 0.0f)
                    {
                        temp = 1.0f;
                    }

                    U /= temp;

                    intersectLeft.X = slopeInfo.P0.X + U * (slopeInfo.P2.X - slopeInfo.P0.X);
                    intersectLeft.Z = slopeInfo.P0.Z + U * (slopeInfo.P2.Z - slopeInfo.P0.Z);
                    intersectLeft.Y = slopeInfo.P0.Y + U * (slopeInfo.P2.Y - slopeInfo.P0.Y);

                    uv[count].Y = (Real)System.Math.Sqrt(
                        (p[count].X - intersectLeft.X) * (p[count].X - intersectLeft.X) +
                        (p[count].Z - intersectLeft.Z) * (p[count].Z - intersectLeft.Z) +
                        (p[count].Y - intersectLeft.Y) * (p[count].Y - intersectLeft.Y));

                    uv[count].X += (Sector.TextureY << 4) / 2.0f;
                    uv[count].Y += (Sector.TextureX << 4) / 2.0f;

                    vectorU.X = slopeInfo.P1.X - slopeInfo.P0.X;
                    vectorU.Z = slopeInfo.P1.Z - slopeInfo.P0.Z;
                    vectorU.Y = slopeInfo.P1.Y - slopeInfo.P0.Y;

                    distance = (Real)System.Math.Sqrt((vectorU.X * vectorU.X) + (vectorU.Y * vectorU.Y));

                    if (distance == 0.0f)
                    {
                        distance = 1.0f;
                    }

                    vectorU.X /= distance;
                    vectorU.Z /= distance;
                    vectorU.Y /= distance;

                    vectorV.X = slopeInfo.P2.X - slopeInfo.P0.X;
                    vectorV.Z = slopeInfo.P2.Z - slopeInfo.P0.Z;
                    vectorV.Y = slopeInfo.P2.Y - slopeInfo.P0.Y;

                    distance = (Real)System.Math.Sqrt((vectorV.X * vectorV.X) + (vectorV.Y * vectorV.Y));

                    if (distance == 0.0f)
                    {
                        distance = 1.0f;
                    }

                    vectorV.X /= distance;
                    vectorV.Z /= distance;
                    vectorV.Y /= distance;

                    vector.X = p[count].X - slopeInfo.P0.X;
                    vector.Y = p[count].Y - slopeInfo.P0.Y;

                    distance = (Real)System.Math.Sqrt((vector.X * vector.X) + (vector.Y * vector.Y));

                    if (distance == 0)
                    {
                        distance = 1.0f;
                    }

                    vector.X /= distance;
                    vector.Y /= distance;

                    if (((vector.X * vectorU.X) +
                         (vector.Y * vectorU.Y)) <= 0)
                    {
                        uv[count].Y = -uv[count].Y;
                    }

                    if (((vector.X * vectorV.X) +
                         (vector.Y * vectorV.Y)) > 0)
                    {
                        uv[count].X = -uv[count].X;
                    }
                }

                // 2.2: UV without slope
                else
                {
                    uv[count].X = System.Math.Abs(Vertices[count].Y - top) - (Sector.TextureY << 4);
                    uv[count].Y = System.Math.Abs(Vertices[count].X - left) - (Sector.TextureX << 4);
                }

                uv[count].X *= INV64;
                uv[count].Y *= INV64;

                // apply additional userscale
                p[count] *= Scale;
            }

            /*****************************************************************/

            // Calculate the normal
            if (slopeInfo != null)
            {
                // if the sector is sloped, we get the normal from slopeinfo
                normal.X = slopeInfo.A;
                normal.Y = slopeInfo.B;
                normal.Z = slopeInfo.C;

                normal.Normalize();
            }
            else if (IsFloor)
            {
                // default normal for non sloped floor
                normal.X = 0.0f;
                normal.Y = 0.0f;
                normal.Z = 1.0f;
            }
            else
            {
                // default normal for non sloped ceilings
                normal.X = 0.0f;
                normal.Y = 0.0f;
                normal.Z = -1.0f;
            }

            /*****************************************************************/

            // save in class properties depending on floor/ceiling
            if (IsFloor)
            {
                FloorP      = p;
                FloorUV     = uv;
                FloorNormal = normal;
            }
            else
            {
                CeilingP      = p;
                CeilingUV     = uv;
                CeilingNormal = normal;
            }
        }
Exemple #6
0
 /// <summary>
 /// Calculates the z coordinate of a point given by it's x,y components and 
 /// a plane equation in slopeinfo.
 /// </summary>
 /// <param name="SlopeInfo"></param>
 /// <param name="x"></param>
 /// <param name="y"></param>
 /// <returns>Height of the point in legacy client FINENESS (1:1024)</returns>
 public static Real CalculateSlopeHeight(RooSectorSlopeInfo SlopeInfo, Real x, Real y)
 {
     return (-SlopeInfo.A * x - SlopeInfo.B * y - SlopeInfo.D) / SlopeInfo.C;
 }
Exemple #7
0
        public unsafe void ReadFrom(ref byte* Buffer)
        {
            ServerID = *((short*)Buffer);
            Buffer += TypeSizes.SHORT;

            FloorTexture = *((ushort*)Buffer);
            Buffer += TypeSizes.SHORT;

            CeilingTexture = *((ushort*)Buffer);
            Buffer += TypeSizes.SHORT;

            TextureX = *((short*)Buffer);
            Buffer += TypeSizes.SHORT;

            TextureY = *((short*)Buffer);
            Buffer += TypeSizes.SHORT;

            FloorHeight = (Real)(*((short*)Buffer));
            Buffer += TypeSizes.SHORT;

            CeilingHeight = (Real)(*((short*)Buffer));
            Buffer += TypeSizes.SHORT;

            Light1 = Buffer[0];
            Buffer++;

            Flags = new RooSectorFlags(*((uint*)Buffer));
            Buffer += TypeSizes.INT;

            if (HasSpeed)
            {
                Speed = Buffer[0];
                Buffer++;
            }

            // Check for attached subinfo
            if (Flags.IsSlopedFloor)           
                SlopeInfoFloor = new RooSectorSlopeInfo(RooVersion, ref Buffer);
                           
            if (Flags.IsSlopedCeiling)
                SlopeInfoCeiling = new RooSectorSlopeInfo(RooVersion, ref Buffer);
        }
Exemple #8
0
        public int ReadFrom(byte[] Buffer, int StartIndex = 0)
        {
            int cursor = StartIndex;

            ServerID = BitConverter.ToInt16(Buffer, cursor);
            cursor += TypeSizes.SHORT;

            FloorTexture = BitConverter.ToUInt16(Buffer, cursor);
            cursor += TypeSizes.SHORT;

            CeilingTexture = BitConverter.ToUInt16(Buffer, cursor);
            cursor += TypeSizes.SHORT;

            TextureX = BitConverter.ToInt16(Buffer, cursor);
            cursor += TypeSizes.SHORT;

            TextureY = BitConverter.ToInt16(Buffer, cursor);
            cursor += TypeSizes.SHORT;

            FloorHeight = (Real)BitConverter.ToInt16(Buffer, cursor);
            cursor += TypeSizes.SHORT;

            CeilingHeight = (Real)BitConverter.ToInt16(Buffer, cursor);
            cursor += TypeSizes.SHORT;

            Light1 = Buffer[cursor];
            cursor++ ;

            Flags = new RooSectorFlags(BitConverter.ToUInt32(Buffer, cursor));
            cursor += TypeSizes.INT;

            if (HasSpeed)
            {
                Speed = Buffer[cursor];
                cursor++;
            }
            
            // Check for attached subinfo
            if (Flags.IsSlopedFloor)
            {
                SlopeInfoFloor = new RooSectorSlopeInfo(RooVersion, Buffer, cursor);
                cursor += SlopeInfoFloor.ByteLength;
            }
            if (Flags.IsSlopedCeiling)
            {
                SlopeInfoCeiling = new RooSectorSlopeInfo(RooVersion, Buffer, cursor);
                cursor += SlopeInfoCeiling.ByteLength;
            }

            return cursor - StartIndex;
        }