Esempio n. 1
0
 public static void ImportAnimation(ImporterContext ctx)
 {
     // animation
     if (ctx.GLTF.animations != null && ctx.GLTF.animations.Any())
     {
         var animation = ctx.Root.AddComponent <Animation>();
         ctx.AnimationClips = ImportAnimationClips(ctx);
         foreach (var clip in ctx.AnimationClips)
         {
             animation.AddClip(clip, clip.name);
         }
         if (ctx.AnimationClips.Count > 0)
         {
             animation.clip = ctx.AnimationClips.First();
         }
     }
 }
Esempio n. 2
0
        public static void ImportAsset(string src, string ext, UnityPath prefabPath)
        {
            if (!prefabPath.IsUnderAssetsFolder)
            {
                Debug.LogWarningFormat("out of asset path: {0}", prefabPath);
                return;
            }

            var context = new ImporterContext();

            context.Parse(src);

            // Extract textures to assets folder
            context.ExtractImages(prefabPath);

            ImportDelayed(src, prefabPath, context);
        }
Esempio n. 3
0
        public static void ImportMenu()
        {
            var path = EditorUtility.OpenFilePanel("open gltf", "", "gltf,glb,zip");

            if (string.IsNullOrEmpty(path))
            {
                return;
            }

            if (Application.isPlaying)
            {
                //
                // load into scene
                //
                var context = new ImporterContext();
                context.Load(path);
                context.ShowMeshes();
                Selection.activeGameObject = context.Root;
            }
            else
            {
                //
                // save as asset
                //
                if (path.StartsWithUnityAssetPath())
                {
                    Debug.LogWarningFormat("disallow import from folder under the Assets");
                    return;
                }

                var assetPath = EditorUtility.SaveFilePanel("save prefab", "Assets", Path.GetFileNameWithoutExtension(path), "prefab");
                if (string.IsNullOrEmpty(path))
                {
                    return;
                }

                // import as asset
                gltfAssetPostprocessor.ImportAsset(path, Path.GetExtension(path).ToLower(), UnityPath.FromFullpath(assetPath));
            }
        }
Esempio n. 4
0
        public MeshContext ReadMesh(ImporterContext ctx, int meshIndex)
        {
            var gltfMesh = ctx.GLTF.meshes[meshIndex];

            bool        sharedMorphTarget = gltfMesh.extras != null && gltfMesh.extras.targetNames.Count > 0;
            MeshContext meshContext;

            if (sharedMorphTarget)
            {
                meshContext = _ImportMeshSharingMorphTarget(ctx, gltfMesh);
            }
            else
            {
                glTFAttributes lastAttributes   = null;
                var            sharedAttributes = true;
                foreach (var prim in gltfMesh.primitives)
                {
                    if (lastAttributes != null && !prim.attributes.Equals(lastAttributes))
                    {
                        sharedAttributes = false;
                        break;
                    }

                    lastAttributes = prim.attributes;
                }

                meshContext = sharedAttributes
                    ? _ImportMeshSharingVertexBuffer(ctx, gltfMesh)
                    : _ImportMeshIndependentVertexBuffer(ctx, gltfMesh);
            }

            meshContext.name = gltfMesh.name;
            if (string.IsNullOrEmpty(meshContext.name))
            {
                meshContext.name = string.Format("UniGLTF import#{0}", meshIndex);
            }

            return(meshContext);
        }
Esempio n. 5
0
        //
        // fix node's coordinate. z-back to z-forward
        //
        public static void FixCoordinate(ImporterContext context, List <TransformWithSkin> nodes)
        {
            var globalTransformMap = nodes.ToDictionary(x => x.Transform, x => new PosRot
            {
                Position = x.Transform.position,
                Rotation = x.Transform.rotation,
            });

            foreach (var x in context.GLTF.rootnodes)
            {
                // fix nodes coordinate
                // reverse Z in global
                var t = nodes[x].Transform;
                //t.SetParent(root.transform, false);

                foreach (var transform in t.Traverse())
                {
                    var g = globalTransformMap[transform];
                    transform.position = g.Position.ReverseZ();
                    transform.rotation = g.Rotation.ReverseZ();
                }
            }
        }
