Пример #1
0
            static void Test(string path, string dir, string filename, string filenameNoEx, string extension)
            {
                Assert.True(ResourcePath.GetDirectoryName(path).SequenceEqual(dir));
                Assert.True(ResourcePath.GetDirectoryName(path.AsSpan()).SequenceEqual(dir));

                Assert.True(ResourcePath.GetFileName(path).SequenceEqual(filename));
                Assert.True(ResourcePath.GetFileName(path.AsSpan()).SequenceEqual(filename));

                Assert.True(ResourcePath.GetFileNameWithoutExtension(path).SequenceEqual(filenameNoEx));
                Assert.True(ResourcePath.GetFileNameWithoutExtension(path.AsSpan()).SequenceEqual(filenameNoEx));

                Assert.True(ResourcePath.GetExtension(path).SequenceEqual(extension));
                Assert.True(ResourcePath.GetExtension(path.AsSpan()).SequenceEqual(extension));
            }
Пример #2
0
        private static UniTask BuildTexture(PMXObject pmx, ResourceFile pmxFile, Model3D model, UnsafeRawArray <SkinnedVertex> vertices, CancellationToken ct)
        {
            var arrayTexture = new ArrayTexture(TextureConfig.BilinearRepeat);

            model.AddComponent(arrayTexture);

            var dir             = ResourcePath.GetDirectoryName(pmxFile.Name);
            var textureNames    = pmx.TextureList.AsSpan();
            var resourcePackage = pmxFile.Package;

            var materials = pmx.MaterialList.AsSpan();

            using var matTexMem = new ValueTypeRentMemory <int>(materials.Length, true);
            var matTex = matTexMem.AsSpan();

            for (int i = 0; i < materials.Length; i++)
            {
                matTex[i] = materials[i].Texture;
            }
            matTex.Sort();
            var texCount = 0;

            if (matTex.Length > 0)
            {
                texCount = 1;
                for (int i = 1; i < matTex.Length; i++)
                {
                    if (matTex[i - 1] != matTex[i])
                    {
                        texCount++;
                    }
                }
            }

            using var textureUsed = new ValueTypeRentMemory <bool>(textureNames.Length, true);

            var size   = new Vector2i(1024, 1024);  // TODO:
            var count  = 0;
            var buffer = new ValueTypeRentMemory <ColorByte>(size.X * size.Y * texCount, false);

            try {
                for (int i = 0; i < textureNames.Length; i++)
                {
                    if (matTex.Contains(i) == false)
                    {
                        continue;
                    }

                    using var _ = GetTexturePath(dir, textureNames[i], out var texturePath, out var ext);
                    var path = texturePath.ToString();

                    // Some pmx have the texture paths that don't exist. (Nobody references them.)
                    // So skip them.
                    if (resourcePackage.TryGetStream(path, out var stream) == false)
                    {
                        continue;
                    }
                    textureUsed[i] = true;
                    var dest = buffer.AsSpan(count * size.X * size.Y);
                    try {
                        using var image = Image.LoadToImageSource(stream, Image.GetTypeFromExt(ext));
                        if (image.Width != size.X || image.Height != size.Y)
                        {
                            using var resized = Image.Resized(image, size);
                            resized.GetPixels().CopyTo(dest);
                        }
                        else
                        {
                            image.GetPixels().CopyTo(dest);
                        }
                        count++;
                    }
                    finally {
                        stream.Dispose();
                    }
                }

                // Calculate texture index of each vertex
                {
                    var indices = pmx.SurfaceList.AsSpan().MarshalCast <Surface, int>();
                    int i       = 0;
                    foreach (var mat in materials)
                    {
                        for (int j = 0; j < mat.VertexCount; j++)
                        {
                            var unusedCount = 0;
                            foreach (var isUsed in textureUsed.AsSpan(0, mat.Texture))
                            {
                                if (isUsed == false)
                                {
                                    unusedCount++;
                                }
                            }
                            vertices[indices[i++]].TextureIndex = mat.Texture - unusedCount;
                        }
                    }
                }
            }
            catch {
                buffer.Dispose();
                throw;
            }
            return(BackToMainThread(arrayTexture, new Vector3i(size.X, size.Y, count), buffer, model.Screen !.TimingPoints.Update, ct));