예제 #1
0
        /// <summary>
        ///
        /// 各primitiveが同じ attribute を共有している場合専用のローダー。
        ///
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="gltfMesh"></param>
        /// <returns></returns>
        private void ImportMeshSharingVertexBuffer(GltfData data, glTFMesh gltfMesh, IAxisInverter inverter)
        {
            var isOldVersion = data.GLTF.IsGeneratedUniGLTFAndOlder(1, 16);

            {
                //  同じVertexBufferを共有しているので先頭のモノを使う
                var primitives = gltfMesh.primitives.First();

                var positions  = primitives.GetPositions(data);
                var normals    = primitives.GetNormals(data, positions.Length);
                var texCoords0 = primitives.GetTexCoords0(data, positions.Length);
                var texCoords1 = primitives.GetTexCoords1(data, positions.Length);
                var colors     = primitives.GetColors(data, positions.Length);
                var skinning   = SkinningInfo.Create(data, gltfMesh, primitives);
                AssignBoneWeight = skinning.ShouldSetRendererNodeAsBone;

                CheckAttributeUsages(primitives);

                for (var i = 0; i < positions.Length; ++i)
                {
                    var position = inverter.InvertVector3(positions[i]);
                    var normal   = normals != null?inverter.InvertVector3(normals.Value[i]) : Vector3.zero;

                    var texCoord0 = Vector2.zero;
                    if (texCoords0 != null)
                    {
                        if (isOldVersion)
                        {
#pragma warning disable 0612
                            texCoord0 = texCoords0.Value[i].ReverseY();
#pragma warning restore 0612
                        }
                        else
                        {
                            texCoord0 = texCoords0.Value[i].ReverseUV();
                        }
                    }

                    var texCoord1 = texCoords1 != null ? texCoords1.Value[i].ReverseUV() : Vector2.zero;
                    var color     = colors != null ? colors.Value[i] : Color.white;

                    AddVertex(
                        new MeshVertex(
                            position,
                            normal,
                            texCoord0,
                            texCoord1,
                            color));
                    var skin =
                        skinning.GetSkinnedVertex(i);
                    if (skin.HasValue)
                    {
                        AddSkin(skin.Value);
                    }
                }

                // blendshape
                if (primitives.targets != null && primitives.targets.Count > 0)
                {
                    for (int i = 0; i < primitives.targets.Count; ++i)
                    {
                        var primTarget = primitives.targets[i];

                        var hasPosition = primTarget.POSITION != -1 && data.GLTF.accessors[primTarget.POSITION].count == positions.Length;
                        var hasNormal   = primTarget.NORMAL != -1 && data.GLTF.accessors[primTarget.NORMAL].count == positions.Length;
                        var hasTangent  = primTarget.TANGENT != -1 && data.GLTF.accessors[primTarget.TANGENT].count == positions.Length;

                        var blendShape = new BlendShape(i.ToString(), positions.Length, hasPosition, hasNormal, hasTangent);
                        _blendShapes.Add(blendShape);

                        if (hasPosition)
                        {
                            var morphPositions = data.GetArrayFromAccessor <Vector3>(primTarget.POSITION);
                            blendShape.Positions.Capacity = morphPositions.Length;
                            for (var j = 0; j < positions.Length; ++j)
                            {
                                blendShape.Positions.Add(inverter.InvertVector3(morphPositions[j]));
                            }
                        }

                        if (hasNormal)
                        {
                            var morphNormals = data.GetArrayFromAccessor <Vector3>(primTarget.NORMAL);
                            blendShape.Normals.Capacity = morphNormals.Length;
                            for (var j = 0; j < positions.Length; ++j)
                            {
                                blendShape.Normals.Add(inverter.InvertVector3(morphNormals[j]));
                            }
                        }

                        if (hasTangent)
                        {
                            var morphTangents = data.GetArrayFromAccessor <Vector3>(primTarget.TANGENT);
                            blendShape.Tangents.Capacity = morphTangents.Length;
                            for (var j = 0; j < positions.Length; ++j)
                            {
                                blendShape.Tangents.Add(inverter.InvertVector3(morphTangents[j]));
                            }
                        }
                    }
                }
            }

            foreach (var primitive in gltfMesh.primitives)
            {
                if (primitive.indices >= 0)
                {
                    var indexOffset = _currentIndexCount;
                    var indices     = data.GetIndicesFromAccessorIndex(primitive.indices);
                    PushIndices(indices, 0);
                    _subMeshes.Add(new SubMeshDescriptor(indexOffset, indices.Count));
                }
                else
                {
                    var indexOffset = _currentIndexCount;
                    var positions   = data.GLTF.accessors[primitive.attributes.POSITION];
                    for (int i = 0; i < positions.count; i += 3)
                    {
                        // flip triangle
                        AddIndex(i + 2);
                        AddIndex(i + 1);
                        AddIndex(i);
                    }
                    _subMeshes.Add(new SubMeshDescriptor(indexOffset, positions.count));
                }

                // material
                _materialIndices.Add(primitive.material);
            }
        }