Esempio n. 6
0
        public void UniGLTFSimpleSceneTest()
        {
            var go      = CreateSimpleScene();
            var context = new ImporterContext();

            try
            {
                // export
                var gltf = new glTF();

                string json = null;
                using (var exporter = new gltfExporter(gltf))
                {
                    exporter.Prepare(go);
                    exporter.Export();

                    // remove empty buffer
                    gltf.buffers.Clear();

                    json = gltf.ToJson();
                }

                // import
                context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>()));
                //Debug.LogFormat("{0}", context.Json);
                context.Load();

                AssertAreEqual(go.transform, context.Root.transform);
            }
            finally
            {
                //Debug.LogFormat("Destroy, {0}", go.name);
                GameObject.DestroyImmediate(go);
                context.EditorDestroyRootAndAssets();
            }
        }
Esempio n. 7
0
        public static List <AnimationClip> ImportAnimationClip(ImporterContext ctx)
        {
            List <AnimationClip> animasionClips = new List <AnimationClip>();

            for (int i = 0; i < ctx.GLTF.animations.Count; ++i)
            {
                var clip = new AnimationClip();
                clip.ClearCurves();
                clip.legacy = true;
                clip.name   = ctx.GLTF.animations[i].name;
                if (string.IsNullOrEmpty(clip.name))
                {
                    clip.name = "legacy_" + i;
                }
                clip.wrapMode = WrapMode.Loop;

                var animation = ctx.GLTF.animations[i];
                if (string.IsNullOrEmpty(animation.name))
                {
                    animation.name = string.Format("animation:{0}", i);
                }

                foreach (var channel in animation.channels)
                {
                    var targetTransform = ctx.Nodes[channel.target.node];
                    var relativePath    = targetTransform.RelativePathFrom(ctx.Root.transform);
                    switch (channel.target.path)
                    {
                    case glTFAnimationTarget.PATH_TRANSLATION:
                    {
                        var sampler = animation.samplers[channel.sampler];
                        var input   = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input);
                        var output  = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output);

                        AnimationImporter.SetAnimationCurve(
                            clip,
                            relativePath,
                            new string[] { "localPosition.x", "localPosition.y", "localPosition.z" },
                            input,
                            output,
                            sampler.interpolation,
                            typeof(Transform),
                            (values, last) =>
                            {
                                Vector3 temp = new Vector3(values[0], values[1], values[2]);
                                return(temp.ReverseZ().ToArray());
                            }
                            );
                    }
                    break;

                    case glTFAnimationTarget.PATH_ROTATION:
                    {
                        var sampler = animation.samplers[channel.sampler];
                        var input   = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input);
                        var output  = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output);

                        AnimationImporter.SetAnimationCurve(
                            clip,
                            relativePath,
                            new string[] { "localRotation.x", "localRotation.y", "localRotation.z", "localRotation.w" },
                            input,
                            output,
                            sampler.interpolation,
                            typeof(Transform),
                            (values, last) =>
                            {
                                Quaternion currentQuaternion = new Quaternion(values[0], values[1], values[2], values[3]);
                                Quaternion lastQuaternion    = new Quaternion(last[0], last[1], last[2], last[3]);
                                return(AnimationImporter.GetShortest(lastQuaternion, currentQuaternion.ReverseZ()).ToArray());
                            }
                            );

                        clip.EnsureQuaternionContinuity();
                    }
                    break;

                    case glTFAnimationTarget.PATH_SCALE:
                    {
                        var sampler = animation.samplers[channel.sampler];
                        var input   = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input);
                        var output  = ctx.GLTF.GetArrayFromAccessorAsFloat(sampler.output);

                        AnimationImporter.SetAnimationCurve(
                            clip,
                            relativePath,
                            new string[] { "localScale.x", "localScale.y", "localScale.z" },
                            input,
                            output,
                            sampler.interpolation,
                            typeof(Transform),
                            (values, last) => values);
                    }
                    break;

                    case glTFAnimationTarget.PATH_WEIGHT:
                    {
                        var node = ctx.GLTF.nodes[channel.target.node];
                        var mesh = ctx.GLTF.meshes[node.mesh];
                        //var primitive = mesh.primitives.FirstOrDefault();
                        //var targets = primitive.targets;

                        List <string> blendShapeNames     = new List <string>();
                        var           transform           = ctx.Nodes[channel.target.node];
                        var           skinnedMeshRenderer = transform.GetComponent <SkinnedMeshRenderer>();
                        if (skinnedMeshRenderer == null)
                        {
                            continue;
                        }

                        for (int j = 0; j < skinnedMeshRenderer.sharedMesh.blendShapeCount; j++)
                        {
                            blendShapeNames.Add(skinnedMeshRenderer.sharedMesh.GetBlendShapeName(j));
                        }

                        var keyNames = blendShapeNames
                                       .Where(x => !string.IsNullOrEmpty(x))
                                       .Select(x => "blendShape." + x)
                                       .ToArray();

                        var sampler = animation.samplers[channel.sampler];
                        var input   = ctx.GLTF.GetArrayFromAccessor <float>(sampler.input);
                        var output  = ctx.GLTF.GetArrayFromAccessor <float>(sampler.output);
                        AnimationImporter.SetAnimationCurve(
                            clip,
                            relativePath,
                            keyNames,
                            input,
                            output,
                            sampler.interpolation,
                            typeof(SkinnedMeshRenderer),
                            (values, last) =>
                            {
                                for (int j = 0; j < values.Length; j++)
                                {
                                    values[j] *= 100.0f;
                                }
                                return(values);
                            });
                    }
                    break;

                    default:
                        Debug.LogWarningFormat("unknown path: {0}", channel.target.path);
                        break;
                    }
                }
                animasionClips.Add(clip);
            }

            return(animasionClips);
        }
