public override void OnImportAsset(AssetImportContext ctx)
        {
            try {
                PCache pcache = PCache.FromFile(ctx.assetPath);

                PointCacheAsset cache = ScriptableObject.CreateInstance <PointCacheAsset>();
                cache.name = "PointCache";
                ctx.AddObjectToAsset("PointCache", cache);
                ctx.SetMainObject(cache);

                List <InProperty> inProperties = new List <InProperty>();
                Dictionary <string, OutProperty>    outProperties = new Dictionary <string, OutProperty>();
                Dictionary <OutProperty, Texture2D> surfaces      = new Dictionary <OutProperty, Texture2D>();

                foreach (var prop in pcache.properties)
                {
                    OutProperty p_out;
                    if (outProperties.ContainsKey(prop.ComponentName))
                    {
                        p_out      = outProperties[prop.ComponentName];
                        p_out.Size = Math.Max(p_out.Size, prop.ComponentIndex + 1);
                    }
                    else
                    {
                        p_out = new OutProperty(prop.Type, prop.ComponentName, prop.ComponentIndex + 1);
                        outProperties.Add(prop.ComponentName, p_out);
                    }

                    inProperties.Add(new InProperty(prop.Type, prop.Name, prop.ComponentIndex, p_out));
                }


                int width, height;
                FindBestSize(pcache.elementCount, out width, out height);

                // Output Surface Creation
                foreach (var kvp in outProperties)
                {
                    TextureFormat surfaceFormat = TextureFormat.Alpha8;
                    switch (kvp.Value.PropertyType)
                    {
                    case "byte":
                        if (kvp.Value.Size == 1)
                        {
                            surfaceFormat = TextureFormat.Alpha8;
                        }
                        else
                        {
                            surfaceFormat = TextureFormat.RGBA32;
                        }
                        break;

                    case "float":
                        if (kvp.Value.Size == 1)
                        {
                            surfaceFormat = TextureFormat.RHalf;
                        }
                        else
                        {
                            surfaceFormat = TextureFormat.RGBAHalf;
                        }
                        break;

                    default: throw new NotImplementedException("Types other than byte/float are not supported yet");
                    }

                    Texture2D surface = new Texture2D(width, height, surfaceFormat, false);
                    surface.name = kvp.Key;
                    surfaces.Add(kvp.Value, surface);
                }

                cache.PointCount = pcache.elementCount;
                cache.surfaces   = new Texture2D[surfaces.Count];

                Dictionary <OutProperty, Color> outValues = new Dictionary <OutProperty, Color>();
                foreach (var kvp in outProperties)
                {
                    outValues.Add(kvp.Value, new Color());
                }

                for (int i = 0; i < pcache.elementCount; i++)
                {
                    int idx = 0;
                    foreach (var prop in inProperties)
                    {
                        float val = 0.0f;
                        switch (prop.PropertyType)
                        {
                        case "byte":
                            val = Mathf.Clamp01(((int)pcache.buckets[idx][i]) / 256.0f);
                            break;

                        case "float":
                            val = ((float)pcache.buckets[idx][i]);
                            break;

                        default: throw new NotImplementedException("Types other than byte/float are not supported yet");
                        }

                        SetPropValue(prop.Index, outValues, prop.OutProperty, val);
                        idx++;
                    }
                    foreach (var kvp in outProperties)
                    {
                        surfaces[kvp.Value].SetPixel(i % width, i / width, outValues[kvp.Value]);
                    }
                }

                int k = 0;

                foreach (var kvp in surfaces)
                {
                    kvp.Value.Apply();
                    kvp.Value.hideFlags = HideFlags.HideInHierarchy;
                    ctx.AddObjectToAsset(kvp.Key.Name, kvp.Value);
                    cache.surfaces[k] = kvp.Value;
                    k++;
                }
            }
            catch (System.Exception e) {
                Debug.LogException(e);
            }
        }
