Пример #1
0
        public static void LoadCommonParams(this Material self, VrmProtobuf.Material material, List <Texture> textures)
        {
            var pbr = material.PbrMetallicRoughness;

            if (pbr.BaseColorFactor.Count > 0)
            {
                self.BaseColorFactor = LinearColor.FromLiner(
                    pbr.BaseColorFactor[0],
                    pbr.BaseColorFactor[1],
                    pbr.BaseColorFactor[2],
                    pbr.BaseColorFactor[3]);
            }
            var baseColorTexture = pbr.BaseColorTexture;

            if (baseColorTexture != null && baseColorTexture.Index.TryGetValidIndex(textures.Count, out int index))
            {
                self.BaseColorTexture = new TextureInfo(textures[index]);
            }

            self.AlphaMode   = EnumUtil.Cast <VrmLib.AlphaModeType>(material.AlphaMode);
            self.AlphaCutoff = material.AlphaCutoff.HasValue
                ? material.AlphaCutoff.Value
                : 0.5f // gltf default
            ;
            self.DoubleSided = material.DoubleSided.HasValue
                ? material.DoubleSided.Value
                : false // gltf default
            ;
        }
Пример #2
0
        public static UniGLTF.Extensions.VRMC_vrm.Expression ToGltf(this VrmLib.Expression x, List <VrmLib.Node> nodes, List <VrmLib.Material> materials)
        {
            var g = new UniGLTF.Extensions.VRMC_vrm.Expression
            {
                Preset         = (UniGLTF.Extensions.VRMC_vrm.ExpressionPreset)x.Preset,
                Name           = x.Name,
                IsBinary       = x.IsBinary,
                OverrideBlink  = EnumUtil.Cast <UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType>(x.OverrideBlink),
                OverrideLookAt = EnumUtil.Cast <UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType>(x.OverrideLookAt),
                OverrideMouth  = EnumUtil.Cast <UniGLTF.Extensions.VRMC_vrm.ExpressionOverrideType>(x.OverrideMouth),
            };

            foreach (var blendShapeBind in x.MorphTargetBinds)
            {
                g.MorphTargetBinds.Add(blendShapeBind.ToGltf(nodes));
            }
            foreach (var materialColorBind in x.MaterialColorBinds)
            {
                g.MaterialColorBinds.Add(materialColorBind.ToGltf(materials));
            }
            foreach (var materialUVBind in x.TextureTransformBinds)
            {
                g.TextureTransformBinds.Add(materialUVBind.ToGltf(materials));
            }
            return(g);
        }
Пример #3
0
        public static UniGLTF.Extensions.VRMC_vrm.MaterialColorBind ToGltf(this MaterialColorBind self, List <VrmLib.Material> materials)
        {
            var m = new UniGLTF.Extensions.VRMC_vrm.MaterialColorBind
            {
                Material    = materials.IndexOfThrow(self.Material),
                Type        = EnumUtil.Cast <UniGLTF.Extensions.VRMC_vrm.MaterialColorType>(self.BindType),
                TargetValue = self.Property.Value.ToFloat4()
            };

            return(m);
        }
Пример #4
0
        public BufferAccessor CreateAccessor(int accessorIndex)
        {
            if (accessorIndex < 0)
            {
                return(null);
            }
            var accessor   = Gltf.Accessors[accessorIndex];
            var bytes      = GetAccessorBytes(accessorIndex);
            var vectorType = EnumUtil.Cast <AccessorVectorType>(accessor.Type);

            return(new BufferAccessor(bytes,
                                      (AccessorValueType)accessor.ComponentType, vectorType, accessor.Count.Value));
        }
Пример #5
0
 public static AvatarPermission ToAvaterPermission(this VrmProtobuf.Meta self)
 {
     return(new AvatarPermission
     {
         AvatarUsage = EnumUtil.Cast <AvatarUsageType>(self.AvatarPermission),
         IsAllowedViolentUsage = self.ViolentUsage.Value,
         IsAllowedSexualUsage = self.SexualUsage.Value,
         CommercialUsage = EnumUtil.Cast <CommercialUsageType>(self.CommercialUsage),
         OtherPermissionUrl = self.OtherPermissionUrl,
         IsAllowedGameUsage = self.GameUsage.Value,
         IsAllowedPoliticalOrReligiousUsage = self.PoliticalOrReligiousUsage.Value,
     });
 }
