protected virtual void BuildMeshAttributes(MeshPrimitive primitive, int meshID, int primitiveIndex)
        {
            if (_assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes.Count == 0)
            {
                Dictionary <string, AttributeAccessor> attributeAccessors = new Dictionary <string, AttributeAccessor>(primitive.Attributes.Count + 1);
                foreach (var attributePair in primitive.Attributes)
                {
                    AttributeAccessor AttributeAccessor = new AttributeAccessor()
                    {
                        AccessorId = attributePair.Value,
                        Buffer     = _assetCache.BufferCache[attributePair.Value.Value.BufferView.Value.Buffer.Id]
                    };

                    attributeAccessors[attributePair.Key] = AttributeAccessor;
                }

                if (primitive.Indices != null)
                {
                    AttributeAccessor indexBuilder = new AttributeAccessor()
                    {
                        AccessorId = primitive.Indices,
                        Buffer     = _assetCache.BufferCache[primitive.Indices.Value.BufferView.Value.Buffer.Id]
                    };

                    attributeAccessors[SemanticProperties.INDICES] = indexBuilder;
                }

                GLTFHelpers.BuildMeshAttributes(ref attributeAccessors);
                _assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes = attributeAccessors;
            }
        }
Esempio n. 2
0
        // todo undo
#if !WINDOWS_UWP
        IEnumerator Start()
        {
            var     fullPath0 = Application.streamingAssetsPath + Path.DirectorySeparatorChar + asset0Path;
            ILoader loader0   = new FileLoader(URIHelper.GetDirectoryName(fullPath0));

            var     fullPath1 = Application.streamingAssetsPath + Path.DirectorySeparatorChar + asset1Path;
            ILoader loader1   = new FileLoader(URIHelper.GetDirectoryName(fullPath1));

            yield return(loader0.LoadStream(Path.GetFileName(asset0Path)));

            var asset0Stream = loader0.LoadedStream;
            var asset0Root   = GLTFParser.ParseJson(asset0Stream);

            yield return(loader1.LoadStream(Path.GetFileName(asset1Path)));

            var asset1Stream = loader1.LoadedStream;
            var asset1Root   = GLTFParser.ParseJson(asset1Stream);

            string newPath = "../../" + URIHelper.GetDirectoryName(asset0Path);

            int previousBufferCount  = asset1Root.Buffers.Count;
            int previousImageCount   = asset1Root.Images.Count;
            int previousSceneCounter = asset1Root.Scenes.Count;

            GLTFHelpers.MergeGLTF(asset1Root, asset0Root);

            for (int i = previousBufferCount; i < asset1Root.Buffers.Count; ++i)
            {
                GLTF.Schema.Buffer buffer = asset1Root.Buffers[i];
                if (!URIHelper.IsBase64Uri(buffer.Uri))
                {
                    buffer.Uri = newPath + buffer.Uri;
                }
            }

            for (int i = previousImageCount; i < asset1Root.Images.Count; ++i)
            {
                Image image = asset1Root.Images[i];
                if (!URIHelper.IsBase64Uri(image.Uri))
                {
                    image.Uri = newPath + image.Uri;
                }
            }

            foreach (NodeId node in asset1Root.Scenes[asset0Root.Scene.Id + previousSceneCounter].Nodes)
            {
                node.Value.Translation.X += 5f;
                asset1Root.Scene.Value.Nodes.Add(node);
            }
            GLTFSceneImporter importer = new GLTFSceneImporter(
                asset1Root,
                loader1
                );

            importer.MaximumLod = MaximumLod;

            yield return(importer.LoadScene(-1, Multithreaded));
        }
        public void MergeNodes()
        {
            Assert.IsTrue(File.Exists(GLTF_BOOMBOX_PATH));
            Assert.IsTrue(File.Exists(GLTF_LANTERN_PATH));

            FileStream gltfBoomBoxStream = File.OpenRead(GLTF_BOOMBOX_PATH);
            GLTFRoot   boomBoxRoot;

            GLTFParser.ParseJson(gltfBoomBoxStream, out boomBoxRoot);

            FileStream gltfLanternStream = File.OpenRead(GLTF_LANTERN_PATH);
            GLTFRoot   lanternRoot;

            GLTFParser.ParseJson(gltfLanternStream, out lanternRoot);

            GLTFRoot boomBoxCopy = new GLTFRoot(boomBoxRoot);

            GLTFHelpers.MergeGLTF(boomBoxRoot, lanternRoot);

            Assert.AreNotEqual(boomBoxRoot.Nodes, boomBoxCopy.Nodes);

            Assert.AreNotEqual(boomBoxCopy.Accessors.Count, boomBoxRoot.Accessors.Count);
            Assert.AreNotEqual(boomBoxCopy.Meshes.Count, boomBoxRoot.Meshes.Count);
            Assert.AreNotEqual(boomBoxCopy.Nodes.Count, boomBoxRoot.Nodes.Count);
            Assert.AreNotEqual(boomBoxCopy.BufferViews.Count, boomBoxRoot.BufferViews.Count);
            Assert.AreNotEqual(boomBoxCopy.Buffers.Count, boomBoxRoot.Buffers.Count);
            Assert.AreNotEqual(boomBoxCopy.Images.Count, boomBoxRoot.Images.Count);
            Assert.AreNotEqual(boomBoxCopy.Materials.Count, boomBoxRoot.Materials.Count);
            Assert.AreNotEqual(boomBoxCopy.Textures.Count, boomBoxRoot.Textures.Count);
            Assert.AreNotEqual(boomBoxCopy.Scenes.Count, boomBoxRoot.Scenes.Count);

            Assert.AreEqual(boomBoxCopy.Accessors.Count + lanternRoot.Accessors.Count, boomBoxRoot.Accessors.Count);
            Assert.AreEqual(boomBoxCopy.Meshes.Count + lanternRoot.Meshes.Count, boomBoxRoot.Meshes.Count);
            Assert.AreEqual(boomBoxCopy.Nodes.Count + lanternRoot.Nodes.Count, boomBoxRoot.Nodes.Count);
            Assert.AreEqual(boomBoxCopy.BufferViews.Count + lanternRoot.BufferViews.Count, boomBoxRoot.BufferViews.Count);
            Assert.AreEqual(boomBoxCopy.Buffers.Count + lanternRoot.Buffers.Count, boomBoxRoot.Buffers.Count);
            Assert.AreEqual(boomBoxCopy.Images.Count + lanternRoot.Images.Count, boomBoxRoot.Images.Count);
            Assert.AreEqual(boomBoxCopy.Materials.Count + lanternRoot.Materials.Count, boomBoxRoot.Materials.Count);
            Assert.AreEqual(boomBoxCopy.Textures.Count + lanternRoot.Textures.Count, boomBoxRoot.Textures.Count);
            Assert.AreEqual(boomBoxCopy.Scenes.Count + lanternRoot.Scenes.Count, boomBoxRoot.Scenes.Count);

            // test no throw
            StringWriter stringWriter = new StringWriter();

            boomBoxRoot.Serialize(stringWriter);
        }
        protected virtual void BuildMeshAttributes(MeshPrimitive primitive, int meshID, int primitiveIndex)
        {
            if (_assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes.Count == 0)
            {
                Dictionary <string, AttributeAccessor> attributeAccessors = new Dictionary <string, AttributeAccessor>(primitive.Attributes.Count + 1);
                foreach (var attributePair in primitive.Attributes)
                {
                    AttributeAccessor AttributeAccessor = new AttributeAccessor()
                    {
                        AccessorId = attributePair.Value,
                        Buffer     = _assetCache.BufferCache[attributePair.Value.Value.BufferView.Value.Buffer.Id]
                    };

                    attributeAccessors[attributePair.Key] = AttributeAccessor;
                }

                if (primitive.Indices != null)
                {
                    AttributeAccessor indexBuilder = new AttributeAccessor()
                    {
                        AccessorId = primitive.Indices,
                        Buffer     = _assetCache.BufferCache[primitive.Indices.Value.BufferView.Value.Buffer.Id]
                    };

                    attributeAccessors[SemanticProperties.INDICES] = indexBuilder;
                }

                GLTFHelpers.BuildMeshAttributes(ref attributeAccessors);

                // Flip vectors and triangles to the Unity coordinate system.
                if (attributeAccessors.ContainsKey(SemanticProperties.POSITION))
                {
                    NumericArray resultArray = attributeAccessors[SemanticProperties.POSITION].AccessorContent;
                    resultArray.AsVertices = GLTFUnityHelpers.FlipVectorArrayHandedness(resultArray.AsVertices);
                    attributeAccessors[SemanticProperties.POSITION].AccessorContent = resultArray;
                }
                if (attributeAccessors.ContainsKey(SemanticProperties.INDICES))
                {
                    NumericArray resultArray = attributeAccessors[SemanticProperties.INDICES].AccessorContent;
                    resultArray.AsTriangles = GLTFUnityHelpers.FlipFaces(resultArray.AsTriangles);
                    attributeAccessors[SemanticProperties.INDICES].AccessorContent = resultArray;
                }
                if (attributeAccessors.ContainsKey(SemanticProperties.NORMAL))
                {
                    NumericArray resultArray = attributeAccessors[SemanticProperties.NORMAL].AccessorContent;
                    resultArray.AsNormals = GLTFUnityHelpers.FlipVectorArrayHandedness(resultArray.AsNormals);
                    attributeAccessors[SemanticProperties.NORMAL].AccessorContent = resultArray;
                }
                // TexCoord goes from 0 to 3 to match GLTFHelpers.BuildMeshAttributes
                for (int i = 0; i < 4; i++)
                {
                    if (attributeAccessors.ContainsKey(SemanticProperties.TexCoord(i)))
                    {
                        NumericArray resultArray = attributeAccessors[SemanticProperties.TexCoord(i)].AccessorContent;
                        resultArray.AsTexcoords = GLTFUnityHelpers.FlipTexCoordArrayV(resultArray.AsTexcoords);
                        attributeAccessors[SemanticProperties.TexCoord(i)].AccessorContent = resultArray;
                    }
                }
                if (attributeAccessors.ContainsKey(SemanticProperties.TANGENT))
                {
                    NumericArray resultArray = attributeAccessors[SemanticProperties.TANGENT].AccessorContent;
                    resultArray.AsTangents = GLTFUnityHelpers.FlipVectorArrayHandedness(resultArray.AsTangents);
                    attributeAccessors[SemanticProperties.TANGENT].AccessorContent = resultArray;
                }

                _assetCache.MeshCache[meshID][primitiveIndex].MeshAttributes = attributeAccessors;
            }
        }
        private void addGLTFChannelDataToClip(GLTF.Schema.AnimationChannel channel, AnimationClip clip)
        {
            int animatedNodeIndex = channel.Target.Node.Id;

            if (!_importedObjects.ContainsKey(animatedNodeIndex))
            {
                Debug.Log("Node '" + animatedNodeIndex + "' found for animation, aborting.");
            }

            Transform animatedNode = _importedObjects[animatedNodeIndex].transform;
            string    nodePath     = AnimationUtility.CalculateTransformPath(animatedNode, _sceneObject.transform);

            bool isStepInterpolation = channel.Sampler.Value.Interpolation != InterpolationType.LINEAR;

            byte[]  timeBufferData = _assetCache.BufferCache[channel.Sampler.Value.Output.Value.BufferView.Value.Buffer.Id];
            float[] times          = GLTFHelpers.ParseKeyframeTimes(channel.Sampler.Value.Input.Value, timeBufferData);

            if (channel.Target.Path == GLTFAnimationChannelPath.translation || channel.Target.Path == GLTFAnimationChannelPath.scale)
            {
                byte[] bufferData             = _assetCache.BufferCache[channel.Sampler.Value.Output.Value.BufferView.Value.Buffer.Id];
                GLTF.Math.Vector3[] keyValues = GLTFHelpers.ParseVector3Keyframes(channel.Sampler.Value.Output.Value, bufferData);
                if (keyValues == null)
                {
                    return;
                }

                Vector3[]        values        = keyValues.ToUnityVector3();
                AnimationCurve[] vector3Curves = GLTFUtils.createCurvesFromArrays(times, values, isStepInterpolation, channel.Target.Path == GLTFAnimationChannelPath.translation);

                if (channel.Target.Path == GLTFAnimationChannelPath.translation)
                {
                    GLTFUtils.addTranslationCurvesToClip(vector3Curves, nodePath, ref clip);
                }
                else
                {
                    GLTFUtils.addScaleCurvesToClip(vector3Curves, nodePath, ref clip);
                }
            }
            else if (channel.Target.Path == GLTFAnimationChannelPath.rotation)
            {
                byte[]           bufferData     = _assetCache.BufferCache[channel.Sampler.Value.Output.Value.BufferView.Value.Buffer.Id];
                Vector4[]        values         = GLTFHelpers.ParseRotationKeyframes(channel.Sampler.Value.Output.Value, bufferData).ToUnityVector4();
                AnimationCurve[] rotationCurves = GLTFUtils.createCurvesFromArrays(times, values, isStepInterpolation);

                GLTFUtils.addRotationCurvesToClip(rotationCurves, nodePath, ref clip);
            }
            else if (channel.Target.Path == GLTFAnimationChannelPath.weights)
            {
                List <string> morphTargets = new List <string>();
                int           meshIndex    = _root.Nodes[animatedNodeIndex].Mesh.Id;
                for (int i = 0; i < _root.Meshes[meshIndex].Primitives[0].Targets.Count; ++i)
                {
                    morphTargets.Add(GLTFUtils.buildBlendShapeName(meshIndex, i));
                }

                byte[]           bufferData  = _assetCache.BufferCache[channel.Sampler.Value.Output.Value.BufferView.Value.Buffer.Id];
                float[]          values      = GLTFHelpers.ParseKeyframeTimes(channel.Sampler.Value.Output.Value, bufferData);
                AnimationCurve[] morphCurves = GLTFUtils.buildMorphAnimationCurves(times, values, morphTargets.Count);

                GLTFUtils.addMorphAnimationCurvesToClip(morphCurves, nodePath, morphTargets.ToArray(), ref clip);
            }
            else
            {
                Debug.Log("Unsupported animation channel target: " + channel.Target.Path);
            }
        }