Esempio n. 8
0
 //ImporterContext m_context;
 public ShaderStore(ImporterContext _)
 {
     //m_context = context;
 }
Esempio n. 9
0
        public static MeshWithMaterials BuildMesh(ImporterContext ctx, MeshImporter.MeshContext meshContext)
        {
            if (!meshContext.materialIndices.Any())
            {
                meshContext.materialIndices.Add(0);
            }

            //Debug.Log(prims.ToJson());
            var mesh = new Mesh();

            mesh.name = meshContext.name;

            if (meshContext.positions.Length > UInt16.MaxValue)
            {
#if UNITY_2017_3_OR_NEWER
                mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32;
#else
                Debug.LogWarningFormat("vertices {0} exceed 65535. not implemented. Unity2017.3 supports large mesh",
                                       meshContext.positions.Length);
#endif
            }

            mesh.vertices = meshContext.positions;
            bool recalculateNormals = false;
            if (meshContext.normals != null && meshContext.normals.Length > 0)
            {
                mesh.normals = meshContext.normals;
            }
            else
            {
                recalculateNormals = true;
            }

            if (meshContext.uv != null && meshContext.uv.Length > 0)
            {
                mesh.uv = meshContext.uv;
            }

            bool recalculateTangents = true;
#if UNIGLTF_IMPORT_TANGENTS
            if (meshContext.tangents != null && meshContext.tangents.Length > 0)
            {
                mesh.tangents       = meshContext.tangents;
                recalculateTangents = false;
            }
#endif

            if (meshContext.colors != null && meshContext.colors.Length > 0)
            {
                mesh.colors = meshContext.colors;
            }
            if (meshContext.boneWeights != null && meshContext.boneWeights.Count > 0)
            {
                mesh.boneWeights = meshContext.boneWeights.ToArray();
            }
            mesh.subMeshCount = meshContext.subMeshes.Count;
            for (int i = 0; i < meshContext.subMeshes.Count; ++i)
            {
                mesh.SetTriangles(meshContext.subMeshes[i], i);
            }

            if (recalculateNormals)
            {
                mesh.RecalculateNormals();
            }
            if (recalculateTangents)
            {
#if UNITY_5_6_OR_NEWER
                mesh.RecalculateTangents();
#else
                CalcTangents(mesh);
#endif
            }

            var result = new MeshWithMaterials
            {
                Mesh      = mesh,
                Materials = meshContext.materialIndices.Select(x => ctx.GetMaterial(x)).ToArray()
            };

            if (meshContext.blendShapes != null)
            {
                Vector3[] emptyVertices = null;
                foreach (var blendShape in meshContext.blendShapes)
                {
                    if (blendShape.Positions.Count > 0)
                    {
                        if (blendShape.Positions.Count == mesh.vertexCount)
                        {
                            mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT,
                                                    blendShape.Positions.ToArray(),
                                                    (meshContext.normals != null && meshContext.normals.Length == mesh.vertexCount && blendShape.Normals.Count() == blendShape.Positions.Count()) ? blendShape.Normals.ToArray() : null,
                                                    null
                                                    );
                        }
                        else
                        {
                            Debug.LogWarningFormat("May be partial primitive has blendShape. Require separate mesh or extend blend shape, but not implemented: {0}", blendShape.Name);
                        }
                    }
                    else
                    {
                        if (emptyVertices == null)
                        {
                            emptyVertices = new Vector3[mesh.vertexCount];
                        }
                        // Debug.LogFormat("empty blendshape: {0}.{1}", mesh.name, blendShape.Name);
                        // add empty blend shape for keep blend shape index
                        mesh.AddBlendShapeFrame(blendShape.Name, FRAME_WEIGHT,
                                                emptyVertices,
                                                null,
                                                null
                                                );
                    }
                }
            }

            return(result);
        }