Пример #6
0
        public static VrmProtobuf.MaterialValue ToGltf(this MaterialBindValue self, List <VrmLib.Material> materials)
        {
            var m = new VrmProtobuf.MaterialValue
            {
                Material = materials.IndexOfThrow(self.Material),
                Type     = EnumUtil.Cast <VrmProtobuf.MaterialValue.Types.MaterialValueType>(self.BindType),
            };
            var kv = self.Property;

            m.TargetValue.Add(kv.Value.X);
            m.TargetValue.Add(kv.Value.Y);
            m.TargetValue.Add(kv.Value.Z);
            m.TargetValue.Add(kv.Value.W);
            return(m);
        }
Пример #7
0
 static VrmProtobuf.Accessor CreateGltfAccessor(this BufferAccessor self,
                                                int viewIndex, int count = 0, int byteOffset = 0)
 {
     if (count == 0)
     {
         count = self.Count;
     }
     return(new VrmProtobuf.Accessor
     {
         BufferView = viewIndex,
         ByteOffset = byteOffset,
         ComponentType = (int)self.ComponentType,
         Type = EnumUtil.Cast <VrmProtobuf.Accessor.Types.accessorType>(self.AccessorType),
         Count = count,
     });
 }
Пример #8
0
        public static VrmLib.Expression FromGltf(this UniGLTF.Extensions.VRMC_vrm.Expression x, List <VrmLib.Node> nodes, List <VrmLib.Material> materials)
        {
            var expression = new VrmLib.Expression((VrmLib.ExpressionPreset)x.Preset,
                                                   x.Name,
                                                   x.IsBinary.HasValue && x.IsBinary.Value)
            {
                IgnoreBlink  = x.IgnoreBlink.GetValueOrDefault(),
                IgnoreLookAt = x.IgnoreLookAt.GetValueOrDefault(),
                IgnoreMouth  = x.IgnoreMouth.GetValueOrDefault(),
            };

            if (x.MorphTargetBinds != null)
            {
                foreach (var y in x.MorphTargetBinds)
                {
                    var node           = nodes[y.Node.Value];
                    var blendShapeName = node.Mesh.MorphTargets[y.Index.Value].Name;
                    var blendShapeBind = new MorphTargetBind(node, blendShapeName, y.Weight.Value);
                    expression.MorphTargetBinds.Add(blendShapeBind);
                }
            }

            if (x.MaterialColorBinds != null)
            {
                foreach (var y in x.MaterialColorBinds)
                {
                    var material          = materials[y.Material.Value];
                    var materialColorBind = new MaterialColorBind(material, EnumUtil.Cast <MaterialBindType>(y.Type), y.TargetValue.ToVector4(Vector4.Zero));
                    expression.MaterialColorBinds.Add(materialColorBind);
                }
            }

            if (x.TextureTransformBinds != null)
            {
                foreach (var y in x.TextureTransformBinds)
                {
                    var material       = materials[y.Material.Value];
                    var materialUVBind = new TextureTransformBind(material,
                                                                  y.Scaling.ToVector2(Vector2.One),
                                                                  y.Offset.ToVector2(Vector2.Zero));
                    expression.TextureTransformBinds.Add(materialUVBind);
                }
            }

            return(expression);
        }
Пример #9
0
        public static VrmProtobuf.FirstPerson ToGltf(this FirstPerson self, List <Node> nodes)
        {
            if (self == null)
            {
                return(null);
            }

            var firstPerson = new VrmProtobuf.FirstPerson
            {
            };

            foreach (var x in self.Annotations)
            {
                firstPerson.MeshAnnotations.Add(new VrmProtobuf.MeshAnnotation
                {
                    Node            = nodes.IndexOfThrow(x.Node),
                    FirstPersonType = EnumUtil.Cast <VrmProtobuf.MeshAnnotation.Types.FirstPersonType>(x.FirstPersonFlag),
                });
            }
            return(firstPerson);
        }