Esempio n. 6
0
        // todo undo
#if !WINDOWS_UWP
        private async Task Start()
        {
            var         fullPath0 = Application.streamingAssetsPath + Path.DirectorySeparatorChar + asset0Path;
            IDataLoader loader0   = new FileLoader(URIHelper.GetDirectoryName(fullPath0));

            var         fullPath1 = Application.streamingAssetsPath + Path.DirectorySeparatorChar + asset1Path;
            IDataLoader loader1   = new FileLoader(URIHelper.GetDirectoryName(fullPath1));

            var asset0Stream = await loader0.LoadStreamAsync(Path.GetFileName(asset0Path));

            GLTFRoot asset0Root;

            GLTFParser.ParseJson(asset0Stream, out asset0Root);

            var asset1Stream = await loader1.LoadStreamAsync(Path.GetFileName(asset1Path));

            GLTFRoot asset1Root;

            GLTFParser.ParseJson(asset1Stream, out asset1Root);

            string newPath = "../../" + URIHelper.GetDirectoryName(asset0Path);

            int previousBufferCount  = asset1Root.Buffers.Count;
            int previousImageCount   = asset1Root.Images.Count;
            int previousSceneCounter = asset1Root.Scenes.Count;

            GLTFHelpers.MergeGLTF(asset1Root, asset0Root);

            for (int i = previousBufferCount; i < asset1Root.Buffers.Count; ++i)
            {
                GLTF.Schema.GLTFBuffer buffer = asset1Root.Buffers[i];
                if (!URIHelper.IsBase64Uri(buffer.Uri))
                {
                    buffer.Uri = newPath + buffer.Uri;
                }
            }

            for (int i = previousImageCount; i < asset1Root.Images.Count; ++i)
            {
                GLTFImage image = asset1Root.Images[i];
                if (!URIHelper.IsBase64Uri(image.Uri))
                {
                    image.Uri = newPath + image.Uri;
                }
            }

            foreach (NodeId node in asset1Root.Scenes[asset0Root.Scene.Id + previousSceneCounter].Nodes)
            {
                node.Value.Translation.X += 5f;
                asset1Root.Scene.Value.Nodes.Add(node);
            }
            GLTFSceneImporter importer = new GLTFSceneImporter(
                asset1Root,
                null,
                new ImportOptions
            {
                DataLoader           = loader1,
                AsyncCoroutineHelper = gameObject.AddComponent <AsyncCoroutineHelper>()
            });

            importer.MaximumLod      = MaximumLod;
            importer.IsMultithreaded = Multithreaded;
            await importer.LoadSceneAsync(-1);
        }