Exemplo n.º 1
0
        public static void Load(ImporterContext ctx)
        {
            // textures
            if (ctx.GLTF.textures != null)
            {
                ctx.Textures.AddRange(ctx.GLTF.textures.Select((x, i) => new TextureItem(ctx.GLTF, i, ctx.TextureBaseDir)));
            }
            foreach (var x in ctx.Textures)
            {
                x.Process(ctx.GLTF, ctx.Storage);
            }

            // materials
            if (ctx.CreateMaterial == null)
            {
                ctx.CreateMaterial = MaterialIO.CreateMaterialFuncFromShader(new ShaderStore());
            }

            if (ctx.GLTF.materials == null || !ctx.GLTF.materials.Any())
            {
                // no material
                ctx.Materials.Add(ctx.CreateMaterial(ctx, 0));
            }
            else
            {
                for (int i = 0; i < ctx.GLTF.materials.Count; ++i)
                {
                    var index    = i;
                    var material = ctx.CreateMaterial(ctx, index);

                    var originalName = material.name;
                    for (int j = 1; ctx.Materials.Any(x => x.name == material.name); ++j)
                    {
                        material.name = string.Format("{0}({1})", originalName, j);
                    }
                    ctx.Materials.Add(material);
                }
            }

            // meshes
            if (ctx.GLTF.meshes
                .SelectMany(x => x.primitives)
                .Any(x => x.extensions.KHR_draco_mesh_compression != null))
            {
                throw new UniGLTFNotSupportedException("draco is not supported");
            }

            for (int i = 0; i < ctx.GLTF.meshes.Count; ++i)
            {
                var meshWithMaterials = ImportMesh(ctx, i);

                var mesh = meshWithMaterials.Mesh;

                // mesh name
                if (string.IsNullOrEmpty(mesh.name))
                {
                    mesh.name = string.Format("UniGLTF import#{0}", i);
                }
                var originalName = mesh.name;
                for (int j = 1; ctx.Meshes.Any(x => x.Mesh.name == mesh.name); ++j)
                {
                    mesh.name = string.Format("{0}({1})", originalName, j);
                }

                ctx.Meshes.Add(meshWithMaterials);
            }

            // nodes
            ctx.Nodes.AddRange(ctx.GLTF.nodes.Select(x => ImportNode(x).transform));

            var nodes = ctx.Nodes.Select((x, i) => BuildHierarchy(ctx, i)).ToList();

            gltfImporter.FixCoordinate(ctx, nodes);

            // skinning
            for (int i = 0; i < nodes.Count; ++i)
            {
                gltfImporter.SetupSkinning(ctx, nodes, i);
            }

            // connect root
            ctx.Root = new GameObject("_root_");
            foreach (var x in ctx.GLTF.rootnodes)
            {
                var t = nodes[x].Transform;
                t.SetParent(ctx.Root.transform, false);
            }

            ImportAnimation(ctx);

            //Debug.LogFormat("Import {0}", ctx.Path);
        }
