Exemplo n.º 1
0
        /// <summary>
        /// Sets a cell at the given cell coordinates.
        /// </summary>
        public void SetCell(int x, int y, int z, CellMaterial material, sbyte density)
        {
            Chunk chunk;
            var   coord = new Vector3int16(RoundDownDivide(x, ChunkSize), RoundDownDivide(y, ChunkSize),
                                           RoundDownDivide(z, ChunkSize));

            lock (Locker)
            {
                if (!_chunks.TryGetValue(coord, out chunk))
                {
                    chunk          = new Chunk(this, coord);
                    _chunks[coord] = chunk;
                }
            }

            chunk[
                Math.Abs(x % ChunkSize),
                Math.Abs(y % ChunkSize),
                Math.Abs(z % ChunkSize)] = new Cell(material, density);

            if (chunk.OccupiedCells == 0)
            {
                _chunks.TryRemove(coord);
            }
        }
Exemplo n.º 2
0
        private void GenerateVertex(ref Vector3int16 chunkPos, ref Vector3int16 cellPos, ref List <TerrainVertex> vertices,
                                    int lod, long t, ref byte v0, ref byte v1, ref sbyte d0, ref sbyte d1, ref Vector3 normal)
        {
            var p0 = (Vector3)(chunkPos + CornerIndex[v0] * lod);
            var p1 = (Vector3)(chunkPos + CornerIndex[v1] * lod);
            var q  = InterpolateVoxelVector(t, ref p0, ref p1);

            vertices.Add(new TerrainVertex(ref q, ref normal));
        }
