internal static void ResolveRelativeValue(JToken reference, JToken relative, ref JToken result) { // compound types if (reference.Type == JTokenType.Object) { JObject Reference = (JObject)reference; JObject Relative = (JObject)relative; JObject Result = (JObject)result; if (Reference.ContainsKey("x") && Reference.ContainsKey("y")) { if (Reference.ContainsKey("z")) { // quaternion if (Reference.ContainsKey("w")) { tempA = new Quaternion( Reference.ForceFloat("x"), Reference.ForceFloat("y"), Reference.ForceFloat("z"), Reference.ForceFloat("w")); tempB = new Quaternion( Relative.ForceFloat("x"), Relative.ForceFloat("y"), Relative.ForceFloat("z"), Relative.ForceFloat("w")); // equivalent to applying rotations in sequence: reference, then relative tempMix = tempA * tempB; Result.SetOrAdd("x", tempMix.x); Result.SetOrAdd("y", tempMix.y); Result.SetOrAdd("z", tempMix.z); Result.SetOrAdd("w", tempMix.w); } // Vector3 else { Result.SetOrAdd("x", Reference.ForceFloat("x") + Relative.ForceFloat("x")); Result.SetOrAdd("y", Reference.ForceFloat("y") + Relative.ForceFloat("y")); Result.SetOrAdd("z", Reference.ForceFloat("z") + Relative.ForceFloat("z")); } } // Vector2 else { Result.SetOrAdd("x", Reference.ForceFloat("x") + Relative.ForceFloat("x")); Result.SetOrAdd("y", Reference.ForceFloat("y") + Relative.ForceFloat("y")); } } // TODO: other compound types (color3, color4) } // simple types else { var Reference = (JValue)reference; var Relative = (JValue)relative; var Result = (JValue)result; // numeric types if (Reference.Type == JTokenType.Float || Reference.Type == JTokenType.Integer) { Result.Value = Reference.ForceFloat() + Relative.ForceFloat(); } // can't blend types else { Result.Value = Reference.Value; } } }
internal static void Interpolate(JToken a, JToken b, float linearT, ref JToken mix, CubicBezier easing) { var easedT = easing.Sample(linearT); // compound types if (a.Type == JTokenType.Object) { JObject A = (JObject)a; JObject B = (JObject)b; JObject Mix = (JObject)mix; if (A.ContainsKey("x") && A.ContainsKey("y")) { if (A.ContainsKey("z")) { // quaternion if (A.ContainsKey("w")) { tempA = new Quaternion(A.ForceFloat("x"), A.ForceFloat("y"), A.ForceFloat("z"), A.ForceFloat("w")); tempB = new Quaternion(B.ForceFloat("x"), B.ForceFloat("y"), B.ForceFloat("z"), B.ForceFloat("w")); tempMix = tempA.Slerp(tempB, easedT); Mix.SetOrAdd("x", tempMix.x); Mix.SetOrAdd("y", tempMix.y); Mix.SetOrAdd("z", tempMix.z); Mix.SetOrAdd("w", tempMix.w); } // Vector3 else { Mix.SetOrAdd("x", GodotMath.Lerp(A.ForceFloat("x"), B.ForceFloat("x"), easedT)); Mix.SetOrAdd("y", GodotMath.Lerp(A.ForceFloat("y"), B.ForceFloat("y"), easedT)); Mix.SetOrAdd("z", GodotMath.Lerp(A.ForceFloat("z"), B.ForceFloat("z"), easedT)); } } // Vector2 else { Mix.SetOrAdd("x", GodotMath.Lerp(A.ForceFloat("x"), B.ForceFloat("x"), easedT)); Mix.SetOrAdd("y", GodotMath.Lerp(A.ForceFloat("y"), B.ForceFloat("y"), easedT)); } } // TODO: other compound types (color3, color4) } // simple types else { JValue A = (JValue)a; JValue B = (JValue)b; JValue Mix = (JValue)mix; // numeric types if (a.Type == JTokenType.Float || a.Type == JTokenType.Integer) { Mix.Value = GodotMath.Lerp(A.ForceFloat(), B.ForceFloat(), easedT); } // no interpolation available, just use A else { Mix.Value = A.Value; } } }