Пример #10
0
        public static UniGLTF.Extensions.VRMC_vrm.FirstPerson ToGltf(this FirstPerson self, List <Node> nodes)
        {
            if (self == null)
            {
                return(null);
            }

            var firstPerson = new UniGLTF.Extensions.VRMC_vrm.FirstPerson
            {
            };

            foreach (var x in self.Annotations)
            {
                firstPerson.MeshAnnotations.Add(new UniGLTF.Extensions.VRMC_vrm.MeshAnnotation
                {
                    Node            = nodes.IndexOfThrow(x.Node),
                    FirstPersonType = EnumUtil.Cast <UniGLTF.Extensions.VRMC_vrm.FirstPersonType>(x.FirstPersonFlag),
                });
            }
            return(firstPerson);
        }
Пример #11
0
        static VrmProtobuf.Material ToGltf(this VrmLib.Material src, List <Texture> textures)
        {
            var material = new VrmProtobuf.Material
            {
                Name = src.Name,
                PbrMetallicRoughness = new VrmProtobuf.MaterialPBRMetallicRoughness
                {
                },
                AlphaMode   = EnumUtil.Cast <VrmProtobuf.Material.Types.alphaModeType>(src.AlphaMode),
                AlphaCutoff = src.AlphaCutoff,
                DoubleSided = src.DoubleSided,
            };

            src.BaseColorFactor.ToProtobuf(material.PbrMetallicRoughness.BaseColorFactor.Add, true);
            if (src.BaseColorTexture != null)
            {
                material.PbrMetallicRoughness.BaseColorTexture = new VrmProtobuf.TextureInfo
                {
                    Index = textures.IndexOfNullable(src.BaseColorTexture.Texture),
                };
            }
            return(material);
        }
Пример #12
0
        public static VrmProtobuf.Material PBRToGltf(this PBRMaterial pbr, List <Texture> textures)
        {
            var material = pbr.ToGltf(textures);

            // MetallicRoughness
            material.PbrMetallicRoughness.BaseColorFactor.Add(pbr.BaseColorFactor.ToFloat4());
            if (pbr.BaseColorTexture != null)
            {
                material.PbrMetallicRoughness.BaseColorTexture = new VrmProtobuf.TextureInfo
                {
                    Index = textures.IndexOfNullable(pbr.BaseColorTexture.Texture),
                };
            }
            material.PbrMetallicRoughness.MetallicFactor  = pbr.MetallicFactor;
            material.PbrMetallicRoughness.RoughnessFactor = pbr.RoughnessFactor;
            if (pbr.MetallicRoughnessTexture != null)
            {
                material.PbrMetallicRoughness.MetallicRoughnessTexture = new VrmProtobuf.TextureInfo
                {
                    Index = textures.IndexOfNullable(pbr.MetallicRoughnessTexture),
                };
            }

            // Normal
            if (pbr.NormalTexture != null)
            {
                material.NormalTexture = new VrmProtobuf.MaterialNormalTextureInfo
                {
                    Index = textures.IndexOfNullable(pbr.NormalTexture),
                    Scale = pbr.NormalTextureScale
                };
            }

            // Occlusion
            if (pbr.OcclusionTexture != null)
            {
                material.OcclusionTexture = new VrmProtobuf.MaterialOcclusionTextureInfo
                {
                    Index    = textures.IndexOfNullable(pbr.OcclusionTexture),
                    Strength = pbr.OcclusionTextureStrength,
                };
            }

            // Emissive
            if (pbr.EmissiveTexture != null)
            {
                material.EmissiveTexture = new VrmProtobuf.TextureInfo
                {
                    Index = textures.IndexOfNullable(pbr.EmissiveTexture),
                };
            }
            material.EmissiveFactor.Add(pbr.EmissiveFactor.X);
            material.EmissiveFactor.Add(pbr.EmissiveFactor.Y);
            material.EmissiveFactor.Add(pbr.EmissiveFactor.Z);

            // AlphaMode
            var alphaMode = (pbr.AlphaMode == AlphaModeType.BLEND_ZWRITE)?AlphaModeType.BLEND: pbr.AlphaMode;

            material.AlphaMode = EnumUtil.Cast <VrmProtobuf.Material.Types.alphaModeType>(alphaMode);

            // AlphaCutoff
            material.AlphaCutoff = pbr.AlphaCutoff;

            // DoubleSided
            material.DoubleSided = pbr.DoubleSided;

            return(material);
        }