Exemplo n.º 3
0
        public ReuseCell GetReusedIndex(Vector3int16 pos, byte rDir)
        {
            int rx = rDir & 0x01;
            int rz = (rDir >> 1) & 0x01;
            int ry = (rDir >> 2) & 0x01;

            int dx = pos.x - rx;
            int dy = pos.y - ry;
            int dz = pos.z - rz;

            Debug.Assert(dx >= 0 && dy >= 0 && dz >= 0);
            return(_cache[dx & 1][dy * chunkSize + dz]);
        }
        public void WriteProperty(Property prop, XmlDocument doc, XmlNode node)
        {
            Vector3int16 value = prop.CastValue <Vector3int16>();

            XmlElement x = doc.CreateElement("X");

            x.InnerText = value.X.ToString();
            node.AppendChild(x);

            XmlElement y = doc.CreateElement("Y");

            y.InnerText = value.Y.ToString();
            node.AppendChild(y);

            XmlElement z = doc.CreateElement("Z");

            z.InnerText = value.Z.ToString();
            node.AppendChild(z);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Returns the cell at the given cell coordinates.
        /// </summary>
        public Cell GetCell(int x, int y, int z)
        {
            Chunk chunk;
            var   coord = new Vector3int16(RoundDownDivide(x, ChunkSize), RoundDownDivide(y, ChunkSize),
                                           RoundDownDivide(z, ChunkSize));

            _chunks.TryGetValue(coord, out chunk);

            if (chunk == null)
            {
                return(default(Cell));
            }

            var cell = chunk[
                Math.Abs(x) % ChunkSize,
                Math.Abs(y) % ChunkSize,
                Math.Abs(z) % ChunkSize];

            return(cell);
        }
Exemplo n.º 6
0
        public void GenLodCell(Terrain.Chunk chunk, int lod, out TerrainVertex[] resultVertices,
                               out ushort[] resultIndices)
        {
            var vertices = new List <TerrainVertex>();
            var indices  = new List <ushort>();

            const short chunkSize = Terrain.ChunkSize;

            for (short x = 0; x < chunkSize; x++)
            {
                for (short y = 0; y < chunkSize; y++)
                {
                    for (short z = 0; z < chunkSize; z++)
                    {
                        var cellPos = new Vector3int16(x, y, z);
                        PolygonizeCell(chunk.Position, cellPos, ref vertices, ref indices, lod);
                    }
                }
            }

            resultVertices = vertices.ToArray();
            resultIndices  = indices.ToArray();
        }
Exemplo n.º 7
0
 public ReuseCell this[Vector3int16 v]
 {
     set { this[v.x, v.y, v.z] = value; }
 }
Exemplo n.º 8
0
        private void PolygonizeCell(Vector3int16 offsetPos, Vector3int16 pos, ref List <TerrainVertex> vertices,
                                    ref List <ushort> indices, int lod)
        {
            Debug.Assert(lod >= 1, "Level of Detail must be greater than 1");
            offsetPos *= Terrain.ChunkSize;
            offsetPos += pos * lod;

            byte directionMask = (byte)((pos.x > 0 ? 1 : 0) | ((pos.z > 0 ? 1 : 0) << 1) | ((pos.y > 0 ? 1 : 0) << 2));

            sbyte[] density = new sbyte[8];

            for (int i = 0; i < density.Length; i++)
            {
                density[i] = _volume[offsetPos + CornerIndex[i] * lod].Density;
            }

            byte caseCode = GetCaseCode(density);

            if ((caseCode ^ ((density[7] >> 7) & 0xFF)) == 0)             //for this cases there is no triangulation
            {
                return;
            }

            var cornerNormals = new Vector3[8];

            for (int i = 0; i < 8; i++)
            {
                var   p  = offsetPos + CornerIndex[i] * lod;
                float nx = (_volume.GetCell(p.x + 1, p.y, p.z).Density - _volume[p - Vector3int16.Right].Density) * 0.5f;
                float ny = (_volume[p + Vector3int16.Up].Density - _volume[p - Vector3int16.Up].Density) * 0.5f;
                float nz = (_volume[p + Vector3int16.Backward].Density - _volume[p - Vector3int16.Backward].Density) * 0.5f;

                cornerNormals[i].Set(nx, ny, nz);
                cornerNormals[i].Normalize();
            }

            byte regularCellClass = RegularCellClass[caseCode];

            ushort[] vertexLocations = RegularVertexData[caseCode];

            var  c             = RegularCellData[regularCellClass];
            long vertexCount   = c.GetVertexCount();
            long triangleCount = c.GetTriangleCount();

            byte[]   indexOffset   = c.Indices();                    //index offsets for current cell
            ushort[] mappedIndizes = new ushort[indexOffset.Length]; //array with real indizes for current cell

            for (int i = 0; i < vertexCount; i++)
            {
                byte edge       = (byte)(vertexLocations[i] >> 8);
                byte reuseIndex = (byte)(edge & 0xF);               //Vertex id which should be created or reused 1,2 or 3
                byte rDir       = (byte)(edge >> 4);                //the direction to go to reach a previous cell for reusing

                byte v1 = (byte)((vertexLocations[i]) & 0x0F);      //Second Corner Index
                byte v0 = (byte)((vertexLocations[i] >> 4) & 0x0F); //First Corner Index

                sbyte d0 = density[v0];
                sbyte d1 = density[v1];

                //Vector3f n0 = cornerNormals[v0];
                //Vector3f n1 = cornerNormals[v1];

                Debug.Assert(v1 > v0);

                int   t  = (d1 << 8) / (d1 - d0);
                int   u  = 0x0100 - t;
                float t0 = t / 256f;
                float t1 = u / 256f;

                int index = -1;

                if (UseCache && v1 != 7 && (rDir & directionMask) == rDir)
                {
                    Debug.Assert(reuseIndex != 0);
                    ReuseCell cell = _cache.GetReusedIndex(pos, rDir);
                    index = cell.Verts[reuseIndex];
                }

                if (index == -1)
                {
                    var normal = cornerNormals[v0] * t0 + cornerNormals[v1] * t1;
                    GenerateVertex(ref offsetPos, ref pos, ref vertices, lod, t, ref v0, ref v1, ref d0, ref d1, ref normal);
                    index = vertices.Count - 1;
                }

                if ((rDir & 8) != 0)
                {
                    _cache.SetReusableIndex(pos, reuseIndex, (ushort)(vertices.Count - 1));
                }

                mappedIndizes[i] = (ushort)index;
            }

            for (int t = 0; t < triangleCount; t++)
            {
                for (int i = 0; i < 3; i++)
                {
                    indices.Add(mappedIndizes[c.Indices()[t * 3 + i]]);
                }
            }
        }
Exemplo n.º 9
0
            public void Read(BinaryReader propReader)
            {
                var   encode = propReader.ReadInt32();
                short declaringTypeId;
                short propertyTag;

                DecodePropertyTag(encode, out declaringTypeId, out propertyTag);
                EncodeTag       = encode;
                DeclaringTypeId = declaringTypeId;
                PropertyTag     = propertyTag;

                CachedProperty cached;

                if (TypeRecord.Type.TaggedProperties.TryGetValue(encode, out cached))
                {
                    Name         = cached.Name;
                    Property     = cached;
                    PropertyType = cached.PropertyType;
                }

                DataType = (DataType)propReader.ReadByte();

                while (propReader.BaseStream.Position < propReader.BaseStream.Length)
                {
                    switch (DataType)
                    {
                    case DataType.String:
                        Data.Add(propReader.ReadString());
                        break;

                    case DataType.Content:
                        Data.Add(propReader.ReadString());
                        break;

                    case DataType.Boolean:
                        Data.Add(propReader.ReadBoolean());
                        break;

                    case DataType.Int16:
                        Data.Add(propReader.ReadInt16());
                        break;

                    case DataType.Int32:
                        Data.Add(propReader.ReadInt32());
                        break;

                    case DataType.Int64:
                        Data.Add(propReader.ReadInt64());
                        break;

                    case DataType.Single:
                        Data.Add(propReader.ReadSingle());
                        break;

                    case DataType.Double:
                        Data.Add(propReader.ReadDouble());
                        break;

                    case DataType.Enum:
                        Data.Add(propReader.ReadInt16());
                        break;

                    case DataType.FontFamily:
                        Data.Add(new FontFamily(propReader.ReadString()));
                        break;

                    case DataType.Referent:
                        var referent = propReader.ReadInt32();
                        Data.Add(referent == -1 ? Referent.Null : Context.GlobalReferents[referent]);
                        break;

                    case DataType.UserData:
                        if (VisualC.CompareMemory(propReader.ReadBytes(3), _nullChars, 3) == 0)
                        {
                            Data.Add(null);
                        }
                        else
                        {
                            propReader.BaseStream.Position -= 3;     // go back to start
                            var       id = propReader.ReadByte();
                            IDataType userData;

                            switch (id)
                            {
                            case 0:
                                userData = new Vector3();
                                break;

                            case 1:
                                userData = new Vector2();
                                break;

                            case 2:
                                userData = new Vector4();
                                break;

                            case 3:
                                userData = new Colour();
                                break;

                            case 4:
                                userData = new Axes();
                                break;

                            case 5:
                                userData = new CFrame();
                                break;

                            case 6:
                                userData = new UDim2();
                                break;

                            case 7:
                                userData = new ColourSequence();
                                break;

                            case 8:
                                userData = new NumberSequence();
                                break;

                            case 9:
                                userData = new NumberRange();
                                break;

                            case 10:
                                userData = new Faces();
                                break;

                            case 11:
                                userData = new Matrix3();
                                break;

                            case 12:
                                userData = new PhysicalProperties();
                                break;

                            case 13:
                                userData = new Plane();
                                break;

                            case 15:
                                userData = new Ray();
                                break;

                            case 16:
                                userData = new Region3();
                                break;

                            case 17:
                                userData = new Vector3int16();
                                break;

                            case 18:
                                userData = new Region3int16();
                                break;

                            case 19:
                                userData = new DateTime();
                                break;

                            case 20:
                                userData = new TimeSpan();
                                break;

                            case 21:
                                userData = new BinaryData();
                                break;

                            case 22:
                                userData = new MaterialNodeCollection();
                                break;

                            case 23:
                                userData = new InstanceId();
                                break;

                            case 24:
                                userData = new FontFamily();
                                break;

                            default:
                                throw new IndexOutOfRangeException($"No DataType with data ID \"{id}\" found.");
                            }

                            userData.Load(propReader);
                            Data.Add(userData);
                        }
                        break;

                    default:
                        throw new ArgumentOutOfRangeException();
                    }
                }
            }
Exemplo n.º 10
0
 internal Region3int16(Attribute attr)
 {
     Min = new Vector3int16(attr);
     Max = new Vector3int16(attr);
 }
Exemplo n.º 11
0
 internal Chunk(Terrain terrain, Vector3int16 coord)
 {
     _terrain = terrain;
     Position = coord;
     _cells   = new Cell[CellsPerChunk];
 }
Exemplo n.º 12
0
 private void SetCell(Vector3int16 cellPos, CellMaterial material, sbyte density)
 {
     SetCell(cellPos.x, cellPos.y, cellPos.z, material, density);
 }
Exemplo n.º 13
0
 internal Cell GetCell(Vector3int16 cellPos)
 {
     return(GetCell(cellPos.x, cellPos.y, cellPos.z));
 }
Exemplo n.º 14
0
 internal Cell this[Vector3int16 pos]
 {
     get { return(GetCell(pos)); }
     set { SetCell(pos, value.Material, value.Density); }
 }
Exemplo n.º 15
0
 internal void SetReusableIndex(Vector3int16 pos, byte reuseIndex, ushort p)
 {
     _cache[pos.x & 1][pos.y * chunkSize + pos.z].Verts[reuseIndex] = p;
 }
Exemplo n.º 16
0
        public void Save(BinaryRobloxFileWriter writer)
        {
            BinaryRobloxFile file = writer.File;

            File = file;

            INST inst  = file.Classes[ClassIndex];
            var  props = new List <Property>();

            foreach (int instId in inst.InstanceIds)
            {
                Instance instance  = file.Instances[instId];
                var      instProps = instance.Properties;

                if (!instProps.TryGetValue(Name, out Property prop))
                {
                    throw new Exception($"Property {Name} must be defined in {instance.GetFullName()}!");
                }
                else if (prop.Type != Type)
                {
                    throw new Exception($"Property {Name} is not using the correct type in {instance.GetFullName()}!");
                }

                props.Add(prop);
            }

            writer.Write(ClassIndex);
            writer.WriteString(Name);
            writer.Write(TypeId);

            switch (Type)
            {
            case PropertyType.String:
                props.ForEach(prop =>
                {
                    byte[] buffer = prop.HasRawBuffer ? prop.RawBuffer : null;

                    if (buffer == null)
                    {
                        string value = prop.CastValue <string>();
                        buffer       = Encoding.UTF8.GetBytes(value);
                    }

                    writer.Write(buffer.Length);
                    writer.Write(buffer);
                });

                break;

            case PropertyType.Bool:
            {
                props.ForEach(prop =>
                    {
                        bool value = prop.CastValue <bool>();
                        writer.Write(value);
                    });

                break;
            }

            case PropertyType.Int:
            {
                var ints = props
                           .Select(prop => prop.CastValue <int>())
                           .ToList();

                writer.WriteInts(ints);
                break;
            }

            case PropertyType.Float:
            {
                var floats = props
                             .Select(prop => prop.CastValue <float>())
                             .ToList();

                writer.WriteFloats(floats);
                break;
            }

            case PropertyType.Double:
            {
                props.ForEach(prop =>
                    {
                        double value = prop.CastValue <double>();
                        writer.Write(BinaryRobloxFileWriter.GetBytes(value));
                    });

                break;
            }

            case PropertyType.UDim:
            {
                var UDim_Scales  = new List <float>();
                var UDim_Offsets = new List <int>();

                props.ForEach(prop =>
                    {
                        UDim value = prop.CastValue <UDim>();
                        UDim_Scales.Add(value.Scale);
                        UDim_Offsets.Add(value.Offset);
                    });

                writer.WriteFloats(UDim_Scales);
                writer.WriteInts(UDim_Offsets);

                break;
            }

            case PropertyType.UDim2:
            {
                var UDim2_Scales_X = new List <float>();
                var UDim2_Scales_Y = new List <float>();

                var UDim2_Offsets_X = new List <int>();
                var UDim2_Offsets_Y = new List <int>();

                props.ForEach(prop =>
                    {
                        UDim2 value = prop.CastValue <UDim2>();

                        UDim2_Scales_X.Add(value.X.Scale);
                        UDim2_Scales_Y.Add(value.Y.Scale);

                        UDim2_Offsets_X.Add(value.X.Offset);
                        UDim2_Offsets_Y.Add(value.Y.Offset);
                    });

                writer.WriteFloats(UDim2_Scales_X);
                writer.WriteFloats(UDim2_Scales_Y);

                writer.WriteInts(UDim2_Offsets_X);
                writer.WriteInts(UDim2_Offsets_Y);

                break;
            }

            case PropertyType.Ray:
            {
                props.ForEach(prop =>
                    {
                        Ray ray = prop.CastValue <Ray>();

                        Vector3 pos = ray.Origin;
                        writer.Write(pos.X);
                        writer.Write(pos.Y);
                        writer.Write(pos.Z);

                        Vector3 dir = ray.Direction;
                        writer.Write(dir.X);
                        writer.Write(dir.Y);
                        writer.Write(dir.Z);
                    });

                break;
            }

            case PropertyType.Faces:
            case PropertyType.Axes:
            {
                props.ForEach(prop =>
                    {
                        byte value = prop.CastValue <byte>();
                        writer.Write(value);
                    });

                break;
            }

            case PropertyType.BrickColor:
            {
                var brickColorIds = props
                                    .Select(prop => prop.CastValue <BrickColor>())
                                    .Select(value => value.Number)
                                    .ToList();

                writer.WriteInts(brickColorIds);
                break;
            }

            case PropertyType.Color3:
            {
                var Color3_R = new List <float>();
                var Color3_G = new List <float>();
                var Color3_B = new List <float>();

                props.ForEach(prop =>
                    {
                        Color3 value = prop.CastValue <Color3>();
                        Color3_R.Add(value.R);
                        Color3_G.Add(value.G);
                        Color3_B.Add(value.B);
                    });

                writer.WriteFloats(Color3_R);
                writer.WriteFloats(Color3_G);
                writer.WriteFloats(Color3_B);

                break;
            }

            case PropertyType.Vector2:
            {
                var Vector2_X = new List <float>();
                var Vector2_Y = new List <float>();

                props.ForEach(prop =>
                    {
                        Vector2 value = prop.CastValue <Vector2>();
                        Vector2_X.Add(value.X);
                        Vector2_Y.Add(value.Y);
                    });

                writer.WriteFloats(Vector2_X);
                writer.WriteFloats(Vector2_Y);

                break;
            }

            case PropertyType.Vector3:
            {
                var Vector3_X = new List <float>();
                var Vector3_Y = new List <float>();
                var Vector3_Z = new List <float>();

                props.ForEach(prop =>
                    {
                        Vector3 value = prop.CastValue <Vector3>();
                        Vector3_X.Add(value.X);
                        Vector3_Y.Add(value.Y);
                        Vector3_Z.Add(value.Z);
                    });

                writer.WriteFloats(Vector3_X);
                writer.WriteFloats(Vector3_Y);
                writer.WriteFloats(Vector3_Z);

                break;
            }

            case PropertyType.CFrame:
            case PropertyType.Quaternion:
            case PropertyType.OptionalCFrame:
            {
                var CFrame_X = new List <float>();
                var CFrame_Y = new List <float>();
                var CFrame_Z = new List <float>();

                if (Type == PropertyType.OptionalCFrame)
                {
                    writer.Write((byte)PropertyType.CFrame);
                }

                props.ForEach(prop =>
                    {
                        CFrame value = null;

                        if (prop.Value is Quaternion q)
                        {
                            value = q.ToCFrame();
                        }
                        else
                        {
                            value = prop.CastValue <CFrame>();
                        }

                        if (value == null)
                        {
                            value = new CFrame();
                        }

                        Vector3 pos = value.Position;
                        CFrame_X.Add(pos.X);
                        CFrame_Y.Add(pos.Y);
                        CFrame_Z.Add(pos.Z);

                        int orientId = value.GetOrientId();
                        writer.Write((byte)(orientId + 1));

                        if (orientId == -1)
                        {
                            if (Type == PropertyType.Quaternion)
                            {
                                Quaternion quat = new Quaternion(value);
                                writer.Write(quat.X);
                                writer.Write(quat.Y);
                                writer.Write(quat.Z);
                                writer.Write(quat.W);
                            }
                            else
                            {
                                float[] components = value.GetComponents();

                                for (int i = 3; i < 12; i++)
                                {
                                    float component = components[i];
                                    writer.Write(component);
                                }
                            }
                        }
                    });

                writer.WriteFloats(CFrame_X);
                writer.WriteFloats(CFrame_Y);
                writer.WriteFloats(CFrame_Z);

                if (Type == PropertyType.OptionalCFrame)
                {
                    writer.Write((byte)PropertyType.Bool);

                    props.ForEach(prop =>
                        {
                            if (prop.Value is null)
                            {
                                writer.Write(false);
                                return;
                            }

                            if (prop.Value is Optional <CFrame> optional)
                            {
                                writer.Write(optional.HasValue);
                                return;
                            }

                            var cf = prop.Value as CFrame;
                            writer.Write(cf != null);
                        });
                }

                break;
            }

            case PropertyType.Enum:
            {
                var enums = new List <uint>();

                props.ForEach(prop =>
                    {
                        if (prop.Value is uint raw)
                        {
                            enums.Add(raw);
                            return;
                        }

                        int signed = (int)prop.Value;
                        uint value = (uint)signed;

                        enums.Add(value);
                    });

                writer.WriteInterleaved(enums);
                break;
            }

            case PropertyType.Ref:
            {
                var InstanceIds = new List <int>();

                props.ForEach(prop =>
                    {
                        int referent = -1;

                        if (prop.Value != null)
                        {
                            Instance value = prop.CastValue <Instance>();

                            if (value.IsDescendantOf(File))
                            {
                                string refValue = value.Referent;
                                int.TryParse(refValue, out referent);
                            }
                        }

                        InstanceIds.Add(referent);
                    });

                writer.WriteInstanceIds(InstanceIds);
                break;
            }

            case PropertyType.Vector3int16:
            {
                props.ForEach(prop =>
                    {
                        Vector3int16 value = prop.CastValue <Vector3int16>();
                        writer.Write(value.X);
                        writer.Write(value.Y);
                        writer.Write(value.Z);
                    });

                break;
            }

            case PropertyType.NumberSequence:
            {
                props.ForEach(prop =>
                    {
                        NumberSequence value = prop.CastValue <NumberSequence>();

                        var keyPoints = value.Keypoints;
                        writer.Write(keyPoints.Length);

                        foreach (var keyPoint in keyPoints)
                        {
                            writer.Write(keyPoint.Time);
                            writer.Write(keyPoint.Value);
                            writer.Write(keyPoint.Envelope);
                        }
                    });

                break;
            }

            case PropertyType.ColorSequence:
            {
                props.ForEach(prop =>
                    {
                        ColorSequence value = prop.CastValue <ColorSequence>();

                        var keyPoints = value.Keypoints;
                        writer.Write(keyPoints.Length);

                        foreach (var keyPoint in keyPoints)
                        {
                            Color3 color = keyPoint.Value;
                            writer.Write(keyPoint.Time);

                            writer.Write(color.R);
                            writer.Write(color.G);
                            writer.Write(color.B);

                            writer.Write(keyPoint.Envelope);
                        }
                    });

                break;
            }

            case PropertyType.NumberRange:
            {
                props.ForEach(prop =>
                    {
                        NumberRange value = prop.CastValue <NumberRange>();
                        writer.Write(value.Min);
                        writer.Write(value.Max);
                    });

                break;
            }

            case PropertyType.Rect:
            {
                var Rect_X0 = new List <float>();
                var Rect_Y0 = new List <float>();

                var Rect_X1 = new List <float>();
                var Rect_Y1 = new List <float>();

                props.ForEach(prop =>
                    {
                        Rect value = prop.CastValue <Rect>();

                        Vector2 min = value.Min;
                        Rect_X0.Add(min.X);
                        Rect_Y0.Add(min.Y);

                        Vector2 max = value.Max;
                        Rect_X1.Add(max.X);
                        Rect_Y1.Add(max.Y);
                    });

                writer.WriteFloats(Rect_X0);
                writer.WriteFloats(Rect_Y0);

                writer.WriteFloats(Rect_X1);
                writer.WriteFloats(Rect_Y1);

                break;
            }

            case PropertyType.PhysicalProperties:
            {
                props.ForEach(prop =>
                    {
                        bool custom = (prop.Value != null);
                        writer.Write(custom);

                        if (custom)
                        {
                            PhysicalProperties value = prop.CastValue <PhysicalProperties>();

                            writer.Write(value.Density);
                            writer.Write(value.Friction);
                            writer.Write(value.Elasticity);

                            writer.Write(value.FrictionWeight);
                            writer.Write(value.ElasticityWeight);
                        }
                    });

                break;
            }

            case PropertyType.Color3uint8:
            {
                var Color3uint8_R = new List <byte>();
                var Color3uint8_G = new List <byte>();
                var Color3uint8_B = new List <byte>();

                props.ForEach(prop =>
                    {
                        Color3uint8 value = prop.CastValue <Color3uint8>();
                        Color3uint8_R.Add(value.R);
                        Color3uint8_G.Add(value.G);
                        Color3uint8_B.Add(value.B);
                    });

                byte[] rBuffer = Color3uint8_R.ToArray();
                writer.Write(rBuffer);

                byte[] gBuffer = Color3uint8_G.ToArray();
                writer.Write(gBuffer);

                byte[] bBuffer = Color3uint8_B.ToArray();
                writer.Write(bBuffer);

                break;
            }

            case PropertyType.Int64:
            {
                var longs = new List <long>();

                props.ForEach(prop =>
                    {
                        long value = prop.CastValue <long>();
                        longs.Add(value);
                    });

                writer.WriteInterleaved(longs, value =>
                    {
                        // Move the sign bit to the front.
                        return((value << 1) ^ (value >> 63));
                    });

                break;
            }

            case PropertyType.SharedString:
            {
                var  sharedKeys = new List <uint>();
                SSTR sstr       = file.SSTR;

                if (sstr == null)
                {
                    sstr      = new SSTR();
                    file.SSTR = sstr;
                }

                props.ForEach(prop =>
                    {
                        var shared = prop.CastValue <SharedString>();

                        if (shared == null)
                        {
                            byte[] empty = Array.Empty <byte>();
                            shared       = SharedString.FromBuffer(empty);
                        }

                        string key = shared.Key;

                        if (!sstr.Lookup.ContainsKey(key))
                        {
                            uint id = (uint)sstr.Lookup.Count;
                            sstr.Strings.Add(id, shared);
                            sstr.Lookup.Add(key, id);
                        }

                        uint hashId = sstr.Lookup[key];
                        sharedKeys.Add(hashId);
                    });

                writer.WriteInterleaved(sharedKeys);
                break;
            }

            case PropertyType.ProtectedString:
            {
                props.ForEach(prop =>
                    {
                        var protect   = prop.CastValue <ProtectedString>();
                        byte[] buffer = protect.RawBuffer;

                        writer.Write(buffer.Length);
                        writer.Write(buffer);
                    });

                break;
            }

            case PropertyType.UniqueId:
            {
                props.ForEach(prop =>
                    {
                        var guid      = prop.CastValue <Guid>();
                        byte[] buffer = guid.ToByteArray();
                        writer.Write(buffer);
                    });

                break;
            }

            default:
            {
                RobloxFile.LogError($"Unhandled property type: {Type} in {this}!");
                break;
            }
            }
        }
Exemplo n.º 17
0
 internal Cell this[Vector3int16 index]
 {
     get { return(this[index.x, index.y, index.z]); }
     set { this[index.x, index.y, index.z] = value; }
 }
Exemplo n.º 18
0
 public Region3int16(Vector3int16 min = null, Vector3int16 max = null)
 {
     Min = min ?? new Vector3int16();
     Max = max ?? new Vector3int16();
 }
Exemplo n.º 19
0
 public Region3int16(Vector3int16 min, Vector3int16 max)
 {
     Min = min;
     Max = max;
 }