Esempio n. 10
0
        // multiple submMesh is not sharing a VertexBuffer.
        // each subMesh use a independent VertexBuffer.
        private static MeshContext _ImportMeshIndependentVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh)
        {
            //Debug.LogWarning("_ImportMeshIndependentVertexBuffer");

            var targets = gltfMesh.primitives[0].targets;

            for (int i = 1; i < gltfMesh.primitives.Count; ++i)
            {
                if (!gltfMesh.primitives[i].targets.SequenceEqual(targets))
                {
                    throw new NotImplementedException(string.Format("different targets: {0} with {1}",
                                                                    gltfMesh.primitives[i],
                                                                    targets));
                }
            }

            var positions   = new List <Vector3>();
            var normals     = new List <Vector3>();
            var tangents    = new List <Vector4>();
            var uv          = new List <Vector2>();
            var colors      = new List <Color>();
            var meshContext = new MeshContext();

            foreach (var prim in gltfMesh.primitives)
            {
                var indexOffset = positions.Count;
                var indexBuffer = prim.indices;

                var positionCount = positions.Count;
                positions.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.POSITION).Select(x => x.ReverseZ()));
                positionCount = positions.Count - positionCount;

                // normal
                if (prim.attributes.NORMAL != -1)
                {
                    normals.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.NORMAL).Select(x => x.ReverseZ()));
                }

                if (prim.attributes.TANGENT != -1)
                {
                    tangents.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector4>(prim.attributes.TANGENT).Select(x => x.ReverseZ()));
                }

                // uv
                if (prim.attributes.TEXCOORD_0 != -1)
                {
                    if (ctx.IsGeneratedUniGLTFAndOlder(1, 16))
                    {
#pragma warning disable 0612
                        // backward compatibility
                        uv.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector2>(prim.attributes.TEXCOORD_0).Select(x => x.ReverseY()));
#pragma warning restore 0612
                    }
                    else
                    {
                        uv.AddRange(ctx.GLTF.GetArrayFromAccessor <Vector2>(prim.attributes.TEXCOORD_0).Select(x => x.ReverseUV()));
                    }
                }
                else
                {
                    // for inconsistent attributes in primitives
                    uv.AddRange(new Vector2[positionCount]);
                }

                // color
                if (prim.attributes.COLOR_0 != -1)
                {
                    colors.AddRange(ctx.GLTF.GetArrayFromAccessor <Color>(prim.attributes.COLOR_0));
                }

                // skin
                if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1)
                {
                    var joints0  = ctx.GLTF.GetArrayFromAccessor <UShort4>(prim.attributes.JOINTS_0); // uint4
                    var weights0 = ctx.GLTF.GetArrayFromAccessor <Float4>(prim.attributes.WEIGHTS_0).Select(x => x.One()).ToArray();

                    for (int j = 0; j < joints0.Length; ++j)
                    {
                        var bw = new BoneWeight();

                        bw.boneIndex0 = joints0[j].x;
                        bw.weight0    = weights0[j].x;

                        bw.boneIndex1 = joints0[j].y;
                        bw.weight1    = weights0[j].y;

                        bw.boneIndex2 = joints0[j].z;
                        bw.weight2    = weights0[j].z;

                        bw.boneIndex3 = joints0[j].w;
                        bw.weight3    = weights0[j].w;

                        meshContext.boneWeights.Add(bw);
                    }
                }

                // blendshape
                if (prim.targets != null && prim.targets.Count > 0)
                {
                    for (int i = 0; i < prim.targets.Count; ++i)
                    {
                        //var name = string.Format("target{0}", i++);
                        var primTarget = prim.targets[i];
                        var blendShape = new BlendShape(!string.IsNullOrEmpty(prim.extras.targetNames[i])
                            ? prim.extras.targetNames[i]
                            : i.ToString())
                        ;
                        if (primTarget.POSITION != -1)
                        {
                            blendShape.Positions.AddRange(
                                ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.POSITION).Select(x => x.ReverseZ()).ToArray());
                        }
                        if (primTarget.NORMAL != -1)
                        {
                            blendShape.Normals.AddRange(
                                ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.NORMAL).Select(x => x.ReverseZ()).ToArray());
                        }
                        if (primTarget.TANGENT != -1)
                        {
                            blendShape.Tangents.AddRange(
                                ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.TANGENT).Select(x => x.ReverseZ()).ToArray());
                        }
                        meshContext.blendShapes.Add(blendShape);
                    }
                }

                var indices =
                    (indexBuffer >= 0)
                 ? ctx.GLTF.GetIndices(indexBuffer)
                 : TriangleUtil.FlipTriangle(Enumerable.Range(0, meshContext.positions.Length)).ToArray() // without index array
                ;
                for (int i = 0; i < indices.Length; ++i)
                {
                    indices[i] += indexOffset;
                }

                meshContext.subMeshes.Add(indices);

                // material
                meshContext.materialIndices.Add(prim.material);
            }

            meshContext.positions = positions.ToArray();
            meshContext.normals   = normals.ToArray();
            meshContext.tangents  = tangents.ToArray();
            meshContext.uv        = uv.ToArray();

            return(meshContext);
        }
