Пример #1
0
        private void ExportBoneAnimation(GLTFAnimation gltfAnimation, int startFrame, int endFrame, GLTF gltf, BabylonNode babylonNode, GLTFNode gltfNode)
        {
            var channelList = gltfAnimation.ChannelList;
            var samplerList = gltfAnimation.SamplerList;

            if (babylonNode.animations != null && babylonNode.animations[0].property == "_matrix")
            {
                logger?.RaiseMessage("GLTFExporter.Animation | Export animation of bone named: " + babylonNode.name, 2);

                var babylonAnimation = babylonNode.animations[0];

                var babylonAnimationKeysInRange = babylonAnimation.keys.Where(key => key.frame >= startFrame && key.frame <= endFrame);
                if (babylonAnimationKeysInRange.Count() <= 0)
                {
                    return;
                }

                // --- Input ---
                var accessorInput = _createAndPopulateInput(gltf, babylonAnimation, startFrame, endFrame);
                if (accessorInput == null)
                {
                    return;
                }

                // --- Output ---
                var paths = new string[] { "translation", "rotation", "scale" };
                var accessorOutputByPath = new Dictionary <string, GLTFAccessor>();

                foreach (string path in paths)
                {
                    GLTFAccessor accessorOutput = _createAccessorOfPath(path, gltf);
                    accessorOutputByPath.Add(path, accessorOutput);
                }

                // Populate accessors
                foreach (var babylonAnimationKey in babylonAnimationKeysInRange)
                {
                    var matrix = new BabylonMatrix();
                    matrix.m = babylonAnimationKey.values;

                    var translationBabylon  = new BabylonVector3();
                    var rotationQuatBabylon = new BabylonQuaternion();
                    var scaleBabylon        = new BabylonVector3();
                    matrix.decompose(scaleBabylon, rotationQuatBabylon, translationBabylon);

                    // Switch coordinate system at object level
                    translationBabylon.Z  *= -1;
                    translationBabylon    *= exportParameters.scaleFactor;
                    rotationQuatBabylon.X *= -1;
                    rotationQuatBabylon.Y *= -1;

                    var outputValuesByPath = new Dictionary <string, float[]>();
                    outputValuesByPath.Add("translation", translationBabylon.ToArray());
                    outputValuesByPath.Add("rotation", rotationQuatBabylon.ToArray());
                    outputValuesByPath.Add("scale", scaleBabylon.ToArray());

                    // Store values as bytes
                    foreach (string path in paths)
                    {
                        var accessorOutput = accessorOutputByPath[path];
                        var outputValues   = outputValuesByPath[path];

                        foreach (var outputValue in outputValues)
                        {
                            accessorOutput.bytesList.AddRange(BitConverter.GetBytes(outputValue));
                        }
                        accessorOutput.count++;
                    }
                }
                ;

                foreach (string path in paths)
                {
                    var accessorOutput = accessorOutputByPath[path];

                    // Animation sampler
                    var gltfAnimationSampler = new GLTFAnimationSampler
                    {
                        input  = accessorInput.index,
                        output = accessorOutput.index
                    };
                    gltfAnimationSampler.index = samplerList.Count;
                    samplerList.Add(gltfAnimationSampler);

                    // Target
                    var gltfTarget = new GLTFChannelTarget
                    {
                        node = gltfNode.index
                    };
                    gltfTarget.path = path;

                    // Channel
                    var gltfChannel = new GLTFChannel
                    {
                        sampler = gltfAnimationSampler.index,
                        target  = gltfTarget
                    };

                    if (exportParameters.enableASBAnimationRetargeting)
                    {
                        ASOBOAnimationRetargetingTargetExtension(ref gltf, ref gltfTarget, babylonNode);
                    }

                    channelList.Add(gltfChannel);
                }
            }
            AnimationExtensionInfo info = new AnimationExtensionInfo(startFrame, endFrame);

            ExportGLTFExtension(babylonNode, ref gltfAnimation, gltf, info);
        }
Пример #2
0
        private void ExportGenericPropertyAnimation <T1, T2>(GLTFAnimation gltfAnimation, int startFrame, int endFrame, GLTF gltf, T1 babylonObject, T2 gltfObject, BabylonScene babylonScene)
        {
            AnimationExtensionInfo info = new AnimationExtensionInfo(startFrame, endFrame);

            ExportGLTFExtension(babylonObject, ref gltfAnimation, gltf, info);
        }
