public BoneAnimPath(Type type, string animName, string objectName) { this.type = type; var typeStr = TypeToString(type); target = new GlTF_Target(); target.id = objectName; target.path = typeStr; var subName = typeStr + "_" + animName + "_" + objectName; sampler = new GlTF_AnimSampler("sampler_" + subName, "param_" + subName); channel = new GlTF_Channel(sampler, target); accessor = new GlTF_Accessor("accessor_anim_" + subName, TypeToAccType(type), GlTF_Accessor.ComponentType.FLOAT); switch (type) { case Type.Translation: case Type.Scale: accessor.bufferView = GlTF_Writer.vec3BufferView; break; case Type.Rotation: accessor.bufferView = GlTF_Writer.vec4BufferView; break; } GlTF_Writer.accessors.Add(accessor); }
public void Populate(AnimationClip clip, Transform tr, bool bake = true) { // 1. browse clip, collect all curves and create a TargetCurveSet for each target Dictionary <string, TargetCurveSet> targetCurvesBinding = new Dictionary <string, TargetCurveSet>(); collectClipCurves(clip, ref targetCurvesBinding); // Baking needs all properties, fill missing curves with transform data in 2 keyframes (start, endTime) // where endTime is clip duration generateMissingCurves(clip.length, ref tr, ref targetCurvesBinding); if (bake) { // Bake animation for all animated nodes foreach (string target in targetCurvesBinding.Keys) { Transform targetTr = target.Length > 0 ? tr.Find(target) : tr; if (targetTr == null) { continue; } Transform targetObject = targetTr; string targetId = GlTF_Node.GetNameFromObject(targetObject); // Initialize accessors for current animation GlTF_Accessor timeAccessor = new GlTF_Accessor(targetId + "_TimeAccessor_" + clip.name, GlTF_Accessor.Type.SCALAR, GlTF_Accessor.ComponentType.FLOAT); timeAccessor.bufferView = GlTF_Writer.floatBufferView; int timeAccessorIndex = GlTF_Writer.accessors.Count; GlTF_Writer.accessors.Add(timeAccessor); // Translation GlTF_Channel chTranslation = new GlTF_Channel("translation", animSamplers.Count); GlTF_Target targetTranslation = new GlTF_Target(); targetTranslation.id = targetId; targetTranslation.path = "translation"; chTranslation.target = targetTranslation; channels.Add(chTranslation); GlTF_AnimSampler sTranslation = new GlTF_AnimSampler(timeAccessorIndex, GlTF_Writer.accessors.Count); GlTF_Accessor translationAccessor = new GlTF_Accessor(targetId + "_TranslationAccessor_" + clip.name, GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT); translationAccessor.bufferView = GlTF_Writer.vec3BufferView; GlTF_Writer.accessors.Add(translationAccessor); animSamplers.Add(sTranslation); // Rotation GlTF_Channel chRotation = new GlTF_Channel("rotation", animSamplers.Count); GlTF_Target targetRotation = new GlTF_Target(); targetRotation.id = GlTF_Node.GetNameFromObject(targetObject); targetRotation.path = "rotation"; chRotation.target = targetRotation; channels.Add(chRotation); GlTF_AnimSampler sRotation = new GlTF_AnimSampler(timeAccessorIndex, GlTF_Writer.accessors.Count); GlTF_Accessor rotationAccessor = new GlTF_Accessor(targetId + "_RotationAccessor_" + clip.name, GlTF_Accessor.Type.VEC4, GlTF_Accessor.ComponentType.FLOAT); rotationAccessor.bufferView = GlTF_Writer.vec4BufferView; GlTF_Writer.accessors.Add(rotationAccessor); animSamplers.Add(sRotation); // Scale GlTF_Channel chScale = new GlTF_Channel("scale", animSamplers.Count); GlTF_Target targetScale = new GlTF_Target(); targetScale.id = GlTF_Node.GetNameFromObject(targetObject); targetScale.path = "scale"; chScale.target = targetScale; channels.Add(chScale); GlTF_AnimSampler sScale = new GlTF_AnimSampler(timeAccessorIndex, GlTF_Writer.accessors.Count); GlTF_Accessor scaleAccessor = new GlTF_Accessor(targetId + "_ScaleAccessor_" + clip.name, GlTF_Accessor.Type.VEC3, GlTF_Accessor.ComponentType.FLOAT); scaleAccessor.bufferView = GlTF_Writer.vec3BufferView; GlTF_Writer.accessors.Add(scaleAccessor); animSamplers.Add(sScale); // Bake and populate animation data float[] times = null; Vector3[] positions = null; Vector3[] scales = null; Vector4[] rotations = null; bakeCurveSet(targetCurvesBinding[target], clip.length, bakingFramerate, ref times, ref positions, ref rotations, ref scales); // Populate accessors timeAccessor.Populate(times); translationAccessor.Populate(positions); rotationAccessor.Populate(rotations, false); scaleAccessor.Populate(scales, true); } } else { Debug.LogError("Only baked animation is supported for now. Skipping animation"); } }
public void Populate (AnimationClip c) { // AnimationUtility.GetCurveBindings(c); // look at each curve // if position, rotation, scale detected for first time // create channel, sampler, param for it // populate this curve into proper component AnimationClipCurveData[] curveDatas = AnimationUtility.GetAllCurves(c, true); if (curveDatas != null) count = curveDatas[0].curve.keys.Length; for (int i = 0; i < curveDatas.Length; i++) { string propName = curveDatas[i].propertyName; if (propName.Contains("m_LocalPosition")) { if (!gotTranslation) { gotTranslation = true; GlTF_AnimSampler s = new GlTF_AnimSampler(name+"_AnimSampler", "translation"); GlTF_Channel ch = new GlTF_Channel("translation", s); GlTF_Target target = new GlTF_Target(); target.id = "FIXTHIS"; target.path = "translation"; ch.target = target; channels.Add (ch); animSamplers.Add (s); } } if (propName.Contains("m_LocalRotation")) { if (!gotRotation) { gotRotation = true; GlTF_AnimSampler s = new GlTF_AnimSampler(name+"_RotationSampler", "rotation"); GlTF_Channel ch = new GlTF_Channel("rotation", s); GlTF_Target target = new GlTF_Target(); target.id = "FIXTHIS"; target.path = "rotation"; ch.target = target; channels.Add (ch); animSamplers.Add (s); } } if (propName.Contains("m_LocalScale")) { if (!gotScale) { gotScale = true; GlTF_AnimSampler s = new GlTF_AnimSampler(name+"_ScaleSampler", "scale"); GlTF_Channel ch = new GlTF_Channel("scale", s); GlTF_Target target = new GlTF_Target(); target.id = "FIXTHIS"; target.path = "scale"; ch.target = target; channels.Add (ch); animSamplers.Add (s); } } parameters.Populate (curveDatas[i]); // Type propType = curveDatas[i].type; } }