Ejemplo n.º 1
0
        private void ExportTransform(BabylonNode babylonNode, MFnTransform mFnTransform)
        {
            // Position / rotation / scaling
            RaiseVerbose("BabylonExporter.Node | ExportTransform", 2);
            float[] position           = null;
            float[] rotationQuaternion = null;
            float[] rotation           = null;
            float[] scaling            = null;
            BabylonVector3.EulerRotationOrder rotationOrder = BabylonVector3.EulerRotationOrder.XYZ;
            GetTransform(mFnTransform, ref position, ref rotationQuaternion, ref rotation, ref rotationOrder, ref scaling);

            babylonNode.position = position;
            if (_exportQuaternionsInsteadOfEulers)
            {
                babylonNode.rotationQuaternion = rotationQuaternion;
            }
            else
            {
                babylonNode.rotation = rotation;
            }
            babylonNode.scaling = scaling;
        }
Ejemplo n.º 2
0
        public static BabylonVector3.EulerRotationOrder InvertRotationOrder(BabylonVector3.EulerRotationOrder rotationOrder)
        {
            switch (rotationOrder)
            {
            case BabylonVector3.EulerRotationOrder.XYZ:
            default:
                return(BabylonVector3.EulerRotationOrder.ZYX);

            case BabylonVector3.EulerRotationOrder.YZX:
                return(BabylonVector3.EulerRotationOrder.XZY);

            case BabylonVector3.EulerRotationOrder.ZXY:
                return(BabylonVector3.EulerRotationOrder.YXZ);

            case BabylonVector3.EulerRotationOrder.XZY:
                return(BabylonVector3.EulerRotationOrder.YZX);

            case BabylonVector3.EulerRotationOrder.YXZ:
                return(BabylonVector3.EulerRotationOrder.ZXY);

            case BabylonVector3.EulerRotationOrder.ZYX:
                return(BabylonVector3.EulerRotationOrder.XYZ);
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Get TRS and visiblity animations of the transform
        /// </summary>
        /// <param name="transform">Transform above mesh/camera/light</param>
        /// <returns></returns>
        private List <BabylonAnimation> GetAnimation(MFnTransform transform)
        {
            // Animations
            MPlugArray   connections  = new MPlugArray();
            MStringArray animCurvList = new MStringArray();
            MIntArray    keysTime     = new MIntArray();
            MDoubleArray keysValue    = new MDoubleArray();

            MFloatArray translateValues  = new MFloatArray();
            MFloatArray rotateValues     = new MFloatArray();
            MFloatArray scaleValues      = new MFloatArray();
            MFloatArray visibilityValues = new MFloatArray();
            MFloatArray keyTimes         = new MFloatArray();

            List <BabylonAnimation> animationsObject = new List <BabylonAnimation>();

            //Get the animCurve
            MGlobal.executeCommand("listConnections -type \"animCurve\" " + transform.fullPathName + ";", animCurvList);

            List <AnimCurvData> animCurvesData = new List <AnimCurvData>();

            foreach (String animCurv in animCurvList)
            {
                AnimCurvData animCurvData = new AnimCurvData();
                animCurvesData.Add(animCurvData);

                animCurvData.animCurv = animCurv;

                //Get the key time for each curves
                MGlobal.executeCommand("keyframe -q " + animCurv + ";", keysTime);

                //Get the value for each curves
                MGlobal.executeCommand("keyframe - q -vc -absolute " + animCurv + ";", keysValue);

                if (animCurv.EndsWith("translateZ") || animCurv.EndsWith("rotateX") || animCurv.EndsWith("rotateY"))
                {
                    for (int index = 0; index < keysTime.Count; index++)
                    {
                        // Switch coordinate system at object level
                        int key = keysTime[index];
                        if (animCurvData.valuePerFrame.ContainsKey(key) == false)
                        {
                            animCurvData.valuePerFrame.Add(key, (float)keysValue[index] * -1.0f);
                        }
                    }
                }
                else
                {
                    for (int index = 0; index < keysTime.Count; index++)
                    {
                        int key = keysTime[index];
                        if (animCurvData.valuePerFrame.ContainsKey(key) == false)
                        {
                            animCurvData.valuePerFrame.Add(key, (float)keysValue[index]);
                        }
                    }
                }
            }

            string[] mayaAnimationProperties    = new string[] { "translate", "rotate", "scale" };
            string[] babylonAnimationProperties = new string[] { "position", "rotationQuaternion", "scaling" };
            string[] axis = new string[] { "X", "Y", "Z" };

            // Init TRS default values
            Dictionary <string, float> defaultValues = new Dictionary <string, float>();

            float[] position           = null;
            float[] rotationQuaternion = null;
            BabylonVector3.EulerRotationOrder rotationOrder = BabylonVector3.EulerRotationOrder.XYZ;
            float[] rotation = null;
            float[] scaling  = null;
            GetTransform(transform, ref position, ref rotationQuaternion, ref rotation, ref rotationOrder, ref scaling); // coordinate system already switched
            defaultValues.Add("translateX", position[0]);
            defaultValues.Add("translateY", position[1]);
            defaultValues.Add("translateZ", position[2]);
            defaultValues.Add("rotateX", rotation[0]);
            defaultValues.Add("rotateY", rotation[1]);
            defaultValues.Add("rotateZ", rotation[2]);
            defaultValues.Add("scaleX", scaling[0]);
            defaultValues.Add("scaleY", scaling[1]);
            defaultValues.Add("scaleZ", scaling[2]);

            for (int indexAnimationProperty = 0; indexAnimationProperty < mayaAnimationProperties.Length; indexAnimationProperty++)
            {
                string mayaAnimationProperty = mayaAnimationProperties[indexAnimationProperty];

                // Retreive animation curves data for current animation property
                // Ex: all "translate" data are "translateX", "translateY", "translateZ"
                List <AnimCurvData> animDataProperty = animCurvesData.Where(data => data.animCurv.Contains(mayaAnimationProperty)).ToList();

                if (animDataProperty.Count == 0)
                {
                    // Property is not animated
                    continue;
                }

                // Get all frames for this property
                List <int> framesProperty = new List <int>();
                foreach (var animData in animDataProperty)
                {
                    framesProperty.AddRange(animData.valuePerFrame.Keys);
                }
                framesProperty = framesProperty.Distinct().ToList();
                framesProperty.Sort();

                // Get default values for this property
                BabylonAnimationKey lastBabylonAnimationKey = new BabylonAnimationKey();
                lastBabylonAnimationKey.frame  = 0;
                lastBabylonAnimationKey.values = new float[] { defaultValues[mayaAnimationProperty + "X"], defaultValues[mayaAnimationProperty + "Y"], defaultValues[mayaAnimationProperty + "Z"] };

                // Compute all values for this property
                List <BabylonAnimationKey> babylonAnimationKeys = new List <BabylonAnimationKey>();
                foreach (var frameProperty in framesProperty)
                {
                    BabylonAnimationKey babylonAnimationKey = new BabylonAnimationKey();
                    babylonAnimationKeys.Add(babylonAnimationKey);

                    // Frame
                    babylonAnimationKey.frame = frameProperty;

                    // Values
                    float[] valuesProperty = new float[3];
                    for (int indexAxis = 0; indexAxis < axis.Length; indexAxis++)
                    {
                        AnimCurvData animCurvDataAxis = animDataProperty.Find(data => data.animCurv.EndsWith(axis[indexAxis]));

                        float value;
                        if (animCurvDataAxis != null && animCurvDataAxis.valuePerFrame.ContainsKey(frameProperty))
                        {
                            value = animCurvDataAxis.valuePerFrame[frameProperty];
                        }
                        else
                        {
                            value = lastBabylonAnimationKey.values[indexAxis];
                        }
                        valuesProperty[indexAxis] = value;
                    }
                    babylonAnimationKey.values = valuesProperty.ToArray();

                    // Update last known values
                    lastBabylonAnimationKey = babylonAnimationKey;
                }

                // Convert euler to quaternion angles
                if (indexAnimationProperty == 1) // Rotation
                {
                    foreach (var babylonAnimationKey in babylonAnimationKeys)
                    {
                        BabylonVector3    eulerAngles        = BabylonVector3.FromArray(babylonAnimationKey.values);
                        BabylonVector3    eulerAnglesRadians = eulerAngles * (float)(Math.PI / 180);
                        BabylonQuaternion quaternionAngles   = eulerAnglesRadians.toQuaternion(rotationOrder);
                        babylonAnimationKey.values = quaternionAngles.ToArray();
                    }
                }

                var keysFull = new List <BabylonAnimationKey>(babylonAnimationKeys);

                // Optimization
                OptimizeAnimations(babylonAnimationKeys, true);

                // Ensure animation has at least 2 frames
                string babylonAnimationProperty = babylonAnimationProperties[indexAnimationProperty];
                if (IsAnimationKeysRelevant(babylonAnimationKeys, babylonAnimationProperty))
                {
                    // Create BabylonAnimation
                    animationsObject.Add(new BabylonAnimation()
                    {
                        dataType       = indexAnimationProperty == 1 ? (int)BabylonAnimation.DataType.Quaternion : (int)BabylonAnimation.DataType.Vector3,
                        name           = babylonAnimationProperty + " animation",
                        framePerSecond = Loader.GetFPS(),
                        loopBehavior   = (int)BabylonAnimation.LoopBehavior.Cycle,
                        property       = babylonAnimationProperty,
                        keys           = babylonAnimationKeys.ToArray(),
                        keysFull       = keysFull
                    });
                }
            }

            return(animationsObject);
        }
Ejemplo n.º 4
0
        private void GetTransform(MFnTransform mFnTransform, ref float[] position, ref float[] rotationQuaternion, ref float[] rotation, ref BabylonVector3.EulerRotationOrder rotationOrder, ref float[] scaling)
        {
            var transformationMatrix = new MTransformationMatrix(mFnTransform.transformationMatrix);
            var mayaRotationOrder    = 0;

            MGlobal.executeCommand($"getAttr {mFnTransform.fullPathName}.rotateOrder", out mayaRotationOrder);
            rotationOrder = Tools.ConvertMayaRotationOrder((MEulerRotation.RotationOrder)mayaRotationOrder);

            position           = transformationMatrix.getTranslation();
            rotationQuaternion = transformationMatrix.getRotationQuaternion();
            rotation           = transformationMatrix.getRotation();
            scaling            = transformationMatrix.getScale();

            // Switch coordinate system at object level
            position[2]           *= -1;
            rotationQuaternion[0] *= -1;
            rotationQuaternion[1] *= -1;
            rotation[0]           *= -1;
            rotation[1]           *= -1;
            rotationOrder          = Tools.InvertRotationOrder(rotationOrder);

            // Apply unit conversion factor to meter
            position[0] *= scaleFactorToMeters;
            position[1] *= scaleFactorToMeters;
            position[2] *= scaleFactorToMeters;
        }