Exemple #2
0
        public static PCache FromFile(string filename)
        {
            PCache data = new PCache();

            Stream        s = File.OpenRead(filename);
            List <string> header;
            long          offset;

            GetHeader(s, out offset, out header);

            if (header[0] != "pcache")
            {
                throw new Exception("Invalid header : missing magic number");
            }

            Format format = (Format)int.MaxValue;

            data.elementCount = 0;

            data.properties = new List <PropertyDesc>();


            foreach (string line in header)
            {
                var words = line.Split(' ');
                switch (words[0].ToLower())
                {
                case "comment": //do nothing
                    break;

                case "format":
                    if (words.Length != 3)
                    {
                        throw new Exception("Invalid format description :" + line);
                    }
                    switch (words[1])
                    {
                    case "ascii": format = Format.Ascii; break;

                    case "binary": format = Format.Binary; break;

                    default: throw new Exception("Invalid Format :" + words[1]);
                    }
                    break;

                case "elements":
                    if (words.Length != 2)
                    {
                        throw new Exception("Invalid element description  :" + line);
                    }
                    if (!int.TryParse(words[1], out data.elementCount))
                    {
                        throw new Exception("Invalid element count :" + words[1]);
                    }
                    break;

                case "property":
                    if (words.Length != 3)
                    {
                        throw new Exception("Invalid property description :" + line);
                    }
                    string property  = words[2];
                    string component = GetComponentName(property);
                    int    idx       = GetComponentIndex(property);
                    string type      = words[1];
                    int    stride    = GetPropertySize(type);
                    if (stride == 0)
                    {
                        throw new Exception("Invalid Type for " + property + " property : " + type);
                    }

                    PropertyDesc prop = new PropertyDesc()
                    {
                        Name           = property,
                        Type           = type,
                        ComponentName  = component,
                        ComponentIndex = idx,
                        Stride         = stride
                    };
                    data.properties.Add(prop);
                    break;

                case "end_header":
                    if (words.Length != 1)
                    {
                        throw new Exception("Invalid end_header description :" + line);
                    }
                    break;
                }
            }

            data.buckets = new List <List <object> >();

            foreach (var property in data.properties)
            {
                data.buckets.Add(new List <object>(data.elementCount));
            }

            if (format == Format.Binary)
            {
                s.Close(); // End Header, goto binary mode
                s = File.OpenRead(filename);
                BinaryReader b = new BinaryReader(s);
                s.Seek(offset, SeekOrigin.Begin);

                for (int i = 0; i < data.elementCount; i++)
                {
                    for (int j = 0; j < data.properties.Count; j++)
                    {
                        var prop = data.properties[j];
                        switch (prop.Type)
                        {
                        case "short": data.buckets[j].Add(b.ReadInt16()); break;

                        case "ushort": data.buckets[j].Add(b.ReadUInt16()); break;

                        case "int": data.buckets[j].Add(b.ReadInt32()); break;

                        case "uint": data.buckets[j].Add(b.ReadUInt32()); break;

                        case "byte": data.buckets[j].Add(b.ReadChar()); break;

                        case "float": data.buckets[j].Add(b.ReadSingle()); break;

                        case "double": data.buckets[j].Add(b.ReadDouble()); break;
                        }
                    }
                }
            }
            else if (format == Format.Ascii)
            {
                s.Close(); // End Header, goto ascii mode
                s = File.OpenRead(filename);
                StreamReader reader = new StreamReader(s);
                s.Seek(offset, SeekOrigin.Begin);

                string[] lines = reader.ReadToEnd().Replace("\r", "").Split(new char[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

                if (lines.Length != data.elementCount)
                {
                    throw new InvalidOperationException(string.Format("Bad item amount, {0} expected in header, found {1}", data.elementCount, lines.Length));
                }

                for (int i = 0; i < data.elementCount; i++)
                {
                    string   line     = lines[i];
                    string[] elements = line.Split(' ');

                    for (int j = 0; j < data.properties.Count; j++)
                    {
                        var prop = data.properties[j];
                        switch (prop.Type)
                        {
                        case "short": data.buckets[j].Add(short.Parse(elements[j], CultureInfo.InvariantCulture)); break;

                        case "ushort": data.buckets[j].Add(ushort.Parse(elements[j], CultureInfo.InvariantCulture)); break;

                        case "int": data.buckets[j].Add(int.Parse(elements[j], CultureInfo.InvariantCulture)); break;

                        case "uint": data.buckets[j].Add(uint.Parse(elements[j], CultureInfo.InvariantCulture)); break;

                        case "byte": data.buckets[j].Add(byte.Parse(elements[j], CultureInfo.InvariantCulture)); break;

                        case "float": data.buckets[j].Add(float.Parse(elements[j], CultureInfo.InvariantCulture)); break;

                        case "double": data.buckets[j].Add(double.Parse(elements[j], CultureInfo.InvariantCulture)); break;
                        }
                    }
                }
            }
            return(data);
        }