- Barotrauma's projects are in the Barotrauma directory - All libraries are in the Libraries directory - MonoGame is now managed by NuGet, rather than referenced from the installed files (TODO: consider using PCL for easier cross-platform development?) - NuGet libraries are not included in the repo, as getting the latest versions automatically should be preferred - Removed Content/effects.mgfx as it didn't seem to be used anywhere - Removed some references to Subsurface directory - Renamed Launcher2 to Launcher
273 lines
9.0 KiB
C#
273 lines
9.0 KiB
C#
#if !XNA && !WINDOWS_PHONE && !XBOX && !ANDROID
|
|
|
|
#region License
|
|
|
|
/*
|
|
MIT License
|
|
Copyright © 2006 The Mono.Xna Team
|
|
|
|
All rights reserved.
|
|
|
|
Authors:
|
|
Olivier Dufour (Duff)
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in all
|
|
copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
#endregion License
|
|
|
|
using System;
|
|
|
|
namespace Microsoft.Xna.Framework
|
|
{
|
|
public enum CurveLoopType
|
|
{
|
|
Constant,
|
|
Cycle,
|
|
CycleOffset,
|
|
Oscillate,
|
|
Linear
|
|
}
|
|
|
|
public enum CurveContinuity
|
|
{
|
|
Smooth,
|
|
Step
|
|
}
|
|
|
|
public enum CurveTangent
|
|
{
|
|
Flat,
|
|
Linear,
|
|
Smooth
|
|
}
|
|
|
|
public class Curve
|
|
{
|
|
#region Private Fields
|
|
|
|
private CurveKeyCollection keys;
|
|
private CurveLoopType postLoop;
|
|
private CurveLoopType preLoop;
|
|
|
|
#endregion Private Fields
|
|
|
|
#region Public Properties
|
|
|
|
public bool IsConstant
|
|
{
|
|
get { return keys.Count <= 1; }
|
|
}
|
|
|
|
public CurveKeyCollection Keys
|
|
{
|
|
get { return keys; }
|
|
}
|
|
|
|
public CurveLoopType PostLoop
|
|
{
|
|
get { return postLoop; }
|
|
set { postLoop = value; }
|
|
}
|
|
|
|
public CurveLoopType PreLoop
|
|
{
|
|
get { return preLoop; }
|
|
set { preLoop = value; }
|
|
}
|
|
|
|
#endregion Public Properties
|
|
|
|
#region Public Constructors
|
|
|
|
public Curve()
|
|
{
|
|
keys = new CurveKeyCollection();
|
|
}
|
|
|
|
#endregion Public Constructors
|
|
|
|
#region Public Methods
|
|
|
|
public void ComputeTangent(int keyIndex, CurveTangent tangentInType, CurveTangent tangentOutType)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void ComputeTangent(int keyIndex, CurveTangent tangentType)
|
|
{
|
|
ComputeTangent(keyIndex, tangentType, tangentType);
|
|
}
|
|
|
|
public void ComputeTangents(CurveTangent tangentInType, CurveTangent tangentOutType)
|
|
{
|
|
throw new NotImplementedException();
|
|
}
|
|
|
|
public void ComputeTangents(CurveTangent tangentType)
|
|
{
|
|
ComputeTangents(tangentType, tangentType);
|
|
}
|
|
|
|
public Curve Clone()
|
|
{
|
|
Curve curve = new Curve();
|
|
|
|
curve.keys = keys.Clone();
|
|
curve.preLoop = preLoop;
|
|
curve.postLoop = postLoop;
|
|
|
|
return curve;
|
|
}
|
|
|
|
public float Evaluate(float position)
|
|
{
|
|
CurveKey first = keys[0];
|
|
CurveKey last = keys[keys.Count - 1];
|
|
|
|
if (position < first.Position)
|
|
{
|
|
switch (PreLoop)
|
|
{
|
|
case CurveLoopType.Constant:
|
|
//constant
|
|
return first.Value;
|
|
|
|
case CurveLoopType.Linear:
|
|
// linear y = a*x +b with a tangeant of last point
|
|
return first.Value - first.TangentIn*(first.Position - position);
|
|
|
|
case CurveLoopType.Cycle:
|
|
//start -> end / start -> end
|
|
int cycle = GetNumberOfCycle(position);
|
|
float virtualPos = position - (cycle*(last.Position - first.Position));
|
|
return GetCurvePosition(virtualPos);
|
|
|
|
case CurveLoopType.CycleOffset:
|
|
//make the curve continue (with no step) so must up the curve each cycle of delta(value)
|
|
cycle = GetNumberOfCycle(position);
|
|
virtualPos = position - (cycle*(last.Position - first.Position));
|
|
return (GetCurvePosition(virtualPos) + cycle*(last.Value - first.Value));
|
|
|
|
case CurveLoopType.Oscillate:
|
|
//go back on curve from end and target start
|
|
// start-> end / end -> start
|
|
cycle = GetNumberOfCycle(position);
|
|
if (0 == cycle%2f) //if pair
|
|
virtualPos = position - (cycle*(last.Position - first.Position));
|
|
else
|
|
virtualPos = last.Position - position + first.Position +
|
|
(cycle*(last.Position - first.Position));
|
|
return GetCurvePosition(virtualPos);
|
|
}
|
|
}
|
|
else if (position > last.Position)
|
|
{
|
|
int cycle;
|
|
switch (PostLoop)
|
|
{
|
|
case CurveLoopType.Constant:
|
|
//constant
|
|
return last.Value;
|
|
|
|
case CurveLoopType.Linear:
|
|
// linear y = a*x +b with a tangeant of last point
|
|
return last.Value + first.TangentOut*(position - last.Position);
|
|
|
|
case CurveLoopType.Cycle:
|
|
//start -> end / start -> end
|
|
cycle = GetNumberOfCycle(position);
|
|
float virtualPos = position - (cycle*(last.Position - first.Position));
|
|
return GetCurvePosition(virtualPos);
|
|
|
|
case CurveLoopType.CycleOffset:
|
|
//make the curve continue (with no step) so must up the curve each cycle of delta(value)
|
|
cycle = GetNumberOfCycle(position);
|
|
virtualPos = position - (cycle*(last.Position - first.Position));
|
|
return (GetCurvePosition(virtualPos) + cycle*(last.Value - first.Value));
|
|
|
|
case CurveLoopType.Oscillate:
|
|
//go back on curve from end and target start
|
|
// start-> end / end -> start
|
|
cycle = GetNumberOfCycle(position);
|
|
virtualPos = position - (cycle*(last.Position - first.Position));
|
|
if (0 == cycle%2f) //if pair
|
|
virtualPos = position - (cycle*(last.Position - first.Position));
|
|
else
|
|
virtualPos = last.Position - position + first.Position +
|
|
(cycle*(last.Position - first.Position));
|
|
return GetCurvePosition(virtualPos);
|
|
}
|
|
}
|
|
|
|
//in curve
|
|
return GetCurvePosition(position);
|
|
}
|
|
|
|
#endregion Public Methods
|
|
|
|
#region Private Methods
|
|
|
|
private int GetNumberOfCycle(float position)
|
|
{
|
|
float cycle = (position - keys[0].Position)/(keys[keys.Count - 1].Position - keys[0].Position);
|
|
if (cycle < 0f)
|
|
cycle--;
|
|
return (int) cycle;
|
|
}
|
|
|
|
private float GetCurvePosition(float position)
|
|
{
|
|
//only for position in curve
|
|
CurveKey prev = keys[0];
|
|
CurveKey next;
|
|
for (int i = 1; i < keys.Count; i++)
|
|
{
|
|
next = Keys[i];
|
|
if (next.Position >= position)
|
|
{
|
|
if (prev.Continuity == CurveContinuity.Step)
|
|
{
|
|
if (position >= 1f)
|
|
{
|
|
return next.Value;
|
|
}
|
|
return prev.Value;
|
|
}
|
|
float t = (position - prev.Position)/(next.Position - prev.Position); //to have t in [0,1]
|
|
float ts = t*t;
|
|
float tss = ts*t;
|
|
//After a lot of search on internet I have found all about spline function
|
|
// and bezier (phi'sss ancien) but finaly use hermite curve
|
|
//http://en.wikipedia.org/wiki/Cubic_Hermite_spline
|
|
//P(t) = (2*t^3 - 3t^2 + 1)*P0 + (t^3 - 2t^2 + t)m0 + (-2t^3 + 3t^2)P1 + (t^3-t^2)m1
|
|
//with P0.value = prev.value , m0 = prev.tangentOut, P1= next.value, m1 = next.TangentIn
|
|
return (2*tss - 3*ts + 1f)*prev.Value + (tss - 2*ts + t)*prev.TangentOut + (3*ts - 2*tss)*next.Value +
|
|
(tss - ts)*next.TangentIn;
|
|
}
|
|
prev = next;
|
|
}
|
|
return 0f;
|
|
}
|
|
|
|
#endregion
|
|
}
|
|
}
|
|
|
|
#endif |