Exemplo n.º 2
0
        public static Exported FromGameObject(glTF gltf, GameObject go, bool useSparseAccessorForMorphTarget = false)
        {
            var bytesBuffer = new ArrayByteBuffer(new byte[50 * 1024 * 1024]);
            var bufferIndex = gltf.AddBuffer(bytesBuffer);

            if (go.transform.childCount == 0)
            {
                throw new UniGLTFException("empty root GameObject required");
            }

            var unityNodes = go.transform.Traverse()
                             .Skip(1) // exclude root object for the symmetry with the importer
                             .ToList();

            #region Materials and Textures
            var unityMaterials = unityNodes.SelectMany(x => x.GetSharedMaterials()).Where(x => x != null).Distinct().ToList();
            var unityTextures  = unityMaterials.SelectMany(x => x.GetTextures()).Where(x => x != null).Distinct().ToList();

            for (int i = 0; i < unityTextures.Count; ++i)
            {
                var texture = unityTextures[i];
                TextureIO.ExportTexture(gltf, bufferIndex, texture);
            }

            gltf.materials = unityMaterials.Select(x => MaterialIO.ExportMaterial(x, unityTextures)).ToList();
            #endregion

            #region Meshes
            var unityMeshes = unityNodes
                              .Select(x => new MeshWithRenderer
            {
                Mesh       = x.GetSharedMesh(),
                Rendererer = x.GetComponent <Renderer>(),
            })
                              .Where(x =>
            {
                if (x.Mesh == null)
                {
                    return(false);
                }
                if (x.Rendererer.sharedMaterials == null ||
                    x.Rendererer.sharedMaterials.Length == 0)
                {
                    return(false);
                }

                return(true);
            })
                              .ToList();
            ExportMeshes(gltf, bufferIndex, unityMeshes, unityMaterials, useSparseAccessorForMorphTarget);
            #endregion

            #region Skins
            var unitySkins = unityNodes
                             .Select(x => x.GetComponent <SkinnedMeshRenderer>()).Where(x => x != null)
                             .ToList();
            gltf.nodes  = unityNodes.Select(x => ExportNode(x, unityNodes, unityMeshes.Select(y => y.Mesh).ToList(), unitySkins)).ToList();
            gltf.scenes = new List <gltfScene>
            {
                new gltfScene
                {
                    nodes = go.transform.GetChildren().Select(x => unityNodes.IndexOf(x)).ToArray(),
                }
            };

            foreach (var x in unitySkins)
            {
                var matrices = x.sharedMesh.bindposes.Select(y => y.ReverseZ()).ToArray();
                var accessor = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, matrices, glBufferTarget.NONE);

                var skin = new glTFSkin
                {
                    inverseBindMatrices = accessor,
                    joints   = x.bones.Select(y => unityNodes.IndexOf(y)).ToArray(),
                    skeleton = unityNodes.IndexOf(x.rootBone),
                };
                var skinIndex = gltf.skins.Count;
                gltf.skins.Add(skin);

                foreach (var z in unityNodes.Where(y => y.Has(x)))
                {
                    var nodeIndex = unityNodes.IndexOf(z);
                    var node      = gltf.nodes[nodeIndex];
                    node.skin = skinIndex;
                }
            }
            #endregion

#if UNITY_EDITOR
            #region Animations
            var animation = go.GetComponent <Animation>();
            if (animation != null)
            {
                foreach (AnimationState state in animation)
                {
                    var animationWithCurve = ExportAnimation(state.clip, go.transform, unityNodes);

                    foreach (var kv in animationWithCurve.SamplerMap)
                    {
                        var sampler = animationWithCurve.Animation.samplers[kv.Key];

                        var inputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Input);
                        sampler.input = inputAccessorIndex;

                        var outputAccessorIndex = gltf.ExtendBufferAndGetAccessorIndex(bufferIndex, kv.Value.Output);
                        sampler.output = outputAccessorIndex;

                        // modify accessors
                        var outputAccessor = gltf.accessors[outputAccessorIndex];
                        var channel        = animationWithCurve.Animation.channels.First(x => x.sampler == kv.Key);
                        switch (glTFAnimationTarget.GetElementCount(channel.target.path))
                        {
                        case 3:
                            outputAccessor.type   = "VEC3";
                            outputAccessor.count /= 3;
                            break;

                        case 4:
                            outputAccessor.type   = "VEC4";
                            outputAccessor.count /= 4;
                            break;

                        default:
                            throw new NotImplementedException();
                        }
                    }

                    gltf.animations.Add(animationWithCurve.Animation);
                }
            }
            #endregion
#endif

            return(new Exported
            {
                Meshes = unityMeshes,
                Nodes = unityNodes.Select(x => x.transform).ToList(),
                Materials = unityMaterials,
                Textures = unityTextures,
            });
        }