Esempio n. 11
0
 public static void Load(ImporterContext context)
 {
     context.Load();
     context.ShowMeshes();
     context.EnableUpdateWhenOffscreen();
 }
Esempio n. 12
0
        public void Import(ImporterContext context)
        {
            var animationClips = new AnimationClip[context.GLTF.animations.Count];

            // node extension animation
            for (int i = 0; i < context.GLTF.nodes.Count; i++)
            {
                var node = context.GLTF.nodes[i];
                if (node.extensions == null || node.extensions.VCAST_vci_animation == null)
                {
                    continue;
                }

                var vciAnimation = node.extensions.VCAST_vci_animation;
                var root         = context.Nodes[i];
                var animation    = root.gameObject.AddComponent <Animation>();

                foreach (var animationReference in vciAnimation.animationReferences)
                {
                    var           gltfAnimation = context.GLTF.animations[animationReference.animation];
                    AnimationClip clip          = null;
                    if (animationClips[animationReference.animation] == null)
                    {
                        clip = AnimationImporterUtil.ImportAnimationClip(context, gltfAnimation, root);
                        animationClips[animationReference.animation] = clip;
                    }
                    else
                    {
                        clip = animationClips[animationReference.animation];
                    }

                    if (clip != null)
                    {
                        animation.AddClip(clip, clip.name);
                    }
                }
            }

            // root animation
            var rootAnimation = context.Root.GetComponent <Animation>();

            if (rootAnimation == null)
            {
                rootAnimation = context.Root.AddComponent <Animation>();
            }

            for (int i = 0; i < animationClips.Length; i++)
            {
                if (animationClips[i] != null)
                {
                    continue;
                }

                var gltfAnimation = context.GLTF.animations[i];

                animationClips[i] = AnimationImporterUtil.ImportAnimationClip(context, gltfAnimation, context.Root.transform);
                rootAnimation.AddClip(animationClips[i], animationClips[i].name);
            }

            context.AnimationClips = new List <AnimationClip>(animationClips);
        }