Пример #13
0
        public static VrmLib.BlendShape FromGltf(BlendShapeGroup x, List <VrmLib.Node> nodes, List <VrmLib.Material> materials)
        {
            var expression = new VrmLib.BlendShape((VrmLib.BlendShapePreset)x.Preset,
                                                   x.Name,
                                                   x.IsBinary.HasValue && x.IsBinary.Value)
            {
                IgnoreBlink  = x.IgnoreBlink.GetValueOrDefault(),
                IgnoreLookAt = x.IgnoreLookAt.GetValueOrDefault(),
                IgnoreMouth  = x.IgnoreMouth.GetValueOrDefault(),
            };

            foreach (var y in x.Binds)
            {
                var node           = nodes[y.Node.Value];
                var blendShapeName = node.Mesh.MorphTargets[y.Index.Value].Name;
                var blendShapeBind = new BlendShapeBindValue(node, blendShapeName, y.Weight.Value);
                expression.BlendShapeValues.Add(blendShapeBind);
            }

            foreach (var y in x.MaterialValues)
            {
                var     material = materials[y.Material.Value];
                Vector4 target   = default;
                if (y.TargetValue.Count > 0)
                {
                    target.X = y.TargetValue[0];
                }
                if (y.TargetValue.Count > 1)
                {
                    target.Y = y.TargetValue[1];
                }
                if (y.TargetValue.Count > 2)
                {
                    target.Z = y.TargetValue[2];
                }
                if (y.TargetValue.Count > 3)
                {
                    target.W = y.TargetValue[3];
                }
                var materialColorBind = new MaterialBindValue(material, EnumUtil.Cast <MaterialBindType>(y.Type), target);
                expression.MaterialValues.Add(materialColorBind);
            }

            foreach (var y in x.MaterialUVBinds)
            {
                var material = materials[y.Material.Value];
                var scaling  = Vector2.One;
                if (y.Scaling.Count > 0)
                {
                    scaling.X = y.Scaling[0];
                }
                if (y.Scaling.Count > 1)
                {
                    scaling.Y = y.Scaling[1];
                }
                var offset = Vector2.Zero;
                if (y.Offset.Count > 0)
                {
                    offset.X = y.Offset[0];
                }
                if (y.Offset.Count > 1)
                {
                    offset.Y = y.Offset[1];
                }
                var materialUVBind = new UVScaleOffsetValue(material, scaling, offset);
                expression.UVScaleOffsetValues.Add(materialUVBind);
            }

            return(expression);
        }
