示例#1
0
        public static MeshGpuInstancing WithInstanceCustomAccessor(this MeshGpuInstancing instancing, string attribute, IReadOnlyList <Object> values)
        {
            Guard.NotNullOrEmpty(attribute, nameof(attribute));

            attribute = attribute.ToUpperInvariant();
            var expectedType = values.Where(item => item != null).FirstOrDefault()?.GetType();

            if (expectedType == null)
            {
                return(instancing);
            }

            if (expectedType == typeof(int))
            {
                var xValues = values.Select(item => item is int val ? val : 0).ToList();
                return(instancing.WithInstanceAccessor(attribute, xValues));
            }

            if (expectedType == typeof(Single))
            {
                var xValues = values.Select(item => item is float val ? val : 0).ToList();
                return(instancing.WithInstanceAccessor(attribute, xValues));
            }

            throw new ArgumentException(expectedType.Name);
        }
示例#2
0
        public static MeshGpuInstancing WithInstanceAccessors(this MeshGpuInstancing instancing, IReadOnlyList <Transforms.AffineTransform> transforms)
        {
            Guard.NotNull(instancing, nameof(instancing));
            Guard.NotNull(transforms, nameof(transforms));

            var xfrms = transforms.Select(item => item.GetDecomposed());
            var hasS  = xfrms.Any(item => item.Scale != Vector3.One);
            var hasR  = xfrms.Any(item => item.Rotation != Quaternion.Identity);
            var hasT  = xfrms.Any(item => item.Translation != Vector3.Zero);

            if (hasS)
            {
                instancing.WithInstanceAccessor("SCALE", xfrms.Select(item => item.Scale).ToList());
            }
            if (hasR)
            {
                instancing.WithInstanceAccessor("ROTATION", xfrms.Select(item => item.Rotation).ToList());
            }
            if (hasT)
            {
                instancing.WithInstanceAccessor("TRANSLATION", xfrms.Select(item => item.Translation).ToList());
            }

            return(instancing);
        }
示例#3
0
        public static MeshGpuInstancing WithInstanceCustomAccessors(this MeshGpuInstancing instancing, IReadOnlyList <IO.JsonContent> extras)
        {
            Guard.NotNull(instancing, nameof(instancing));

            // gather attribute keys
            var keys = extras
                       .Select(item => item.Content)
                       .OfType <IReadOnlyDictionary <string, Object> >()
                       .SelectMany(item => item.Keys)
                       .Distinct()
                       .Where(item => item.StartsWith("_", StringComparison.Ordinal));

            foreach (var key in keys)
            {
                Object valueGetter(IO.JsonContent extra)
                {
                    if (!(extra.Content is IReadOnlyDictionary <string, Object> dict))
                    {
                        return(null);
                    }
                    return(dict.TryGetValue(key, out var val) ? val : null);
                }

                var values = extras.Select(valueGetter).ToList();

                instancing.WithInstanceCustomAccessor(key, values);
            }

            return(instancing);
        }
示例#4
0
        public static unsafe MeshGpuInstancing WithInstanceAccessor <T>(this MeshGpuInstancing instancing, string attribute, IReadOnlyList <T> values)
            where T : unmanaged
        {
            Guard.NotNull(instancing, nameof(instancing));
            Guard.NotNull(values, nameof(values));

            var root = instancing.LogicalParent.LogicalParent;
            var view = root.CreateBufferView(values);

            var accessor = root.CreateAccessor();

            if (typeof(T) == typeof(int))
            {
                accessor.SetIndexData(view, 0, values.Count, IndexEncodingType.UNSIGNED_INT);
            }
            else
            {
                var dt = DimensionType.CUSTOM;
                if (typeof(T) == typeof(Single))
                {
                    dt = DimensionType.SCALAR;
                }
                if (typeof(T) == typeof(Vector2))
                {
                    dt = DimensionType.VEC2;
                }
                if (typeof(T) == typeof(Vector3))
                {
                    dt = DimensionType.VEC3;
                }
                if (typeof(T) == typeof(Vector4))
                {
                    dt = DimensionType.VEC4;
                }
                if (typeof(T) == typeof(Quaternion))
                {
                    dt = DimensionType.VEC4;
                }
                if (typeof(T) == typeof(Matrix4x4))
                {
                    dt = DimensionType.MAT4;
                }

                if (dt == DimensionType.CUSTOM)
                {
                    throw new ArgumentException(typeof(T).Name);
                }

                accessor.SetVertexData(view, 0, values.Count, dt, EncodingType.FLOAT, false);
            }

            instancing.SetAccessor(attribute, accessor);

            return(instancing);
        }
        public MeshGpuInstancing UseGpuInstancing()
        {
            var ext = GetGpuInstancing();

            if (ext == null)
            {
                ext = new MeshGpuInstancing(this);
                this.SetExtension(ext);
            }

            return(ext);
        }