Esempio n. 13
0
        public void SameMeshButDifferentMaterialExport()
        {
            var go = new GameObject("same_mesh");

            try
            {
                var shader = Shader.Find("Unlit/Color");

                var cubeA = GameObject.CreatePrimitive(PrimitiveType.Cube);
                {
                    cubeA.transform.SetParent(go.transform);
                    var material = new Material(shader);
                    material.name  = "red";
                    material.color = Color.red;
                    cubeA.GetComponent <Renderer>().sharedMaterial = material;
                }

                {
                    var cubeB = GameObject.Instantiate(cubeA);
                    cubeB.transform.SetParent(go.transform);
                    var material = new Material(shader);
                    material.color = Color.blue;
                    material.name  = "blue";
                    cubeB.GetComponent <Renderer>().sharedMaterial = material;

                    Assert.AreEqual(cubeB.GetComponent <MeshFilter>().sharedMesh, cubeA.GetComponent <MeshFilter>().sharedMesh);
                }

                // export
                var gltf = new glTF();
                var json = default(string);
                using (var exporter = new gltfExporter(gltf))
                {
                    exporter.Prepare(go);
                    exporter.Export();

                    json = gltf.ToJson();
                }

                Assert.AreEqual(2, gltf.meshes.Count);

                var red = gltf.materials[gltf.meshes[0].primitives[0].material];
                Assert.AreEqual(new float[] { 1, 0, 0, 1 }, red.pbrMetallicRoughness.baseColorFactor);

                var blue = gltf.materials[gltf.meshes[1].primitives[0].material];
                Assert.AreEqual(new float[] { 0, 0, 1, 1 }, blue.pbrMetallicRoughness.baseColorFactor);

                Assert.AreEqual(2, gltf.nodes.Count);

                Assert.AreNotEqual(gltf.nodes[0].mesh, gltf.nodes[1].mesh);

                // import
                {
                    var context = new ImporterContext();
                    context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024])));
                    //Debug.LogFormat("{0}", context.Json);
                    context.Load();

                    var importedRed         = context.Root.transform.GetChild(0);
                    var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("red", importedRedMaterial.name);
                    Assert.AreEqual(Color.red, importedRedMaterial.color);

                    var importedBlue         = context.Root.transform.GetChild(1);
                    var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("blue", importedBlueMaterial.name);
                    Assert.AreEqual(Color.blue, importedBlueMaterial.color);
                }

                // import new version
                {
                    var context = new ImporterContext
                    {
                        SerializerType = SerializerTypes.UniJSON
                    };
                    context.ParseJson(json, new SimpleStorage(new ArraySegment <byte>(new byte[1024 * 1024])));
                    //Debug.LogFormat("{0}", context.Json);
                    context.Load();

                    var importedRed         = context.Root.transform.GetChild(0);
                    var importedRedMaterial = importedRed.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("red", importedRedMaterial.name);
                    Assert.AreEqual(Color.red, importedRedMaterial.color);

                    var importedBlue         = context.Root.transform.GetChild(1);
                    var importedBlueMaterial = importedBlue.GetComponent <Renderer>().sharedMaterial;
                    Assert.AreEqual("blue", importedBlueMaterial.name);
                    Assert.AreEqual(Color.blue, importedBlueMaterial.color);
                }
            }
            finally
            {
                GameObject.DestroyImmediate(go);
            }
        }
