private void SetRandomColorAndAlpha(ModelNode model) { var randomColor3F = RandomHelper.Random.NextVector3F(0, 4); // Desaturate random color to avoid eye cancer. ;-) float luminance = Vector3F.Dot(randomColor3F, GraphicsHelper.LuminanceWeights); var randomColor = (Vector3)InterpolationHelper.Lerp(new Vector3F(luminance), randomColor3F, 0.5f); var randomAlpha = MathHelper.Clamp(RandomHelper.Random.NextFloat(0, 5), 0, 1); // Change the values of all effect parameters "InstanceColor" and "InstanceAlpha": foreach (MeshNode meshNode in model.GetDescendants().OfType <MeshNode>()) { foreach (MaterialInstance materialInstance in meshNode.MaterialInstances) { foreach (EffectBinding effectBinding in materialInstance.EffectBindings) { if (effectBinding.ParameterBindings.Contains("InstanceColor")) { effectBinding.Set("InstanceColor", randomColor); } if (effectBinding.ParameterBindings.Contains("InstanceAlpha")) { effectBinding.Set("InstanceAlpha", randomAlpha); } } } } }
private float ComputeNoise(Vector2F position) { float t0 = position.X + N; int bx0 = ((int)t0) & _maskB; int bx1 = (bx0 + 1) & _maskB; float rx0 = t0 - (int)t0; float rx1 = rx0 - 1.0f; float t1 = position.Y + N; int by0 = ((int)t1) & _maskB; int by1 = (by0 + 1) & _maskB; float ry0 = t1 - (int)t1; float ry1 = ry0 - 1.0f; int b00 = _permutations[(_permutations[bx0] + by0) & _maskB]; int b10 = _permutations[(_permutations[bx1] + by0) & _maskB]; int b01 = _permutations[(_permutations[bx0] + by1) & _maskB]; int b11 = _permutations[(_permutations[bx1] + by1) & _maskB]; float sx = ComputeCubicSpline(rx0); float u = _magnitudes[b00] * Vector2F.Dot(_gradients[b00], new Vector2F(rx0, ry0)); float v = _magnitudes[b10] * Vector2F.Dot(_gradients[b10], new Vector2F(rx1, ry0)); float a = InterpolationHelper.Lerp(u, v, sx); u = _magnitudes[b01] * Vector2F.Dot(_gradients[b01], new Vector2F(rx0, ry1)); v = _magnitudes[b11] * Vector2F.Dot(_gradients[b11], new Vector2F(rx1, ry1)); float b = InterpolationHelper.Lerp(u, v, sx); float sy = ComputeCubicSpline(ry0); return(InterpolationHelper.Lerp(a, b, sy)); }
protected override void OnUpdate(TimeSpan deltaTime) { // A random new wind change is chosen at regular intervals. const float WindInterval = 3; _timeSinceWindChange += (float)deltaTime.TotalSeconds; if (_timeSinceWindChange > WindInterval) { _lastAngle = _nextAngle; _lastSpeed = _nextSpeed; _timeSinceWindChange = 0; // Get random target angle. float a = RandomHelper.Random.NextFloat(-1, 1); // Apply non-linear curve to make smaller changes more likely. a = (float)Math.Pow(a, 3); // Convert to angle and limit variation. _nextAngle = _lastAngle + ConstantsF.PiOver2 * a * DirectionVariation; // Get random target speed. float s = RandomHelper.Random.NextFloat(0, 1); _nextSpeed = MaxSpeed * (1 - s * SpeedVariation); } // Update current wind. float p = _timeSinceWindChange / WindInterval; float speed = InterpolationHelper.Lerp(_lastSpeed, _nextSpeed, p); float angle = InterpolationHelper.Lerp(_lastAngle, _nextAngle, p); Wind = speed * Matrix33F.CreateRotationY(angle) * Vector3F.UnitX; }
/// <summary> /// Computes the angular attenuation (spotlight falloff) for a given angle. /// </summary> /// <param name="angle">The angle relative to the main light direction in radians.</param> /// <param name="falloffAngle">The falloff angle.</param> /// <param name="cutoffAngle">The cutoff angle.</param> /// <returns> /// The angular attenuation of the light intensity. (1 when <paramref name="angle"/> is less /// than or equal to <paramref name="falloffAngle"/>. 0 when <paramref name="angle"/> is /// greater than or equal to <paramref name="cutoffAngle"/>.) /// </returns> /// <remarks> /// <para> /// The falloff between <paramref name="falloffAngle"/> and <paramref name="cutoffAngle"/> is /// computed using a smoothstep function (see /// <see cref="InterpolationHelper.HermiteSmoothStep(float)"/>). /// </para> /// <para> /// <i>angularAttenuation</i> = smoothstep((cos(<i>angle</i>) - cos(<i>cutoffAngle</i>)) / /// (cos(<i>falloffAngle</i>) - cos(<i>cutoffAngle</i>))) /// </para> /// </remarks> public static float GetAngularAttenuation(float angle, float falloffAngle, float cutoffAngle) { if (angle < 0) { angle = -angle; } if (angle <= falloffAngle) { return(1.0f); } if (angle >= cutoffAngle) { return(0.0f); } float cosOuterCone = (float)Math.Cos(cutoffAngle); float cosInnerCone = (float)Math.Cos(falloffAngle); float cosAngle = (float)Math.Cos(angle); float cosDiff = cosInnerCone - cosOuterCone; if (Numeric.IsZero(cosDiff)) { return(0.0f); } float x = (cosAngle - cosOuterCone) / cosDiff; return(InterpolationHelper.HermiteSmoothStep(x)); }
public void CosineInterpolationSinglePrecision() { Assert.AreEqual(1.0f, InterpolationHelper.CosineInterpolation(1.0f, 2.0f, 0.0f)); Assert.AreEqual(1.5f, InterpolationHelper.CosineInterpolation(1.0f, 2.0f, 0.5f)); Assert.AreEqual(2.0f, InterpolationHelper.CosineInterpolation(1.0f, 2.0f, 1.0f)); Assert.AreEqual(1.5f, InterpolationHelper.CosineInterpolation(2.0f, 1.0f, 0.5f)); }
public void CosineInterpolationDoublePrecision() { Assert.AreEqual(1.0, InterpolationHelper.CosineInterpolation(1.0, 2.0, 0.0)); Assert.AreEqual(1.5, InterpolationHelper.CosineInterpolation(1.0, 2.0, 0.5)); Assert.AreEqual(2.0, InterpolationHelper.CosineInterpolation(1.0, 2.0, 1.0)); Assert.AreEqual(1.5, InterpolationHelper.CosineInterpolation(2.0, 1.0, 0.5)); }
public bool GetDisplacement(float x, float z, out Vector3F displacement, out Vector3F normal) { if (!EnableCpuQueries) { throw new InvalidOperationException("OceanWaves.GetDisplacement() can only be called if EnableCpuQueries is set to true."); } displacement = new Vector3F(0); normal = new Vector3F(0, 1, 0); if (_h == null) { return(false); } float texCoordX = (x - TileCenter.X) / TileSize + 0.5f; float texCoordY = (z - TileCenter.Z) / TileSize + 0.5f; // Point sampling or bilinear filtering: #if false // Convert to array indices. int xIndex = Wrap((int)(texCoordX * CpuSize)); int yIndex = Wrap((int)(texCoordY * CpuSize)); float h = _h[xIndex, yIndex].X; Vector2F d = _D[xIndex, yIndex]; Vector2F n = _N[xIndex, yIndex]; #else // Sample 4 values. The upper left index is (without wrapping): float xIndex = texCoordX * CpuSize - 0.5f; float yIndex = texCoordY * CpuSize - 0.5f; // Get the 4 indices. int x0 = Wrap((int)xIndex); int x1 = Wrap((int)xIndex + 1); int y0 = Wrap((int)yIndex); int y1 = Wrap((int)yIndex + 1); // Get fractions to use as lerp parameters. float px = MathHelper.Frac(xIndex); float py = MathHelper.Frac(yIndex); float h = InterpolationHelper.Lerp(InterpolationHelper.Lerp(_h[x0, y0].X, _h[x1, y0].X, px), InterpolationHelper.Lerp(_h[x0, y1].X, _h[x1, y1].X, px), py); Vector2F d = InterpolationHelper.Lerp(InterpolationHelper.Lerp(_D[x0, y0], _D[x1, y0], px), InterpolationHelper.Lerp(_D[x0, y1], _D[x1, y1], px), py); Vector2F n = InterpolationHelper.Lerp(InterpolationHelper.Lerp(_N[x0, y0], _N[x1, y0], px), InterpolationHelper.Lerp(_N[x0, y1], _N[x1, y1], px), py); #endif displacement = new Vector3F(-d.X * Choppiness, h, -d.Y * Choppiness); normal = new Vector3F(-n.X, 0, -n.Y); normal.Y = (float)Math.Sqrt(1 - normal.X * normal.X - normal.Y * normal.Y); return(true); }
//public void resetInterpolationTime() //{ // m_elapsedTime = 0.0f; //} // Updates the transform based on the behavior. // Returns true if the state of the transform changed. public virtual bool tryMove(Transform transform, float deltaTime = 0.0f) { Vector3 prevPosition = transform.position; Vector3 newPosition = prevPosition; //TODO: FIX THIS TO ALLOW UPDATING OVER THE RIGIDBODY FORCE APPLICATION TIMER UPDATING. // If an interpolator was given, use the interpolated position. if (m_interpolator != null) { if (m_interpolationTime < m_interpolator.duration) { m_interpolationTime = Mathf.Min(m_interpolationTime + deltaTime, m_interpolator.duration); newPosition = InterpolationHelper.getInterpolatedVector3(m_interpolator, m_interpolationTime); } } // Otherwise get the final target position. else { newPosition = getTargetPosition(transform, deltaTime); } //if(m_moveRelative) //{ // transform.forward = //} //else //{ transform.position = newPosition; //} return(true); //!prevPosition.Equals(transform.position); }
public void SamplingKeyFrames() { var keyFrame0 = new KeyFrame <QuaternionF>(TimeSpan.FromSeconds(1.0), _random.NextQuaternionF()); var keyFrame1 = new KeyFrame <QuaternionF>(TimeSpan.FromSeconds(2.0), _random.NextQuaternionF()); var keyFrame2 = new KeyFrame <QuaternionF>(TimeSpan.FromSeconds(3.0), _random.NextQuaternionF()); var animation = new QuaternionFKeyFrameAnimation(); animation.KeyFrames.Add(keyFrame0); animation.KeyFrames.Add(keyFrame1); animation.KeyFrames.Add(keyFrame2); var defaultSource = _random.NextQuaternionF(); var defaultTarget = _random.NextQuaternionF(); // Without interpolation animation.EnableInterpolation = false; Assert.AreEqual(keyFrame0.Value, animation.GetValue(TimeSpan.FromSeconds(1.0), defaultSource, defaultTarget)); Assert.AreEqual(keyFrame0.Value, animation.GetValue(TimeSpan.FromSeconds(1.75), defaultSource, defaultTarget)); Assert.AreEqual(keyFrame1.Value, animation.GetValue(TimeSpan.FromSeconds(2.0), defaultSource, defaultTarget)); Assert.AreEqual(keyFrame1.Value, animation.GetValue(TimeSpan.FromSeconds(2.75), defaultSource, defaultTarget)); Assert.AreEqual(keyFrame2.Value, animation.GetValue(TimeSpan.FromSeconds(3.0), defaultSource, defaultTarget)); // With interpolation animation.EnableInterpolation = true; Assert.IsTrue(QuaternionF.AreNumericallyEqual(keyFrame0.Value, animation.GetValue(TimeSpan.FromSeconds(1.0), defaultSource, defaultTarget))); var expected = InterpolationHelper.Lerp(keyFrame0.Value, keyFrame1.Value, 0.75f); Assert.AreEqual(expected, animation.GetValue(TimeSpan.FromSeconds(1.75), defaultSource, defaultTarget)); Assert.AreEqual(keyFrame1.Value, animation.GetValue(TimeSpan.FromSeconds(2.0), defaultSource, defaultTarget)); expected = InterpolationHelper.Lerp(keyFrame1.Value, keyFrame2.Value, 0.75f); Assert.AreEqual(expected, animation.GetValue(TimeSpan.FromSeconds(2.75), defaultSource, defaultTarget)); Assert.AreEqual(keyFrame2.Value, animation.GetValue(TimeSpan.FromSeconds(3.0), defaultSource, defaultTarget)); }
public void CyclicOffsetLoopBehavior() { var keyFrame0 = new KeyFrame <QuaternionF>(TimeSpan.FromSeconds(0.0), _random.NextQuaternionF()); var keyFrame1 = new KeyFrame <QuaternionF>(TimeSpan.FromSeconds(1.0), _random.NextQuaternionF()); var keyFrame2 = new KeyFrame <QuaternionF>(TimeSpan.FromSeconds(2.0), _random.NextQuaternionF()); var animation = new QuaternionFKeyFrameAnimation(); animation.KeyFrames.Add(keyFrame0); animation.KeyFrames.Add(keyFrame1); animation.KeyFrames.Add(keyFrame2); var animationClip = new AnimationClip <QuaternionF> { Animation = animation }; animationClip.LoopBehavior = LoopBehavior.CycleOffset; animationClip.Duration = TimeSpan.MaxValue; animationClip.ClipOffset = TimeSpan.FromSeconds(-1); var defaultSource = _random.NextQuaternionF(); var defaultTarget = _random.NextQuaternionF(); // Pre loop var cycleOffset = keyFrame2.Value * keyFrame0.Value.Inverse; var expected = InterpolationHelper.Lerp(keyFrame1.Value, keyFrame2.Value, 0.25f); Assert.IsTrue(QuaternionF.AreNumericallyEqual(expected, cycleOffset * animationClip.GetValue(TimeSpan.FromSeconds(0.25), defaultSource, defaultTarget))); // Post loop expected = cycleOffset * cycleOffset * InterpolationHelper.Lerp(keyFrame1.Value, keyFrame2.Value, 0.75f); Assert.IsTrue(QuaternionF.AreNumericallyEqual(expected, animationClip.GetValue(TimeSpan.FromSeconds(6.75), defaultSource, defaultTarget))); }
public void PolynomialInterpolationDoublePrecisionException3() { // Error: 2 identical x values. var points = new[] { new Vector2D(0, 1), new Vector2D(0, 4), new Vector2D(5, -1) }; InterpolationHelper.PolynomialInterpolation(points, 0); }
public static void GetSunlight(float altitude, float turbidity, Vector3D sunDirection, out Vector3F directSunlight, out Vector3F scatteredSunlight) { _spectrum.SetSolarSpectrum(); sunDirection.TryNormalize(); double cosZenith = sunDirection.Y; Vector3F direct, indirect; if (cosZenith > 0) { // Daylight - Sun is above horizon. double zenithAngle = Math.Acos(cosZenith); _spectrum.ApplyAtmosphericTransmittance(zenithAngle, turbidity, altitude, _spectrumDirect, _spectrumIndirect); direct = _spectrumDirect.ToXYZ(); indirect = _spectrumIndirect.ToXYZ(); } else { // Twilight - Sun is below horizon. // We lookup luminance based on experimental results on cloudless nights. // Get sun angle in degrees for table lookup. float solarAltitude = (float)MathHelper.ToDegrees(Math.Asin(sunDirection.Y)); // Get luminance from table (linearly interpolating the next two table entries). int lower = (int)Math.Floor(solarAltitude); int higher = (int)Math.Ceiling(solarAltitude); float a, b; TwilightLuminance.TryGetValue(lower, out a); TwilightLuminance.TryGetValue(higher, out b); float Y = InterpolationHelper.Lerp(a, b, solarAltitude - lower); // We use fixed chromacity values. float x = 0.2f; float y = 0.2f; // Convert xyY to XYZ. float X = x * (Y / y); float Z = (1.0f - x - y) * (Y / y); // Get sunlight from slightly above the horizon. const float epsilon = 0.001f; const double zenithAngle = ConstantsD.PiOver2 - epsilon; _spectrum.ApplyAtmosphericTransmittance(zenithAngle, turbidity, altitude, _spectrumDirect, _spectrumIndirect); direct = _spectrumDirect.ToXYZ(); indirect = _spectrumIndirect.ToXYZ(); // Blend between table values and sunset light. float blend = MathHelper.Clamp(-solarAltitude / 5.0f, 0, 1); direct = InterpolationHelper.Lerp(direct, new Vector3F(0, 0, 0), blend); indirect = InterpolationHelper.Lerp(indirect, new Vector3F(X, Y, Z), blend); } // Convert XYZ to RGB. directSunlight = GraphicsHelper.XYZToRGB * direct; scatteredSunlight = GraphicsHelper.XYZToRGB * indirect; }
public void PolynomialInterpolationDoublePrecision() { var points = new[] { new Vector2D(0, 1), new Vector2D(3, 4), new Vector2D(5, -1) }; Assert.IsTrue(Numeric.AreEqual(points[0].Y, InterpolationHelper.PolynomialInterpolation(points, points[0].X))); Assert.IsTrue(Numeric.AreEqual(points[1].Y, InterpolationHelper.PolynomialInterpolation(points, points[1].X))); Assert.IsTrue(Numeric.AreEqual(points[2].Y, InterpolationHelper.PolynomialInterpolation(points, points[2].X))); }
private void RenderDebugInfo(RenderContext context) { _debugRenderer.Clear(); _debugRenderer.DrawAxes(Pose.Identity, 0.5f, true); //_debugRenderer.DrawTexture(_cloudLayerNode._renderTarget, new Rectangle(1280-512, 0, 512, 512)); #if XBOX _debugRenderer.DrawText(_ephemeris.Time.DateTime.ToString()); #else _debugRenderer.DrawText(_ephemeris.Time.ToString()); #endif _debugRenderer.PointSize = 10; var extraterrestrialSunlight = Ephemeris.ExtraterrestrialSunlight; Vector3F sun; Vector3F ambient; Ephemeris.GetSunlight(_scatteringSky.ObserverAltitude, 2.2f, _scatteringSky.SunDirection, out sun, out ambient); var scatterSun = _scatteringSky.GetSunlight() / _scatteringSky.SunIntensity * extraterrestrialSunlight; var scatterAmbient = _scatteringSky.GetAmbientLight(1024); scatterAmbient = scatterAmbient / _scatteringSky.SunIntensity * extraterrestrialSunlight; var scatterFog = _scatteringSky.GetFogColor(128) / _scatteringSky.SunIntensity * extraterrestrialSunlight; var luminance = Vector3F.Dot(GraphicsHelper.LuminanceWeights, scatterFog); scatterFog = InterpolationHelper.Lerp(scatterFog, new Vector3F(luminance), 0.7f); _debugRenderer.DrawText("Extraterrestrial sun intensity:" + extraterrestrialSunlight.Length); _debugRenderer.DrawText("Spectrum sun intensity:" + sun.Length); _debugRenderer.DrawText("Scatter sun intensity:" + scatterSun.Length); _debugRenderer.DrawText("\nSpectrum ambient intensity:" + ambient.Length); _debugRenderer.DrawText("Scatter ambient intensity:" + scatterAmbient.Length); _debugRenderer.DrawText("\nScatter fog intensity:" + scatterFog.Length); _debugRenderer.DrawPoint(new Vector3F(-0.5f, 0, 0), new Color((Vector3)extraterrestrialSunlight.Normalized), true); sun.TryNormalize(); ambient /= ambient.Length; _debugRenderer.DrawPoint(new Vector3F(0, 0, 0), new Color((Vector3)sun), true); _debugRenderer.DrawPoint(new Vector3F(0, -0.5f, 0), new Color((Vector3)ambient), true); scatterSun.TryNormalize(); scatterAmbient.TryNormalize(); _debugRenderer.DrawPoint(new Vector3F(0.5f, 0, 0), new Color((Vector3)scatterSun), true); _debugRenderer.DrawPoint(new Vector3F(0.5f, -0.5f, 0), new Color((Vector3)scatterAmbient), true); scatterFog.TryNormalize(); _debugRenderer.DrawPoint(new Vector3F(0, 0.5f, 0), new Color((Vector3)scatterFog), true); _debugRenderer.PointSize = 40f; _debugRenderer.Render(context); }
public void HermiteSmoothStepF() { Assert.IsTrue(Numeric.AreEqual(0, InterpolationHelper.HermiteSmoothStep(-1.0))); Assert.IsTrue(Numeric.AreEqual(0, InterpolationHelper.HermiteSmoothStep(0.0))); Assert.IsTrue(Numeric.AreEqual(0.5, InterpolationHelper.HermiteSmoothStep(0.5))); Assert.IsTrue(Numeric.AreEqual(1, InterpolationHelper.HermiteSmoothStep(1.0))); Assert.IsTrue(Numeric.AreEqual(1, InterpolationHelper.HermiteSmoothStep(2.0))); Assert.IsTrue(Numeric.AreEqual(1 - InterpolationHelper.HermiteSmoothStep(1 - 0.3), InterpolationHelper.HermiteSmoothStep(0.3))); Assert.Greater(InterpolationHelper.HermiteSmoothStep(1 - 0.3), InterpolationHelper.HermiteSmoothStep(0.3)); }
public void InterpolationTest() { var traits = QuaternionTraits.Instance; var value0 = (Quaternion)_random.NextQuaternionF(); var value1 = (Quaternion)_random.NextQuaternionF(); Assert.IsTrue(QuaternionF.AreNumericallyEqual((QuaternionF)value0, (QuaternionF)traits.Interpolate(value0, value1, 0.0f))); Assert.IsTrue(QuaternionF.AreNumericallyEqual((QuaternionF)value1, (QuaternionF)traits.Interpolate(value0, value1, 1.0f))); Assert.IsTrue(QuaternionF.AreNumericallyEqual(InterpolationHelper.Lerp((QuaternionF)value0, (QuaternionF)value1, 0.75f), (QuaternionF)traits.Interpolate(value0, value1, 0.75f))); }
public void SlerpNegatedDoublePrecision() { QuaternionD q1 = new QuaternionD(-1.0, 0.0, 0.0, 0.0); QuaternionD q2 = QuaternionD.CreateRotation(-Vector3.UnitZ, -Math.PI / 2); QuaternionD slerp = InterpolationHelper.Slerp(q1, q2, 0.5); Assert.IsTrue(slerp.IsNumericallyNormalized); Vector3D v = slerp.Rotate(Vector3D.UnitX); Vector3D result = new Vector3D(1.0, 1.0, 0.0).Normalized; Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); }
public void SlerpXSinglePrecision() { QuaternionF q1 = QuaternionF.Identity; QuaternionF q2 = QuaternionF.CreateRotation(Vector3F.UnitX, (float)Math.PI / 2); QuaternionF slerp = InterpolationHelper.Slerp(q1, q2, 0.5f); Assert.IsTrue(slerp.IsNumericallyNormalized); Vector3F v = slerp.Rotate(Vector3F.UnitY); Vector3F result = new Vector3F(0.0f, 1.0f, 1.0f).Normalized; Assert.IsTrue(Vector3F.AreNumericallyEqual(result, v)); }
public void Lerp() { Assert.AreEqual(1.0f, InterpolationHelper.Lerp(1.0f, 2.0f, 0.0f)); Assert.AreEqual(1.5f, InterpolationHelper.Lerp(1.0f, 2.0f, 0.5f)); Assert.AreEqual(2.0f, InterpolationHelper.Lerp(1.0f, 2.0f, 1.0f)); Assert.AreEqual(1.5f, InterpolationHelper.Lerp(2.0f, 1.0f, 0.5f)); Assert.AreEqual(1.0, InterpolationHelper.Lerp(1.0, 2.0, 0.0)); Assert.AreEqual(1.5, InterpolationHelper.Lerp(1.0, 2.0, 0.5)); Assert.AreEqual(2.0, InterpolationHelper.Lerp(1.0, 2.0, 1.0)); Assert.AreEqual(1.5, InterpolationHelper.Lerp(2.0, 1.0, 0.5)); }
public void CosineInterpolationVector4() { Vector4 v = new Vector4(1.0f, 10.0f, 100.0f, 1000.0f); Vector4 w = new Vector4(2.0f, 20.0f, 200.0f, 2000.0f); Vector4 lerp0 = InterpolationHelper.CosineInterpolation(v, w, 0.0f); Vector4 lerp1 = InterpolationHelper.CosineInterpolation(v, w, 1.0f); Vector4 lerp05 = InterpolationHelper.CosineInterpolation(v, w, 0.5f); Assert.AreEqual(v, lerp0); Assert.AreEqual(w, lerp1); Assert.AreEqual(new Vector4(1.5f, 15.0f, 150.0f, 1500.0f), lerp05); }
public void CosineInterpolationVectorF() { VectorF v = new VectorF(new[] { 1.0f, 10.0f, 100.0f, 1000.0f }); VectorF w = new VectorF(new[] { 2.0f, 20.0f, 200.0f, 2000.0f }); VectorF lerp0 = InterpolationHelper.CosineInterpolation(v, w, 0.0f); VectorF lerp1 = InterpolationHelper.CosineInterpolation(v, w, 1.0f); VectorF lerp05 = InterpolationHelper.CosineInterpolation(v, w, 0.5f); Assert.AreEqual(v, lerp0); Assert.AreEqual(w, lerp1); Assert.AreEqual(new VectorF(new[] { 1.5f, 15.0f, 150.0f, 1500.0f }), lerp05); }
public void SlerpXDoublePrecision() { QuaternionD q1 = QuaternionD.Identity; QuaternionD q2 = QuaternionD.CreateRotation(Vector3.UnitX, Math.PI / 2); QuaternionD slerp = InterpolationHelper.Slerp(q1, q2, 0.5); Assert.IsTrue(slerp.IsNumericallyNormalized); Vector3D v = slerp.Rotate(Vector3.UnitY); Vector3D result = new Vector3D(0.0, 1.0, 1.0).Normalized; Assert.IsTrue(Vector3D.AreNumericallyEqual(result, v)); }
public void CosineInterpolationVectorD() { VectorD v = new VectorD(new[] { 1.0, 10.0, 100.0, 1000.0 }); VectorD w = new VectorD(new[] { 2.0, 20.0, 200.0, 2000.0 }); VectorD lerp0 = InterpolationHelper.CosineInterpolation(v, w, 0.0); VectorD lerp1 = InterpolationHelper.CosineInterpolation(v, w, 1.0); VectorD lerp05 = InterpolationHelper.CosineInterpolation(v, w, 0.5); Assert.AreEqual(v, lerp0); Assert.AreEqual(w, lerp1); Assert.IsTrue(VectorD.AreNumericallyEqual(new VectorD(new[] { 1.5, 15.0, 150.0, 1500.0 }), lerp05)); }
public void SlerpNegatedSinglePrecision() { Quaternion q1 = new Quaternion(-1.0f, 0.0f, 0.0f, 0.0f); Quaternion q2 = Quaternion.CreateFromRotationMatrix(-Vector3.UnitZ, (float)-Math.PI / 2); Quaternion slerp = InterpolationHelper.Slerp(q1, q2, 0.5f); Assert.IsTrue(slerp.IsNumericallyNormalized); Vector3 v = slerp.Rotate(Vector3.UnitX); Vector3 result = new Vector3(1.0f, 1.0f, 0.0f).Normalized; Assert.IsTrue(Vector3.AreNumericallyEqual(result, v)); }
/// <summary> /// Interpolates two poses. /// </summary> /// <param name="startPose">The start pose.</param> /// <param name="endPose">The end pose.</param> /// <param name="parameter"> /// The interpolation parameter. If the value is 0, the <paramref name="startPose"/> is /// returned. If the value is 1, the <paramref name="endPose"/> is returned. For values between /// 0 and 1 an interpolated pose is returned. /// </param> /// <returns>An interpolated pose.</returns> public static Pose Interpolate(Pose startPose, Pose endPose, float parameter) { // Linearly interpolate position. var interpolatedPosition = startPose.Position * (1 - parameter) + endPose.Position * parameter; // Slerp orientation. var interpolatedOrientation = InterpolationHelper.Lerp( Quaternion.CreateFromRotationMatrix(startPose.Orientation), Quaternion.CreateFromRotationMatrix(endPose.Orientation), parameter); return(new Pose(interpolatedPosition, interpolatedOrientation)); }
public void AnimateUsingDefaults() { var defaultSource = _random.NextQuaternion(); var defaultTarget = _random.NextQuaternion(); var animation = new QuaternionFromToByAnimation(); animation.From = null; animation.To = null; animation.By = null; Assert.AreEqual(defaultSource, animation.GetValue(TimeSpan.FromSeconds(0.0), defaultSource, defaultTarget)); Assert.IsTrue(Quaternion.AreNumericallyEqual(InterpolationHelper.Lerp(defaultSource, defaultTarget, 0.75f), animation.GetValue(TimeSpan.FromSeconds(0.75), defaultSource, defaultTarget))); Assert.AreEqual(defaultTarget, animation.GetValue(TimeSpan.FromSeconds(1.0), defaultSource, defaultTarget)); }
public void EaseInOutSmoothStepF() { Assert.IsTrue(Numeric.AreEqual(0, InterpolationHelper.EaseInOutSmoothStep(-1.0f))); Assert.IsTrue(Numeric.AreEqual(0, InterpolationHelper.EaseInOutSmoothStep(0.0f))); Assert.IsTrue(Numeric.AreEqual(0.5, InterpolationHelper.EaseInOutSmoothStep(0.5f))); Assert.IsTrue(Numeric.AreEqual(1, InterpolationHelper.EaseInOutSmoothStep(1.0f))); Assert.IsTrue(Numeric.AreEqual(1, InterpolationHelper.EaseInOutSmoothStep(2.0f))); Assert.IsTrue(Numeric.AreEqual(1 - InterpolationHelper.EaseInOutSmoothStep(1 - 0.3f), InterpolationHelper.EaseInOutSmoothStep(0.3f))); Assert.Greater(InterpolationHelper.EaseInOutSmoothStep(1 - 0.3f), InterpolationHelper.EaseInOutSmoothStep(0.3f)); Assert.Greater(0.5f, InterpolationHelper.EaseInOutSmoothStep(0.3f)); Assert.Less(0.5f, InterpolationHelper.EaseInOutSmoothStep(0.6f)); }
/// <summary> /// Interpolates two poses. /// </summary> /// <param name="startPose">The start pose.</param> /// <param name="endPose">The end pose.</param> /// <param name="parameter"> /// The interpolation parameter. If the value is 0, the <paramref name="startPose"/> is /// returned. If the value is 1, the <paramref name="endPose"/> is returned. For values between /// 0 and 1 an interpolated pose is returned. /// </param> /// <returns>An interpolated pose.</returns> public static PoseD Interpolate(PoseD startPose, PoseD endPose, double parameter) { // Linearly interpolate position. var interpolatedPosition = startPose.Position * (1 - parameter) + endPose.Position * parameter; // Slerp orientation. var interpolatedOrientation = InterpolationHelper.Lerp( QuaternionD.CreateRotation(startPose.Orientation), QuaternionD.CreateRotation(endPose.Orientation), parameter); return(new PoseD(interpolatedPosition, interpolatedOrientation)); }
public void LerpVector4() { Vector4 v = new Vector4(1.0f, 10.0f, 100.0f, 1000.0f); Vector4 w = new Vector4(2.0f, 20.0f, 200.0f, 2000.0f); Vector4 lerp0 = InterpolationHelper.Lerp(v, w, 0.0f); Vector4 lerp1 = InterpolationHelper.Lerp(v, w, 1.0f); Vector4 lerp05 = InterpolationHelper.Lerp(v, w, 0.5f); Vector4 lerp025 = InterpolationHelper.Lerp(v, w, 0.25f); Assert.AreEqual(v, lerp0); Assert.AreEqual(w, lerp1); Assert.AreEqual(new Vector4(1.5f, 15.0f, 150.0f, 1500.0f), lerp05); Assert.AreEqual(new Vector4(1.25f, 12.5f, 125.0f, 1250.0f), lerp025); }
public float GetValue(float frame) { if (Keys.Count == 0) { return(0); } float startFrame = Keys.First().Frame; Animation.KeyFrame LK = Keys.First(); Animation.KeyFrame RK = Keys.Last(); foreach (Animation.KeyFrame keyFrame in Keys) { if (keyFrame.Frame <= frame) { LK = keyFrame; } if (keyFrame.Frame >= frame && keyFrame.Frame < RK.Frame) { RK = keyFrame; } } if (LK.Frame != RK.Frame) { // float FrameDiff = frame - LK.Frame; // float Weight = 1.0f / (RK.Frame - LK.Frame); // float Weight = FrameDiff / (RK.Frame - LK.Frame); float FrameDiff = frame - LK.Frame; float Weight = FrameDiff / (RK.Frame - LK.Frame); Console.WriteLine($"frame diff {FrameDiff} frame {frame} LK {LK.Frame} RK {RK} ratio {Weight}"); switch (InterpolationType) { case InterpolationType.CONSTANT: return(LK.Value); case InterpolationType.STEP: return(LK.Value); case InterpolationType.LINEAR: return(InterpolationHelper.Lerp(LK.Value, RK.Value, Weight)); case InterpolationType.HERMITE: float val = Hermite(frame, LK.Frame, RK.Frame, LK.In, LK.Out != -1 ? LK.Out : RK.In, LK.Value, RK.Value); return(val); } } return(LK.Value); }