public static string ToJson(this glTFPrimitives self)
        {
            var f = new JsonFormatter();

            GltfSerializer.Serialize_gltf_meshes__primitives_ITEM(f, self);
            return(f.ToString());
        }
Пример #2
0
 public static bool HasSameVertexBuffer(this glTFPrimitives lhs, glTFPrimitives rhs)
 {
     if (lhs.attributes.POSITION != rhs.attributes.POSITION)
     {
         return(false);
     }
     if (lhs.attributes.NORMAL != rhs.attributes.NORMAL)
     {
         return(false);
     }
     if (lhs.attributes.TEXCOORD_0 != rhs.attributes.TEXCOORD_0)
     {
         return(false);
     }
     if (lhs.attributes.TEXCOORD_1 != rhs.attributes.TEXCOORD_1)
     {
         return(false);
     }
     if (lhs.attributes.COLOR_0 != rhs.attributes.COLOR_0)
     {
         return(false);
     }
     if (lhs.attributes.WEIGHTS_0 != rhs.attributes.WEIGHTS_0)
     {
         return(false);
     }
     if (lhs.attributes.JOINTS_0 != rhs.attributes.JOINTS_0)
     {
         return(false);
     }
     return(true);
 }
Пример #3
0
        public static SkinningInfo Create(GltfData data, glTFMesh mesh, glTFPrimitives primitives)
        {
            var hasMorphTarget = HasMorphTarget(mesh);

            var positions = data.GLTF.accessors[primitives.attributes.POSITION];
            var skinning  = new SkinningInfo
            {
                Joints  = primitives.GetJoints(data, positions.count),
                Weights = primitives.GetWeights(data, positions.count),
            };

            if (skinning.Joints != null)
            {
                // use SkinnedMeshRenderer
                return(skinning);
            }
            else if (!hasMorphTarget)
            {
                // use MeshRenderer
                return(skinning);
            }
            else
            {
                // use SkinnedMeshRenderer without boneWeight.
                // https://github.com/vrm-c/UniVRM/issues/1675
                return(new SkinningInfo
                {
                    ShouldSetRendererNodeAsBone = true,
                    Joints = _ => (0, 0, 0, 0),
                    Weights = _ => (1, 0, 0, 0), // assign weight 1
                });
Пример #4
0
        static Mesh FromGltf(Vrm10ImportData storage, glTFMesh x, glTFPrimitives primitive, bool isShared)
        {
            var mesh = new Mesh((TopologyType)primitive.mode)
            {
                VertexBuffer = primitive.attributes.FromGltf(storage)
            };

            if (isShared)
            {
                // create joined index buffer
                mesh.IndexBuffer = storage.CreateAccessor(x.primitives.Select(y => y.indices).ToArray());
            }
            else
            {
                mesh.IndexBuffer = storage.CreateAccessor(primitive.indices);
            }

            if (mesh.IndexBuffer == null)
            {
                var indices = Enumerable.Range(0, mesh.VertexBuffer.Count).ToArray();
                var na      = storage.Data.NativeArrayManager.CreateNativeArray(indices);
                mesh.IndexBuffer = new BufferAccessor(storage.Data.NativeArrayManager, na.Reinterpret <byte>(4), AccessorValueType.UNSIGNED_INT, AccessorVectorType.SCALAR, na.Length);
            }

            {
                gltf_mesh_extras_targetNames.TryGet(x, out List <string> targetNames);

                for (int i = 0; i < primitive.targets.Count; ++i)
                {
                    var gltfTarget = primitive.targets[i];

                    string targetName = null;
                    {
                        targetName = targetNames[i];
                    }
                    var target = new MorphTarget(targetName)
                    {
                        VertexBuffer = gltfTarget.FromGltf(storage)
                    };

                    // validate count
                    foreach (var kv in target.VertexBuffer)
                    {
                        if (kv.Value.Count != mesh.VertexBuffer.Count)
                        {
                            throw new Exception();
                        }
                    }

                    mesh.MorphTargets.Add(target);
                }
            }

            return(mesh);
        }
Пример #5
0
        bool HasSameBuffer(glTFPrimitives lhs, glTFPrimitives rhs)
        {
            {
                var l = GLTF.accessors[lhs.indices];
                var r = GLTF.accessors[rhs.indices];
                if (l.componentType != r.componentType)
                {
                    return(false);
                }
                if (l.type != r.type)
                {
                    return(false);
                }
                if (l.bufferView != r.bufferView)
                {
                    return(false);
                }
            }

            if (lhs.attributes.POSITION != rhs.attributes.POSITION)
            {
                return(false);
            }
            if (lhs.attributes.NORMAL != rhs.attributes.NORMAL)
            {
                return(false);
            }
            if (lhs.attributes.TEXCOORD_0 != rhs.attributes.TEXCOORD_0)
            {
                return(false);
            }
            if (lhs.attributes.TANGENT != rhs.attributes.TANGENT)
            {
                return(false);
            }
            if (lhs.attributes.COLOR_0 != rhs.attributes.COLOR_0)
            {
                return(false);
            }
            if (lhs.attributes.JOINTS_0 != rhs.attributes.JOINTS_0)
            {
                return(false);
            }
            if (lhs.attributes.WEIGHTS_0 != rhs.attributes.WEIGHTS_0)
            {
                return(false);
            }

            return(true);
        }
Пример #6
0
        static Mesh FromGltf(Vrm10Storage storage, glTFMesh x, glTFPrimitives primitive, bool isShared)
        {
            var mesh = new Mesh((TopologyType)primitive.mode)
            {
                VertexBuffer = primitive.attributes.FromGltf(storage)
            };

            if (isShared)
            {
                // create joined index buffer
                mesh.IndexBuffer = storage.CreateAccessor(x.primitives.Select(y => y.indices).ToArray());
            }
            else
            {
                mesh.IndexBuffer = storage.CreateAccessor(primitive.indices);
            }

            {
                gltf_mesh_extras_targetNames.TryGet(x, out List <string> targetNames);

                for (int i = 0; i < primitive.targets.Count; ++i)
                {
                    var gltfTarget = primitive.targets[i];

                    string targetName = null;
                    {
                        targetName = targetNames[i];
                    }
                    var target = new MorphTarget(targetName)
                    {
                        VertexBuffer = gltfTarget.FromGltf(storage)
                    };

                    // validate count
                    foreach (var kv in target.VertexBuffer)
                    {
                        if (kv.Value.Count != mesh.VertexBuffer.Count)
                        {
                            throw new Exception();
                        }
                    }

                    mesh.MorphTargets.Add(target);
                }
            }

            return(mesh);
        }
Пример #7
0
            public Item(string name, glTFPrimitives primitives)
            {
                Name = name;

                Material = primitives.material;
                Mode     = primitives.mode;
                if (primitives.attributes != null)
                {
                    var sb = new List <string>();
                    if (primitives.attributes.POSITION != -1)
                    {
                        sb.Add($"POS={primitives.attributes.POSITION}");
                    }
                    if (primitives.attributes.NORMAL != -1)
                    {
                        sb.Add($"NOM={primitives.attributes.NORMAL}");
                    }
                    if (primitives.attributes.TEXCOORD_0 != -1)
                    {
                        sb.Add($"TEX={primitives.attributes.TEXCOORD_0}");
                    }
                    if (primitives.attributes.COLOR_0 != -1)
                    {
                        sb.Add($"COL={primitives.attributes.COLOR_0}");
                    }
                    if (primitives.attributes.JOINTS_0 != -1)
                    {
                        sb.Add($"JOT={primitives.attributes.JOINTS_0}");
                    }
                    if (primitives.attributes.WEIGHTS_0 != -1)
                    {
                        sb.Add($"WGT={primitives.attributes.WEIGHTS_0}");
                    }
                    Attributes = string.Join(",", sb);
                }
                Indices = primitives.indices;
            }
Пример #8
0
 /// <summary>
 /// IndexBuffer毎に異なるVertexBufferを参照する
 ///
 ///  VertexBuffer
 ///  +--------+ +--------+ +--------+
 ///  |0       | |1       | |2       |
 ///  +--------+ +--------+ +--------+
 ///       A         A        A
 ///       |         |        |
 ///  +---------+--------+--------+
 ///  | submesh0|submesh1|submesh2|
 ///  +---------+--------+--------+
 ///  IndexBuffer
 /// </summary>
 public static Mesh FromGltf(this glTFPrimitives primitive, Vrm10Storage storage, glTFMesh x)
 {
     return(FromGltf(storage, x, primitive, false));
 }
Пример #9
0
        static void ExportMesh(this Mesh mesh, List <object> materials, Vrm10Storage storage, glTFMesh gltfMesh, ExportArgs option)
        {
            //
            // primitive share vertex buffer
            //
            var attributeAccessorIndexMap = mesh.VertexBuffer
                                            .ToDictionary(
                kv => kv.Key,
                kv => kv.Value.AddAccessorTo(
                    storage, 0, option.sparse,
                    kv.Key == VertexBuffer.PositionKey ? (Action <ArraySegment <byte>, glTFAccessor>)Vec3MinMax : null
                    )
                );

            List <Dictionary <string, int> > morphTargetAccessorIndexMapList = null;

            if (mesh.MorphTargets.Any())
            {
                morphTargetAccessorIndexMapList = new List <Dictionary <string, int> >();
                foreach (var morphTarget in mesh.MorphTargets)
                {
                    var dict = new Dictionary <string, int>();

                    foreach (var kv in morphTarget.VertexBuffer)
                    {
                        if (option.removeTangent && kv.Key == VertexBuffer.TangentKey)
                        {
                            // remove tangent
                            continue;
                        }
                        if (option.removeMorphNormal && kv.Key == VertexBuffer.NormalKey)
                        {
                            // normal normal
                            continue;
                        }
                        if (kv.Value.Count != mesh.VertexBuffer.Count)
                        {
                            throw new Exception("inavlid data");
                        }
                        var accessorIndex = kv.Value.AddAccessorTo(storage, 0,
                                                                   option.sparse,
                                                                   kv.Key == VertexBuffer.PositionKey ? (Action <ArraySegment <byte>, glTFAccessor>)Vec3MinMax : null);
                        dict.Add(kv.Key, accessorIndex);
                    }

                    morphTargetAccessorIndexMapList.Add(dict);
                }
            }

            var drawCountOffset = 0;

            foreach (var y in mesh.Submeshes)
            {
                // index
                // slide index buffer accessor
                var indicesAccessorIndex = ExportIndices(storage, mesh.IndexBuffer, drawCountOffset, y.DrawCount, option);
                drawCountOffset += y.DrawCount;

                var prim = new glTFPrimitives
                {
                    mode       = (int)mesh.Topology,
                    material   = y.Material,
                    indices    = indicesAccessorIndex,
                    attributes = new glTFAttributes(),
                };
                gltfMesh.primitives.Add(prim);

                // attribute
                foreach (var kv in mesh.VertexBuffer)
                {
                    var attributeAccessorIndex = attributeAccessorIndexMap[kv.Key];

                    switch (kv.Key)
                    {
                    case VertexBuffer.PositionKey: prim.attributes.POSITION = attributeAccessorIndex; break;

                    case VertexBuffer.NormalKey: prim.attributes.NORMAL = attributeAccessorIndex; break;

                    case VertexBuffer.ColorKey: prim.attributes.COLOR_0 = attributeAccessorIndex; break;

                    case VertexBuffer.TexCoordKey: prim.attributes.TEXCOORD_0 = attributeAccessorIndex; break;

                    case VertexBuffer.TexCoordKey2: prim.attributes.TEXCOORD_1 = attributeAccessorIndex; break;

                    case VertexBuffer.JointKey: prim.attributes.JOINTS_0 = attributeAccessorIndex; break;

                    case VertexBuffer.WeightKey: prim.attributes.WEIGHTS_0 = attributeAccessorIndex; break;
                    }
                }

                // morph target
                if (mesh.MorphTargets.Any())
                {
                    foreach (var(t, accessorIndexMap) in
                             Enumerable.Zip(mesh.MorphTargets, morphTargetAccessorIndexMapList, (t, v) => (t, v)))
                    {
                        var target = new gltfMorphTarget();
                        prim.targets.Add(target);

                        foreach (var kv in t.VertexBuffer)
                        {
                            if (!accessorIndexMap.TryGetValue(kv.Key, out int targetAccessorIndex))
                            {
                                continue;
                            }
                            switch (kv.Key)
                            {
                            case VertexBuffer.PositionKey:
                                target.POSITION = targetAccessorIndex;
                                break;

                            case VertexBuffer.NormalKey:
                                target.NORMAL = targetAccessorIndex;
                                break;

                            case VertexBuffer.TangentKey:
                                target.TANGENT = targetAccessorIndex;
                                break;

                            default:
                                throw new NotImplementedException();
                            }
                        }
                    }
                }
            }

            // target name
            if (mesh.MorphTargets.Any())
            {
                gltf_mesh_extras_targetNames.Serialize(gltfMesh, mesh.MorphTargets.Select(z => z.Name));
            }
        }
Пример #10
0
 /// <summary>
 /// IndexBuffer毎に異なるVertexBufferを参照する
 ///
 ///  VertexBuffer
 ///  +--------+ +--------+ +--------+
 ///  |0       | |1       | |2       |
 ///  +--------+ +--------+ +--------+
 ///       A         A        A
 ///       |         |        |
 ///  +---------+--------+--------+
 ///  | submesh0|submesh1|submesh2|
 ///  +---------+--------+--------+
 ///  IndexBuffer
 /// </summary>
 static Mesh FromGltf(this glTFPrimitives primitive, Vrm10ImportData storage, glTFMesh x)
 {
     return(FromGltf(storage, x, primitive, false));
 }