Esempio n. 14
0
        public static void SetupSkinning(ImporterContext context, List <TransformWithSkin> nodes, int i)
        {
            var x = nodes[i];
            var skinnedMeshRenderer = x.Transform.GetComponent <SkinnedMeshRenderer>();

            if (skinnedMeshRenderer != null)
            {
                var mesh = skinnedMeshRenderer.sharedMesh;
                if (x.SkinIndex.HasValue)
                {
                    if (mesh == null)
                    {
                        throw new Exception();
                    }
                    if (skinnedMeshRenderer == null)
                    {
                        throw new Exception();
                    }

                    if (x.SkinIndex.Value < context.GLTF.skins.Count)
                    {
                        // calculate internal values(boundingBox etc...) when sharedMesh assigned ?
                        skinnedMeshRenderer.sharedMesh = null;

                        var skin   = context.GLTF.skins[x.SkinIndex.Value];
                        var joints = skin.joints.Select(y => nodes[y].Transform).ToArray();
                        if (joints.Any())
                        {
                            // have bones
                            skinnedMeshRenderer.bones = joints;

                            if (skin.inverseBindMatrices != -1)
                            {
                                var bindPoses = context.GLTF.GetArrayFromAccessor <Matrix4x4>(skin.inverseBindMatrices)
                                                .Select(y => y.ReverseZ())
                                                .ToArray()
                                ;
                                mesh.bindposes = bindPoses;
                            }
                            else
                            {
                                //
                                // calc default matrices
                                // https://docs.unity3d.com/ScriptReference/Mesh-bindposes.html
                                //
                                var meshCoords          = skinnedMeshRenderer.transform; // ?
                                var calculatedBindPoses = joints.Select(y => y.worldToLocalMatrix * meshCoords.localToWorldMatrix).ToArray();
                                mesh.bindposes = calculatedBindPoses;
                            }
                        }
                        else
                        {
                            // BlendShape only ?
                        }

                        skinnedMeshRenderer.sharedMesh = mesh;
                        if (skin.skeleton >= 0 && skin.skeleton < nodes.Count)
                        {
                            skinnedMeshRenderer.rootBone = nodes[skin.skeleton].Transform;
                        }
                    }
                }
            }
        }
Esempio n. 15
0
        // multiple submesh sharing same VertexBuffer
        private static MeshContext _ImportMeshSharingVertexBuffer(ImporterContext ctx, glTFMesh gltfMesh)
        {
            var context = new MeshContext();

            {
                var prim = gltfMesh.primitives.First();
                context.positions = ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.POSITION).SelectInplace(x => x.ReverseZ());

                // normal
                if (prim.attributes.NORMAL != -1)
                {
                    context.normals = ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.NORMAL).SelectInplace(x => x.ReverseZ());
                }

                // tangent
                if (prim.attributes.TANGENT != -1)
                {
                    context.tangents = ctx.GLTF.GetArrayFromAccessor <Vector4>(prim.attributes.TANGENT).SelectInplace(x => x.ReverseZ());
                }

                // uv
                if (prim.attributes.TEXCOORD_0 != -1)
                {
                    if (ctx.IsGeneratedUniGLTFAndOlder(1, 16))
                    {
#pragma warning disable 0612
                        // backward compatibility
                        context.uv = ctx.GLTF.GetArrayFromAccessor <Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseY());
#pragma warning restore 0612
                    }
                    else
                    {
                        context.uv = ctx.GLTF.GetArrayFromAccessor <Vector2>(prim.attributes.TEXCOORD_0).SelectInplace(x => x.ReverseUV());
                    }
                }
                else
                {
                    // for inconsistent attributes in primitives
                    context.uv = new Vector2[context.positions.Length];
                }

                // color
                if (prim.attributes.COLOR_0 != -1)
                {
                    if (ctx.GLTF.accessors[prim.attributes.COLOR_0].TypeCount == 3)
                    {
                        var vec3Color = ctx.GLTF.GetArrayFromAccessor <Vector3>(prim.attributes.COLOR_0);
                        context.colors = new Color[vec3Color.Length];

                        for (int i = 0; i < vec3Color.Length; i++)
                        {
                            Vector3 color = vec3Color[i];
                            context.colors[i] = new Color(color.x, color.y, color.z);
                        }
                    }
                    else if (ctx.GLTF.accessors[prim.attributes.COLOR_0].TypeCount == 4)
                    {
                        context.colors = ctx.GLTF.GetArrayFromAccessor <Color>(prim.attributes.COLOR_0);
                    }
                    else
                    {
                        throw new NotImplementedException(string.Format("unknown color type {0}", ctx.GLTF.accessors[prim.attributes.COLOR_0].type));
                    }
                }

                // skin
                if (prim.attributes.JOINTS_0 != -1 && prim.attributes.WEIGHTS_0 != -1)
                {
                    var joints0  = ctx.GLTF.GetArrayFromAccessor <UShort4>(prim.attributes.JOINTS_0); // uint4
                    var weights0 = ctx.GLTF.GetArrayFromAccessor <Float4>(prim.attributes.WEIGHTS_0);
                    for (int i = 0; i < weights0.Length; ++i)
                    {
                        weights0[i] = weights0[i].One();
                    }

                    for (int j = 0; j < joints0.Length; ++j)
                    {
                        var bw = new BoneWeight();

                        bw.boneIndex0 = joints0[j].x;
                        bw.weight0    = weights0[j].x;

                        bw.boneIndex1 = joints0[j].y;
                        bw.weight1    = weights0[j].y;

                        bw.boneIndex2 = joints0[j].z;
                        bw.weight2    = weights0[j].z;

                        bw.boneIndex3 = joints0[j].w;
                        bw.weight3    = weights0[j].w;

                        context.boneWeights.Add(bw);
                    }
                }

                // blendshape
                if (prim.targets != null && prim.targets.Count > 0)
                {
                    context.blendShapes.AddRange(prim.targets.Select((x, i) => new BlendShape(
                                                                         i < prim.extras.targetNames.Count && !string.IsNullOrEmpty(prim.extras.targetNames[i])
                        ? prim.extras.targetNames[i]
                        : i.ToString())));
                    for (int i = 0; i < prim.targets.Count; ++i)
                    {
                        //var name = string.Format("target{0}", i++);
                        var primTarget = prim.targets[i];
                        var blendShape = context.blendShapes[i];

                        if (primTarget.POSITION != -1)
                        {
                            blendShape.Positions.Assign(
                                ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.POSITION), x => x.ReverseZ());
                        }
                        if (primTarget.NORMAL != -1)
                        {
                            blendShape.Normals.Assign(
                                ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.NORMAL), x => x.ReverseZ());
                        }
                        if (primTarget.TANGENT != -1)
                        {
                            blendShape.Tangents.Assign(
                                ctx.GLTF.GetArrayFromAccessor <Vector3>(primTarget.TANGENT), x => x.ReverseZ());
                        }
                    }
                }
            }

            foreach (var prim in gltfMesh.primitives)
            {
                if (prim.indices == -1)
                {
                    context.subMeshes.Add(TriangleUtil.FlipTriangle(Enumerable.Range(0, context.positions.Length)).ToArray());
                }
                else
                {
                    var indices = ctx.GLTF.GetIndices(prim.indices);
                    context.subMeshes.Add(indices);
                }

                // material
                context.materialIndices.Add(prim.material);
            }

            return(context);
        }
