// It is important to note that all translations, reorientations and scales // are relative to the original position of the group rather than the world, at the start of the animation. // So the result of the JSON animation: // // position: { // x: "0.0", // y: "4.0", // z: "9.0" // }, // // would be the same as doing transform.Translate(new Vector3(0f, 4f, 9f), Space.Self); // // -TH 4/29/2016 // // // This entire function for parsing the JSON associated with an exported animation will be changed drastically // and also implemented later in the Voxify software designed specifically for 3d modeling and animating. // // -TH 5/4/2016 // // public Scd_Data(string json) { JSONNode node = JSONNode.Parse(json); name = node["name"]; rate = node["name"].AsFloat; flags = new List<ScdFlag>(); foreach (int flag in node["flags"].AsArray) { if (!flags.Contains((ScdFlag)flag)) flags.Add((ScdFlag)flag); } int anim_length = 0; // I'm genuinely not sure how to explain this loop in plain english. foreach (JSONNode key in node["keys"].AsArray) { int current_length = (key["start"].AsInt + key["frames"].AsInt - 1); if (current_length > anim_length) anim_length = current_length; } frames = new Scd_Frame[anim_length]; for (int i = 0; i < anim_length; i++) frames[i] = null; for (int current_frame = 0; current_frame < frames.Length; current_frame++) { // kframe is the current keyframe we're scoping into foreach (JSONNode kframe in node["keys"].AsArray) { // Is the current frame a frame capture by the key being iterated through. if (current_frame >= kframe["start"].AsInt && current_frame < (kframe["start"].AsInt + kframe["frames"].AsInt)) { frames[current_frame] = new Scd_Frame(); frames[current_frame].groups = new Scd_Frame_Group[kframe["groups"].AsArray.Count]; for (int current_group = 0; current_group < frames[current_frame].groups.Length; current_group++) { frames[current_frame].groups[current_group] = new Scd_Frame_Group(); frames[current_frame].groups[current_group].group = kframe["groups"].AsArray[current_group]; // Values used to determine a value completion from 0.0 to 1.0 frames[current_frame].groups[current_group].gframe_count = kframe["frames"].AsInt; frames[current_frame].groups[current_group].current_gframe = Mathf.Abs(kframe["start"].AsInt - current_frame) + 1; float completion = frames[current_frame].groups[current_group].current_gframe / frames[current_frame].groups[current_group].gframe_count; frames[current_frame].interp = (InterpType)kframe["interp"].AsInt; switch (frames[current_frame].interp) { case InterpType.ASSIGN: if (flags.Contains(ScdFlag.CHANGES_POSITION)) { JSONNode position = kframe["position"]; frames[current_frame].groups[current_group].delta_position = new Vector3(position["x"].AsFloat, position["y"].AsFloat, position["z"].AsFloat); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { JSONNode rotation = kframe["rotation"]; frames[current_frame].groups[current_group].rotation = new Vector3(rotation["x"].AsFloat, rotation["y"].AsFloat, rotation["z"].AsFloat); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { JSONNode scale = kframe["scale"]; frames[current_frame].groups[current_group].rotation = new Vector3(scale["x"].AsFloat, scale["y"].AsFloat, scale["z"].AsFloat); } break; case InterpType.LINEAR: // use Lerp // We want to start at the previous frame, and go backwards until we hit the same group again for (int fcheck = current_frame - 1; fcheck > -1; fcheck--) { if (fcheck == 0) { if (flags.Contains(ScdFlag.CHANGES_POSITION)) { Vector3 prev_pos = new Vector3(0, 0, 0); JSONNode json_position = kframe["position"]; Vector3 new_pos = new Vector3(json_position["x"].AsFloat, json_position["y"].AsFloat, json_position["z"].AsFloat); frames[current_frame].groups[current_group].delta_position = Vector3.Lerp(prev_pos, new_pos, completion); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { Vector3 prev_rot = new Vector3(0, 0, 0); JSONNode json_rotation = kframe["rotation"]; Vector3 new_rot = new Vector3(json_rotation["x"].AsFloat, json_rotation["y"].AsFloat, json_rotation["z"].AsFloat); frames[current_frame].groups[current_group].rotation = Vector3.Lerp(prev_rot, new_rot, completion); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { Vector3 prev_scale = new Vector3(0, 0, 0); JSONNode json_scale = kframe["scale"]; Vector3 new_scale = new Vector3(json_scale["x"].AsFloat, json_scale["y"].AsFloat, json_scale["z"].AsFloat); frames[current_frame].groups[current_group].scale = Vector3.Lerp(prev_scale, new_scale, completion); } } else { foreach (Scd_Frame_Group group in frames[fcheck].groups) { if (group.group == frames[current_frame].groups[current_group].group) { if (flags.Contains(ScdFlag.CHANGES_POSITION)) { Vector3 prev_pos = group.delta_position; JSONNode json_position = kframe["position"]; Vector3 new_pos = new Vector3(json_position["x"].AsFloat, json_position["y"].AsFloat, json_position["z"].AsFloat); frames[current_frame].groups[current_group].delta_position = Vector3.Lerp(Vector3.zero, new_pos, completion); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { Vector3 prev_rot = group.rotation; JSONNode json_rotation = kframe["rotation"]; Vector3 new_rot = new Vector3(json_rotation["x"].AsFloat, json_rotation["y"].AsFloat, json_rotation["z"].AsFloat); frames[current_frame].groups[current_group].rotation = Vector3.Lerp(prev_rot, new_rot, completion); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { Vector3 prev_scale = group.scale; JSONNode json_scale = kframe["scale"]; Vector3 new_scale = new Vector3(json_scale["x"].AsFloat, json_scale["y"].AsFloat, json_scale["z"].AsFloat); frames[current_frame].groups[current_group].scale = Vector3.Lerp(prev_scale, new_scale, completion); } } } } } break; case InterpType.SPHERICAL: // use Slerp instead of Lerp for (int fcheck = current_frame - 1; fcheck > -1; fcheck--) { if (fcheck == 0) { if (flags.Contains(ScdFlag.CHANGES_POSITION)) { Vector3 prev_pos = new Vector3(0, 0, 0); JSONNode json_position = kframe["position"]; Vector3 new_pos = new Vector3(json_position["x"].AsFloat, json_position["y"].AsFloat, json_position["z"].AsFloat); frames[current_frame].groups[current_group].delta_position = Vector3.Slerp(prev_pos, new_pos, completion); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { Vector3 prev_rot = new Vector3(0, 0, 0); JSONNode json_rotation = kframe["rotation"]; Vector3 new_rot = new Vector3(json_rotation["x"].AsFloat, json_rotation["y"].AsFloat, json_rotation["z"].AsFloat); frames[current_frame].groups[current_group].rotation = Vector3.Slerp(prev_rot, new_rot, completion); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { Vector3 prev_scale = new Vector3(0, 0, 0); JSONNode json_scale = kframe["scale"]; Vector3 new_scale = new Vector3(json_scale["x"].AsFloat, json_scale["y"].AsFloat, json_scale["z"].AsFloat); frames[current_frame].groups[current_group].scale = Vector3.Slerp(prev_scale, new_scale, completion); } } else { foreach (Scd_Frame_Group group in frames[fcheck].groups) { if (group.group == frames[current_frame].groups[current_group].group) { if (flags.Contains(ScdFlag.CHANGES_POSITION)) { Vector3 prev_pos = group.delta_position; JSONNode json_position = kframe["position"]; Vector3 new_pos = new Vector3(json_position["x"].AsFloat, json_position["y"].AsFloat, json_position["z"].AsFloat); frames[current_frame].groups[current_group].delta_position = Vector3.Slerp(prev_pos, new_pos, completion); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { Vector3 prev_rot = group.rotation; JSONNode json_rotation = kframe["rotation"]; Vector3 new_rot = new Vector3(json_rotation["x"].AsFloat, json_rotation["y"].AsFloat, json_rotation["z"].AsFloat); frames[current_frame].groups[current_group].rotation = Vector3.Slerp(prev_rot, new_rot, completion); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { Vector3 prev_scale = group.scale; JSONNode json_scale = kframe["scale"]; Vector3 new_scale = new Vector3(json_scale["x"].AsFloat, json_scale["y"].AsFloat, json_scale["z"].AsFloat); frames[current_frame].groups[current_group].scale = Vector3.Slerp(prev_scale, new_scale, completion); } } } } } break; } } } } } }
// It is important to note that all translations, reorientations and scales // are relative to the original position of the group rather than the world, at the start of the animation. // So the result of the JSON animation: // // position: { // x: "0.0", // y: "4.0", // z: "9.0" // }, // // would be the same as doing transform.Translate(new Vector3(0f, 4f, 9f), Space.Self); // // -TH 4/29/2016 // // // This entire function for parsing the JSON associated with an exported animation will be changed drastically // and also implemented later in the Voxify software designed specifically for 3d modeling and animating. // // -TH 5/4/2016 // // public Scd_Data(string json) { JSONNode node = JSONNode.Parse(json); name = node["name"]; rate = node["name"].AsFloat; flags = new List <ScdFlag>(); foreach (int flag in node["flags"].AsArray) { if (!flags.Contains((ScdFlag)flag)) { flags.Add((ScdFlag)flag); } } int anim_length = 0; // I'm genuinely not sure how to explain this loop in plain english. foreach (JSONNode key in node["keys"].AsArray) { int current_length = (key["start"].AsInt + key["frames"].AsInt - 1); if (current_length > anim_length) { anim_length = current_length; } } frames = new Scd_Frame[anim_length]; for (int i = 0; i < anim_length; i++) { frames[i] = null; } for (int current_frame = 0; current_frame < frames.Length; current_frame++) { // kframe is the current keyframe we're scoping into foreach (JSONNode kframe in node["keys"].AsArray) { // Is the current frame a frame capture by the key being iterated through. if (current_frame >= kframe["start"].AsInt && current_frame < (kframe["start"].AsInt + kframe["frames"].AsInt)) { frames[current_frame] = new Scd_Frame(); frames[current_frame].groups = new Scd_Frame_Group[kframe["groups"].AsArray.Count]; for (int current_group = 0; current_group < frames[current_frame].groups.Length; current_group++) { frames[current_frame].groups[current_group] = new Scd_Frame_Group(); frames[current_frame].groups[current_group].group = kframe["groups"].AsArray[current_group]; // Values used to determine a value completion from 0.0 to 1.0 frames[current_frame].groups[current_group].gframe_count = kframe["frames"].AsInt; frames[current_frame].groups[current_group].current_gframe = Mathf.Abs(kframe["start"].AsInt - current_frame) + 1; float completion = frames[current_frame].groups[current_group].current_gframe / frames[current_frame].groups[current_group].gframe_count; frames[current_frame].interp = (InterpType)kframe["interp"].AsInt; switch (frames[current_frame].interp) { case InterpType.ASSIGN: if (flags.Contains(ScdFlag.CHANGES_POSITION)) { JSONNode position = kframe["position"]; frames[current_frame].groups[current_group].delta_position = new Vector3(position["x"].AsFloat, position["y"].AsFloat, position["z"].AsFloat); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { JSONNode rotation = kframe["rotation"]; frames[current_frame].groups[current_group].rotation = new Vector3(rotation["x"].AsFloat, rotation["y"].AsFloat, rotation["z"].AsFloat); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { JSONNode scale = kframe["scale"]; frames[current_frame].groups[current_group].rotation = new Vector3(scale["x"].AsFloat, scale["y"].AsFloat, scale["z"].AsFloat); } break; case InterpType.LINEAR: // use Lerp // We want to start at the previous frame, and go backwards until we hit the same group again for (int fcheck = current_frame - 1; fcheck > -1; fcheck--) { if (fcheck == 0) { if (flags.Contains(ScdFlag.CHANGES_POSITION)) { Vector3 prev_pos = new Vector3(0, 0, 0); JSONNode json_position = kframe["position"]; Vector3 new_pos = new Vector3(json_position["x"].AsFloat, json_position["y"].AsFloat, json_position["z"].AsFloat); frames[current_frame].groups[current_group].delta_position = Vector3.Lerp(prev_pos, new_pos, completion); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { Vector3 prev_rot = new Vector3(0, 0, 0); JSONNode json_rotation = kframe["rotation"]; Vector3 new_rot = new Vector3(json_rotation["x"].AsFloat, json_rotation["y"].AsFloat, json_rotation["z"].AsFloat); frames[current_frame].groups[current_group].rotation = Vector3.Lerp(prev_rot, new_rot, completion); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { Vector3 prev_scale = new Vector3(0, 0, 0); JSONNode json_scale = kframe["scale"]; Vector3 new_scale = new Vector3(json_scale["x"].AsFloat, json_scale["y"].AsFloat, json_scale["z"].AsFloat); frames[current_frame].groups[current_group].scale = Vector3.Lerp(prev_scale, new_scale, completion); } } else { foreach (Scd_Frame_Group group in frames[fcheck].groups) { if (group.group == frames[current_frame].groups[current_group].group) { if (flags.Contains(ScdFlag.CHANGES_POSITION)) { Vector3 prev_pos = group.delta_position; JSONNode json_position = kframe["position"]; Vector3 new_pos = new Vector3(json_position["x"].AsFloat, json_position["y"].AsFloat, json_position["z"].AsFloat); frames[current_frame].groups[current_group].delta_position = Vector3.Lerp(Vector3.zero, new_pos, completion); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { Vector3 prev_rot = group.rotation; JSONNode json_rotation = kframe["rotation"]; Vector3 new_rot = new Vector3(json_rotation["x"].AsFloat, json_rotation["y"].AsFloat, json_rotation["z"].AsFloat); frames[current_frame].groups[current_group].rotation = Vector3.Lerp(prev_rot, new_rot, completion); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { Vector3 prev_scale = group.scale; JSONNode json_scale = kframe["scale"]; Vector3 new_scale = new Vector3(json_scale["x"].AsFloat, json_scale["y"].AsFloat, json_scale["z"].AsFloat); frames[current_frame].groups[current_group].scale = Vector3.Lerp(prev_scale, new_scale, completion); } } } } } break; case InterpType.SPHERICAL: // use Slerp instead of Lerp for (int fcheck = current_frame - 1; fcheck > -1; fcheck--) { if (fcheck == 0) { if (flags.Contains(ScdFlag.CHANGES_POSITION)) { Vector3 prev_pos = new Vector3(0, 0, 0); JSONNode json_position = kframe["position"]; Vector3 new_pos = new Vector3(json_position["x"].AsFloat, json_position["y"].AsFloat, json_position["z"].AsFloat); frames[current_frame].groups[current_group].delta_position = Vector3.Slerp(prev_pos, new_pos, completion); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { Vector3 prev_rot = new Vector3(0, 0, 0); JSONNode json_rotation = kframe["rotation"]; Vector3 new_rot = new Vector3(json_rotation["x"].AsFloat, json_rotation["y"].AsFloat, json_rotation["z"].AsFloat); frames[current_frame].groups[current_group].rotation = Vector3.Slerp(prev_rot, new_rot, completion); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { Vector3 prev_scale = new Vector3(0, 0, 0); JSONNode json_scale = kframe["scale"]; Vector3 new_scale = new Vector3(json_scale["x"].AsFloat, json_scale["y"].AsFloat, json_scale["z"].AsFloat); frames[current_frame].groups[current_group].scale = Vector3.Slerp(prev_scale, new_scale, completion); } } else { foreach (Scd_Frame_Group group in frames[fcheck].groups) { if (group.group == frames[current_frame].groups[current_group].group) { if (flags.Contains(ScdFlag.CHANGES_POSITION)) { Vector3 prev_pos = group.delta_position; JSONNode json_position = kframe["position"]; Vector3 new_pos = new Vector3(json_position["x"].AsFloat, json_position["y"].AsFloat, json_position["z"].AsFloat); frames[current_frame].groups[current_group].delta_position = Vector3.Slerp(prev_pos, new_pos, completion); } if (flags.Contains(ScdFlag.CHANGES_ROTATION)) { Vector3 prev_rot = group.rotation; JSONNode json_rotation = kframe["rotation"]; Vector3 new_rot = new Vector3(json_rotation["x"].AsFloat, json_rotation["y"].AsFloat, json_rotation["z"].AsFloat); frames[current_frame].groups[current_group].rotation = Vector3.Slerp(prev_rot, new_rot, completion); } if (flags.Contains(ScdFlag.CHANGES_SCALE)) { Vector3 prev_scale = group.scale; JSONNode json_scale = kframe["scale"]; Vector3 new_scale = new Vector3(json_scale["x"].AsFloat, json_scale["y"].AsFloat, json_scale["z"].AsFloat); frames[current_frame].groups[current_group].scale = Vector3.Slerp(prev_scale, new_scale, completion); } } } } } break; } } } } } }