Пример #3
0
        private void ExportNodeAnimation(GLTFAnimation gltfAnimation, int startFrame, int endFrame, GLTF gltf, BabylonNode babylonNode, GLTFNode gltfNode, BabylonScene babylonScene, bool keepNonAnimated = false)
        {
            var channelList = gltfAnimation.ChannelList;
            var samplerList = gltfAnimation.SamplerList;

            // bool exportNonAnimated = exportParameters.animgroupExportNonAnimated;
            //bool exportNonAnimated = true;

            // Combine babylon animations from .babylon file and cached ones
            var babylonAnimations = new List <BabylonAnimation>();

            if (babylonNode.animations != null)
            {
                babylonAnimations.AddRange(babylonNode.animations);
            }
            if (babylonNode.extraAnimations != null)
            {
                babylonAnimations.AddRange(babylonNode.extraAnimations);
            }

            // Filter animations to only keep TRS ones
            babylonAnimations = babylonAnimations.FindAll(babylonAnimation => _getTargetPath(babylonAnimation.property) != null);

            if (babylonAnimations.Count > 0 || keepNonAnimated)
            {
                if (babylonAnimations.Count > 0)
                {
                    logger?.RaiseMessage("GLTFExporter.Animation | Export animations of node named: " + babylonNode.name, 2);
                }
                else if (keepNonAnimated)
                {
                    logger?.RaiseMessage("GLTFExporter.Animation | Export dummy animation for node named: " + babylonNode.name, 2);
                    // Export a dummy animation
                    babylonAnimations.Add(GetDummyAnimation(gltfNode, startFrame, endFrame, babylonScene));
                }


                foreach (BabylonAnimation babylonAnimation in babylonAnimations)
                {
                    var babylonAnimationKeysInRange = babylonAnimation.keys.Where(key => key.frame >= startFrame && key.frame <= endFrame);
                    if (babylonAnimationKeysInRange.Count() <= 0)
                    {
                        continue;
                    }

                    // Target
                    var gltfTarget = new GLTFChannelTarget
                    {
                        node = gltfNode.index
                    };
                    gltfTarget.path = _getTargetPath(babylonAnimation.property);

                    // --- Input ---
                    var accessorInput = _createAndPopulateInput(gltf, babylonAnimation, startFrame, endFrame);
                    if (accessorInput == null)
                    {
                        continue;
                    }

                    // --- Output ---
                    GLTFAccessor accessorOutput = _createAccessorOfPath(gltfTarget.path, gltf);

                    // Populate accessor
                    int numKeys = 0;
                    foreach (var babylonAnimationKey in babylonAnimationKeysInRange)
                    {
                        numKeys++;

                        // copy data before changing it in case animation groups overlap
                        float[] outputValues = new float[babylonAnimationKey.values.Length];
                        babylonAnimationKey.values.CopyTo(outputValues, 0);

                        // Switch coordinate system at object level
                        if (babylonAnimation.property == "position")
                        {
                            outputValues[2] *= -1;
                            outputValues[0] *= exportParameters.scaleFactor;
                            outputValues[1] *= exportParameters.scaleFactor;
                            outputValues[2] *= exportParameters.scaleFactor;
                        }
                        else if (babylonAnimation.property == "rotationQuaternion")
                        {
                            outputValues[0] *= -1;
                            outputValues[1] *= -1;
                        }

                        // Store values as bytes
                        foreach (var outputValue in outputValues)
                        {
                            accessorOutput.bytesList.AddRange(BitConverter.GetBytes(outputValue));
                        }
                    }
                    ;
                    accessorOutput.count = numKeys;
                    if (accessorOutput.count == 0)
                    {
                        logger?.RaiseWarning(String.Format("GLTFExporter.Animation | No frames to export in node animation \"{1}\" of node named \"{0}\". This will cause an error in the output gltf.", babylonNode.name, babylonAnimation.name));
                    }

                    // Animation sampler
                    var gltfAnimationSampler = new GLTFAnimationSampler
                    {
                        input  = accessorInput.index,
                        output = accessorOutput.index
                    };
                    gltfAnimationSampler.index = samplerList.Count;
                    samplerList.Add(gltfAnimationSampler);

                    // Channel
                    var gltfChannel = new GLTFChannel
                    {
                        sampler = gltfAnimationSampler.index,
                        target  = gltfTarget
                    };

                    if (exportParameters.enableASBAnimationRetargeting)
                    {
                        ASOBOAnimationRetargetingTargetExtension(ref gltf, ref gltfTarget, babylonNode);
                    }

                    channelList.Add(gltfChannel);
                }
            }
            AnimationExtensionInfo info = new AnimationExtensionInfo(startFrame, endFrame);

            ExportGLTFExtension(babylonNode, ref gltfAnimation, gltf, info);
        }
Пример #4
0
        private void ExportMaterialAnimation(GLTFAnimation gltfAnimation, int startFrame, int endFrame, GLTF gltf, BabylonMaterial babylonMaterial, GLTFMaterial gltfMaterial, BabylonScene babylonScene)
        {
            AnimationExtensionInfo info = new AnimationExtensionInfo(startFrame, endFrame);

            ExportGLTFExtension(babylonMaterial, ref gltfAnimation, gltf, info);
        }