Esempio n. 16
0
        public static TransformWithSkin BuildHierarchy(ImporterContext context, int i)
        {
            var go = context.Nodes[i].gameObject;

            if (string.IsNullOrEmpty(go.name))
            {
                go.name = string.Format("node{0:000}", i);
            }

            var nodeWithSkin = new TransformWithSkin
            {
                Transform = go.transform,
            };

            //
            // build hierarchy
            //
            var node = context.GLTF.nodes[i];

            if (node.children != null)
            {
                foreach (var child in node.children)
                {
                    context.Nodes[child].transform.SetParent(context.Nodes[i].transform,
                                                             false // node has local transform
                                                             );
                }
            }

            //
            // attach mesh
            //
            if (node.mesh != -1)
            {
                var mesh = context.Meshes[node.mesh];
                if (mesh.Mesh.blendShapeCount == 0 && node.skin == -1)
                {
                    // without blendshape and bone skinning
                    var filter = go.AddComponent <MeshFilter>();
                    filter.sharedMesh = mesh.Mesh;
                    var renderer = go.AddComponent <MeshRenderer>();
                    renderer.sharedMaterials = mesh.Materials;
                    // invisible in loading
                    renderer.enabled = false;
                    mesh.Renderers.Add(renderer);
                }
                else
                {
                    var renderer = go.AddComponent <SkinnedMeshRenderer>();

                    if (node.skin != -1)
                    {
                        nodeWithSkin.SkinIndex = node.skin;
                    }

                    renderer.sharedMesh      = mesh.Mesh;
                    renderer.sharedMaterials = mesh.Materials;
                    // invisible in loading
                    renderer.enabled = false;
                    mesh.Renderers.Add(renderer);
                }
            }

            return(nodeWithSkin);
        }
Esempio n. 17
0
 public MaterialImporter(IShaderStore shaderStore, ImporterContext context)
 {
     m_shaderStore = shaderStore;
     m_context     = context;
 }