예제 #2
0
        /// <summary>
        /// 各 primitive の attribute の要素が同じでない。=> uv が有るものと無いものが混在するなど
        /// glTF 的にはありうる。
        ///
        /// primitive を独立した(Independent) Mesh として扱いこれを連結する。
        /// </summary>
        /// <param name="ctx"></param>
        /// <param name="gltfMesh"></param>
        /// <returns></returns>
        private void ImportMeshIndependentVertexBuffer(GltfData data, glTFMesh gltfMesh, IAxisInverter inverter)
        {
            bool isOldVersion = data.GLTF.IsGeneratedUniGLTFAndOlder(1, 16);

            foreach (var primitives in gltfMesh.primitives)
            {
                var vertexOffset     = _currentVertexCount;
                var indexBufferCount = primitives.indices;

                // position は必ずある
                var positions  = primitives.GetPositions(data);
                var normals    = primitives.GetNormals(data, positions.Length);
                var texCoords0 = primitives.GetTexCoords0(data, positions.Length);
                var texCoords1 = primitives.GetTexCoords1(data, positions.Length);
                var colors     = primitives.GetColors(data, positions.Length);
                var skinning   = SkinningInfo.Create(data, gltfMesh, primitives);
                AssignBoneWeight = skinning.ShouldSetRendererNodeAsBone;

                CheckAttributeUsages(primitives);

                for (var i = 0; i < positions.Length; ++i)
                {
                    var position = inverter.InvertVector3(positions[i]);
                    var normal   = normals != null?inverter.InvertVector3(normals.Value[i]) : Vector3.zero;

                    var texCoord0 = Vector2.zero;
                    if (texCoords0 != null)
                    {
                        if (isOldVersion)
                        {
#pragma warning disable 0612
                            // backward compatibility
                            texCoord0 = texCoords0.Value[i].ReverseY();
#pragma warning restore 0612
                        }
                        else
                        {
                            texCoord0 = texCoords0.Value[i].ReverseUV();
                        }
                    }

                    var texCoord1 = texCoords1 != null ? texCoords1.Value[i].ReverseUV() : Vector2.zero;

                    var color = colors != null ? colors.Value[i] : Color.white;
                    AddVertex(
                        new MeshVertex(
                            position,
                            normal,
                            texCoord0,
                            texCoord1,
                            color
                            ));
                    var skin = skinning.GetSkinnedVertex(i);
                    if (skin.HasValue)
                    {
                        AddSkin(skin.Value);
                    }
                }

                // blendshape
                if (primitives.targets != null && primitives.targets.Count > 0)
                {
                    for (var i = 0; i < primitives.targets.Count; ++i)
                    {
                        var primTarget = primitives.targets[i];
                        var blendShape = GetOrCreateBlendShape(i);
                        if (primTarget.POSITION != -1)
                        {
                            var array = data.GetArrayFromAccessor <Vector3>(primTarget.POSITION);
                            if (array.Length != positions.Length)
                            {
                                throw new Exception("different length");
                            }

                            blendShape.Positions.AddRange(array.Select(inverter.InvertVector3).ToArray());
                        }

                        if (primTarget.NORMAL != -1)
                        {
                            var array = data.GetArrayFromAccessor <Vector3>(primTarget.NORMAL);
                            if (array.Length != positions.Length)
                            {
                                throw new Exception("different length");
                            }

                            blendShape.Normals.AddRange(array.Select(inverter.InvertVector3).ToArray());
                        }

                        if (primTarget.TANGENT != -1)
                        {
                            var array = data.GetArrayFromAccessor <Vector3>(primTarget.TANGENT);
                            if (array.Length != positions.Length)
                            {
                                throw new Exception("different length");
                            }

                            blendShape.Tangents.AddRange(array.Select(inverter.InvertVector3).ToArray());
                        }
                    }
                }

                if (indexBufferCount >= 0)
                {
                    var indexOffset = _currentIndexCount;
                    var dataIndices = data.GetIndicesFromAccessorIndex(indexBufferCount);
                    PushIndices(dataIndices, vertexOffset);
                    _subMeshes.Add(new SubMeshDescriptor(indexOffset, dataIndices.Count));
                }
                else
                {
                    var indexOffset = _currentIndexCount;
                    for (int i = 0; i < positions.Count(); i += 3)
                    {
                        // flip triangle
                        AddIndex(i + vertexOffset + 2);
                        AddIndex(i + vertexOffset + 1);
                        AddIndex(i + vertexOffset);
                    }
                    _subMeshes.Add(new SubMeshDescriptor(indexOffset, positions.Count()));
                }

                // material
                _materialIndices.Add(primitives.material);
            }
        }