Пример #14
0
        /// <summary>
        /// Gltfの Primitive[] の indices をひとまとめにした
        /// IndexBuffer を返す。
        /// </summary>
        public BufferAccessor CreateAccessor(int[] accessorIndices)
        {
            var totalCount = accessorIndices.Sum(x => Gltf.Accessors[x].Count);

            if (AccessorsIsContinuous(accessorIndices))
            {
                // IndexBufferが連続して格納されている => Slice でいける
                var firstAccessor = Gltf.Accessors[accessorIndices[0]];
                var firstView     = Gltf.BufferViews[firstAccessor.BufferView.Value];
                var start         = firstView.ByteOffset.GetValueOrDefault() + firstAccessor.ByteOffset.Value;
                if (!firstView.Buffer.TryGetValidIndex(Gltf.Buffers.Count, out int firstViewBufferIndex))
                {
                    throw new Exception();
                }
                var buffer = Gltf.Buffers[firstViewBufferIndex];
                var bin    = GetBufferBytes(buffer);
                var bytes  = bin.Slice(start, totalCount.Value * firstAccessor.GetStride());
                return(new BufferAccessor(bytes,
                                          (AccessorValueType)firstAccessor.ComponentType,
                                          EnumUtil.Cast <AccessorVectorType>(firstAccessor.Type),
                                          totalCount.Value));
            }
            else
            {
                // IndexBufferが連続して格納されていない => Int[] を作り直す
                var indices = new byte[totalCount.Value * Marshal.SizeOf(typeof(int))];
                var span    = MemoryMarshal.Cast <byte, int>(indices.AsSpan());
                var offset  = 0;
                foreach (var accessorIndex in accessorIndices)
                {
                    var accessor = Gltf.Accessors[accessorIndex];
                    if (accessor.Type != VrmProtobuf.Accessor.Types.accessorType.Scalar)
                    {
                        throw new ArgumentException($"accessor.type: {accessor.Type}");
                    }
                    var view = Gltf.BufferViews[accessor.BufferView.Value];
                    if (!view.Buffer.TryGetValidIndex(Gltf.Buffers.Count, out int viewBufferIndex))
                    {
                        throw new Exception();
                    }
                    var buffer = Gltf.Buffers[viewBufferIndex];
                    var bin    = GetBufferBytes(buffer);
                    var start  = view.ByteOffset.GetValueOrDefault() + accessor.ByteOffset.Value;
                    var bytes  = bin.Slice(start, accessor.Count.Value * accessor.GetStride());
                    var dst    = MemoryMarshal.Cast <byte, int>(indices.AsSpan()).Slice(offset, accessor.Count.Value);
                    offset += accessor.Count.Value;
                    switch ((AccessorValueType)accessor.ComponentType)
                    {
                    case AccessorValueType.UNSIGNED_BYTE:
                    {
                        var src = bytes.Span;
                        for (int i = 0; i < src.Length; ++i)
                        {
                            // byte to int
                            dst[i] = src[i];
                        }
                    }
                    break;

                    case AccessorValueType.UNSIGNED_SHORT:
                    {
                        var src = MemoryMarshal.Cast <byte, ushort>(bytes.Span);
                        for (int i = 0; i < src.Length; ++i)
                        {
                            // ushort to int
                            dst[i] = src[i];
                        }
                    }
                    break;

                    case AccessorValueType.UNSIGNED_INT:
                    {
                        var src = MemoryMarshal.Cast <byte, int>(bytes.Span);
                        // int to int
                        src.CopyTo(dst);
                    }
                    break;

                    default:
                        throw new NotImplementedException($"accessor.componentType: {accessor.ComponentType}");
                    }
                }
                return(new BufferAccessor(indices, AccessorValueType.UNSIGNED_INT, AccessorVectorType.SCALAR, totalCount.Value));
            }
        }
Пример #15
0
        public static int AddAccessorTo(this BufferAccessor self,
                                        Vrm10Storage storage, int bufferIndex,
                                        // GltfBufferTargetType targetType,
                                        bool useSparse,
                                        Action <Memory <byte>, VrmProtobuf.Accessor> minMax = null,
                                        int offset = 0, int count = 0)
        {
            if (self.ComponentType == AccessorValueType.FLOAT &&
                self.AccessorType == AccessorVectorType.VEC3
                )
            {
                var values = self.GetSpan <Vector3>();
                // 巨大ポリゴンのモデル対策にValueTupleの型をushort -> uint へ
                var sparseValuesWithIndex = new List <ValueTuple <int, Vector3> >();
                for (int i = 0; i < values.Length; ++i)
                {
                    var v = values[i];
                    if (v != Vector3.Zero)
                    {
                        sparseValuesWithIndex.Add((i, v));
                    }
                }

                //var status = $"{sparseIndices.Count * 14}/{values.Length * 12}";
                if (useSparse &&
                    sparseValuesWithIndex.Count > 0 && // avoid empty sparse
                    sparseValuesWithIndex.Count * 16 < values.Length * 12)
                {
                    // use sparse
                    var sparseIndexBin  = new byte[sparseValuesWithIndex.Count * 4].AsMemory();
                    var sparseIndexSpan = MemoryMarshal.Cast <byte, int>(sparseIndexBin.Span);
                    var sparseValueBin  = new byte[sparseValuesWithIndex.Count * 12].AsMemory();
                    var sparseValueSpan = MemoryMarshal.Cast <byte, Vector3>(sparseValueBin.Span);

                    for (int i = 0; i < sparseValuesWithIndex.Count; ++i)
                    {
                        var(index, value)  = sparseValuesWithIndex[i];
                        sparseIndexSpan[i] = index;
                        sparseValueSpan[i] = value;
                    }

                    var sparseIndexView = storage.AppendToBuffer(bufferIndex, sparseIndexBin, 4);
                    var sparseValueView = storage.AppendToBuffer(bufferIndex, sparseValueBin, 12);

                    var accessorIndex = storage.Gltf.Accessors.Count;
                    var accessor      = new VrmProtobuf.Accessor
                    {
                        ComponentType = (int)self.ComponentType,
                        Type          = EnumUtil.Cast <VrmProtobuf.Accessor.Types.accessorType>(self.AccessorType),
                        Count         = self.Count,
                        Sparse        = new VrmProtobuf.AccessorSparse
                        {
                            Count   = sparseValuesWithIndex.Count,
                            Indices = new VrmProtobuf.AccessorSparseIndices
                            {
                                ComponentType = (int)AccessorValueType.UNSIGNED_INT,
                                BufferView    = sparseIndexView,
                            },
                            Values = new VrmProtobuf.AccessorSparseValues
                            {
                                BufferView = sparseValueView,
                            },
                        }
                    };
                    if (minMax != null)
                    {
                        minMax(sparseValueBin, accessor);
                    }
                    storage.Gltf.Accessors.Add(accessor);
                    return(accessorIndex);
                }
            }

            var viewIndex = self.AddViewTo(storage, bufferIndex, offset, count);

            return(self.AddAccessorTo(storage, viewIndex, minMax, 0, count));
        }
