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 ; }
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); }
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); }
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)); }
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, }); }
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); }
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, }); }
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); }
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); }
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); }
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); }
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); }
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); }
/// <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)); } }
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)); }
/// <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); }