Пример #16
0
        /// <summary>
        /// VRM-0.X の MaterialBindValue を VRM-1.0 仕様に変換する
        ///
        /// * Property名 => enum MaterialBindType
        /// * 特に _MainTex_ST の場合、MaterialBindType.UvScale + MaterialBindType.UvScale 2つになりうる
        ///
        /// </summary>
        VrmLib.Expression ToVrmLib(VRM10Expression clip, GameObject root)
        {
            var expression = new VrmLib.Expression(clip.Preset, clip.ExpressionName, clip.IsBinary);

            expression.OverrideBlink  = EnumUtil.Cast <VrmLib.ExpressionOverrideType>(clip.OverrideBlink);
            expression.OverrideLookAt = EnumUtil.Cast <VrmLib.ExpressionOverrideType>(clip.OverrideLookAt);
            expression.OverrideMouth  = EnumUtil.Cast <VrmLib.ExpressionOverrideType>(clip.OverrideMouth);

            foreach (var binding in clip.MorphTargetBindings)
            {
                var transform = GetTransformFromRelativePath(root.transform, binding.RelativePath);
                if (transform == null)
                {
                    continue;
                }
                var renderer = transform.gameObject.GetComponent <SkinnedMeshRenderer>();
                if (renderer == null)
                {
                    continue;
                }
                var mesh = renderer.sharedMesh;
                if (mesh == null)
                {
                    continue;
                }

                var names = new List <string>();
                for (int i = 0; i < mesh.blendShapeCount; ++i)
                {
                    names.Add(mesh.GetBlendShapeName(i));
                }

                var node            = Nodes[transform.gameObject];
                var blendShapeValue = new VrmLib.MorphTargetBind(
                    node,
                    names[binding.Index],
                    // Unity Range [0-100] to VRM-1.0 Range [0-1.0]
                    binding.Weight * 0.01f
                    );
                expression.MorphTargetBinds.Add(blendShapeValue);
            }

            foreach (var binding in clip.MaterialColorBindings)
            {
                var materialPair = Materials.FirstOrDefault(x => x.Key.name == binding.MaterialName);
                if (materialPair.Value != null)
                {
                    var bind = new VrmLib.MaterialColorBind(
                        materialPair.Value,
                        binding.BindType,
                        binding.TargetValue.ToNumericsVector4()
                        );
                    expression.MaterialColorBinds.Add(bind);
                }
            }

            foreach (var binding in clip.MaterialUVBindings)
            {
                var materialPair = Materials.FirstOrDefault(x => x.Key.name == binding.MaterialName);
                if (materialPair.Value != null)
                {
                    var bind = new VrmLib.TextureTransformBind(
                        materialPair.Value,
                        binding.Scaling.ToNumericsVector2(),
                        binding.Offset.ToNumericsVector2()
                        );
                    expression.TextureTransformBinds.Add(bind);
                }
            }

            return(expression);
        }