[csharp] Port of commit 0c269a07: "Spring constraint -> physics constraint.", added missing documentation lines.

This commit is contained in:
Harald Csaszar 2022-12-19 12:56:53 +01:00
parent 522e985de8
commit db39be9b89
6 changed files with 77 additions and 45 deletions

View File

@ -31,12 +31,12 @@ using System;
namespace Spine { namespace Spine {
/// <summary> /// <summary>
/// Stores the current pose for a spring constraint. A spring constraint applies physics to bones. /// Stores the current pose for a physics constraint. A physics constraint applies physics to bones.
/// <para> /// <para>
/// See <a href="http://esotericsoftware.com/spine-spring-constraints">Spring constraints</a> in the Spine User Guide.</para> /// See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide.</para>
/// </summary> /// </summary>
public class SpringConstraint : IUpdatable { public class PhysicsConstraint : IUpdatable {
internal readonly SpringConstraintData data; internal readonly PhysicsConstraintData data;
internal readonly ExposedList<Bone> bones; internal readonly ExposedList<Bone> bones;
// BOZO! - stiffness -> strength. stiffness, damping, rope, stretch -> move to spring. // BOZO! - stiffness -> strength. stiffness, damping, rope, stretch -> move to spring.
internal float mix, friction, gravity, wind, stiffness, damping; internal float mix, friction, gravity, wind, stiffness, damping;
@ -44,7 +44,7 @@ namespace Spine {
internal bool active; internal bool active;
public SpringConstraint (SpringConstraintData data, Skeleton skeleton) { public PhysicsConstraint (PhysicsConstraintData data, Skeleton skeleton) {
if (data == null) throw new ArgumentNullException("data", "data cannot be null."); if (data == null) throw new ArgumentNullException("data", "data cannot be null.");
if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
this.data = data; this.data = data;
@ -63,7 +63,7 @@ namespace Spine {
} }
/// <summary>Copy constructor.</summary> /// <summary>Copy constructor.</summary>
public SpringConstraint (SpringConstraint constraint, Skeleton skeleton) { public PhysicsConstraint (PhysicsConstraint constraint, Skeleton skeleton) {
if (constraint == null) throw new ArgumentNullException("constraint", "constraint cannot be null."); if (constraint == null) throw new ArgumentNullException("constraint", "constraint cannot be null.");
if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null."); if (skeleton == null) throw new ArgumentNullException("skeleton", "skeleton cannot be null.");
data = constraint.data; data = constraint.data;
@ -85,6 +85,8 @@ namespace Spine {
} }
/// <summary>The bones that will be modified by this physics constraint.</summary>
public ExposedList<Bone> Bones { get { return bones; } }
/// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained poses.</summary> /// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained poses.</summary>
public float Mix { get { return mix; } set { mix = value; } } public float Mix { get { return mix; } set { mix = value; } }
public float Friction { get { return friction; } set { friction = value; } } public float Friction { get { return friction; } set { friction = value; } }
@ -95,8 +97,8 @@ namespace Spine {
public bool Rope { get { return rope; } set { rope = value; } } public bool Rope { get { return rope; } set { rope = value; } }
public bool Stretch { get { return stretch; } set { stretch = value; } } public bool Stretch { get { return stretch; } set { stretch = value; } }
public bool Active { get { return active; } } public bool Active { get { return active; } }
/// <summary>The spring constraint's setup pose data.</summary> /// <summary>The physics constraint's setup pose data.</summary>
public SpringConstraintData Data { get { return data; } } public PhysicsConstraintData Data { get { return data; } }
override public string ToString () { override public string ToString () {
return data.name; return data.name;

View File

@ -31,19 +31,19 @@ using System;
namespace Spine { namespace Spine {
/// <summary> /// <summary>
/// Stores the setup pose for a <see cref="SpringConstraint"/>. /// Stores the setup pose for a <see cref="PhysicsConstraint"/>.
/// <para> /// <para>
/// See <a href="http://esotericsoftware.com/spine-spring-constraints">Spring constraints</a> in the Spine User Guide.</para> /// See <a href="http://esotericsoftware.com/spine-physics-constraints">Physics constraints</a> in the Spine User Guide.</para>
/// </summary> /// </summary>
public class SpringConstraintData : ConstraintData { public class PhysicsConstraintData : ConstraintData {
internal ExposedList<BoneData> bones = new ExposedList<BoneData>(); internal ExposedList<BoneData> bones = new ExposedList<BoneData>();
internal float mix, friction, gravity, wind, stiffness, damping; internal float mix, friction, gravity, wind, stiffness, damping;
internal bool rope, stretch; internal bool rope, stretch;
public SpringConstraintData (string name) : base(name) { public PhysicsConstraintData (string name) : base(name) {
} }
/// <summary>The bones that are constrained by this spring constraint.</summary> /// <summary>The bones that are constrained by this physics constraint.</summary>
public ExposedList<BoneData> Bones { get { return bones; } } public ExposedList<BoneData> Bones { get { return bones; } }
/// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained poses.</summary> /// <summary>A percentage (0-1) that controls the mix between the constrained and unconstrained poses.</summary>

View File

@ -38,23 +38,35 @@ namespace Spine {
internal ExposedList<IkConstraint> ikConstraints; internal ExposedList<IkConstraint> ikConstraints;
internal ExposedList<TransformConstraint> transformConstraints; internal ExposedList<TransformConstraint> transformConstraints;
internal ExposedList<PathConstraint> pathConstraints; internal ExposedList<PathConstraint> pathConstraints;
internal ExposedList<SpringConstraint> springConstraints; internal ExposedList<PhysicsConstraint> physicsConstraints;
internal ExposedList<IUpdatable> updateCache = new ExposedList<IUpdatable>(); internal ExposedList<IUpdatable> updateCache = new ExposedList<IUpdatable>();
internal Skin skin; internal Skin skin;
internal float r = 1, g = 1, b = 1, a = 1; internal float r = 1, g = 1, b = 1, a = 1;
internal float scaleX = 1, scaleY = 1; internal float scaleX = 1, scaleY = 1;
internal float x, y; internal float x, y;
/// <summary>The skeleton's setup pose data.</summary>
public SkeletonData Data { get { return data; } } public SkeletonData Data { get { return data; } }
/// <summary>The skeleton's bones, sorted parent first. The root bone is always the first bone.</summary>
public ExposedList<Bone> Bones { get { return bones; } } public ExposedList<Bone> Bones { get { return bones; } }
/// <summary>The list of bones and constraints, sorted in the order they should be updated,
/// as computed by <see cref="UpdateCache()"/>.</summary>
public ExposedList<IUpdatable> UpdateCacheList { get { return updateCache; } } public ExposedList<IUpdatable> UpdateCacheList { get { return updateCache; } }
/// <summary>The skeleton's slots.</summary>
public ExposedList<Slot> Slots { get { return slots; } } public ExposedList<Slot> Slots { get { return slots; } }
/// <summary>The skeleton's slots in the order they should be drawn.
/// The returned array may be modified to change the draw order.</summary>
public ExposedList<Slot> DrawOrder { get { return drawOrder; } } public ExposedList<Slot> DrawOrder { get { return drawOrder; } }
/// <summary>The skeleton's IK constraints.</summary>
public ExposedList<IkConstraint> IkConstraints { get { return ikConstraints; } } public ExposedList<IkConstraint> IkConstraints { get { return ikConstraints; } }
/// <summary>The skeleton's path constraints.</summary>
public ExposedList<PathConstraint> PathConstraints { get { return pathConstraints; } } public ExposedList<PathConstraint> PathConstraints { get { return pathConstraints; } }
public ExposedList<SpringConstraint> SpringConstraints { get { return springConstraints; } } /// <summary>The skeleton's physics constraints.</summary>
public ExposedList<PhysicsConstraint> PhysicsConstraints { get { return physicsConstraints; } }
/// <summary>The skeleton's transform constraints.</summary>
public ExposedList<TransformConstraint> TransformConstraints { get { return transformConstraints; } } public ExposedList<TransformConstraint> TransformConstraints { get { return transformConstraints; } }
/// <summary>The skeleton's current skin.</summary>
public Skin Skin { public Skin Skin {
/// <summary>The skeleton's current skin. May be null.</summary> /// <summary>The skeleton's current skin. May be null.</summary>
get { return skin; } get { return skin; }
@ -65,9 +77,21 @@ namespace Spine {
public float G { get { return g; } set { g = value; } } public float G { get { return g; } set { g = value; } }
public float B { get { return b; } set { b = value; } } public float B { get { return b; } set { b = value; } }
public float A { get { return a; } set { a = value; } } public float A { get { return a; } set { a = value; } }
/// <summary><para>The skeleton X position, which is added to the root bone worldX position.</para>
/// <para>
/// Bones that do not inherit translation are still affected by this property.</para></summary>
public float X { get { return x; } set { x = value; } } public float X { get { return x; } set { x = value; } }
/// <summary><para>The skeleton Y position, which is added to the root bone worldY position.</para>
/// <para>
/// Bones that do not inherit translation are still affected by this property.</para></summary>
public float Y { get { return y; } set { y = value; } } public float Y { get { return y; } set { y = value; } }
/// <summary><para> Scales the entire skeleton on the X axis.</para>
/// <para>
/// Bones that do not inherit scale are still affected by this property.</para></summary>
public float ScaleX { get { return scaleX; } set { scaleX = value; } } public float ScaleX { get { return scaleX; } set { scaleX = value; } }
/// <summary><para> Scales the entire skeleton on the Y axis.</para>
/// <para>
/// Bones that do not inherit scale are still affected by this property.</para></summary>
public float ScaleY { get { return scaleY * (Bone.yDown ? -1 : 1); } set { scaleY = value; } } public float ScaleY { get { return scaleY * (Bone.yDown ? -1 : 1); } set { scaleY = value; } }
[Obsolete("Use ScaleX instead. FlipX is when ScaleX is negative.")] [Obsolete("Use ScaleX instead. FlipX is when ScaleX is negative.")]
@ -120,9 +144,9 @@ namespace Spine {
foreach (PathConstraintData pathConstraintData in data.pathConstraints) foreach (PathConstraintData pathConstraintData in data.pathConstraints)
pathConstraints.Add(new PathConstraint(pathConstraintData, this)); pathConstraints.Add(new PathConstraint(pathConstraintData, this));
springConstraints = new ExposedList<SpringConstraint>(data.springConstraints.Count); physicsConstraints = new ExposedList<PhysicsConstraint>(data.physicsConstraints.Count);
foreach (SpringConstraintData springConstraintData in data.springConstraints) foreach (PhysicsConstraintData physicsConstraintData in data.physicsConstraints)
springConstraints.Add(new SpringConstraint(springConstraintData, this)); physicsConstraints.Add(new PhysicsConstraint(physicsConstraintData, this));
UpdateCache(); UpdateCache();
} }
@ -169,9 +193,9 @@ namespace Spine {
foreach (PathConstraint pathConstraint in skeleton.pathConstraints) foreach (PathConstraint pathConstraint in skeleton.pathConstraints)
pathConstraints.Add(new PathConstraint(pathConstraint, this)); pathConstraints.Add(new PathConstraint(pathConstraint, this));
springConstraints = new ExposedList<SpringConstraint>(skeleton.springConstraints.Count); physicsConstraints = new ExposedList<PhysicsConstraint>(skeleton.physicsConstraints.Count);
foreach (SpringConstraint springConstraint in skeleton.springConstraints) foreach (PhysicsConstraint physicsConstraint in skeleton.physicsConstraints)
springConstraints.Add(new SpringConstraint(springConstraint, this)); physicsConstraints.Add(new PhysicsConstraint(physicsConstraint, this));
skin = skeleton.skin; skin = skeleton.skin;
r = skeleton.r; r = skeleton.r;
@ -210,12 +234,12 @@ namespace Spine {
} }
int ikCount = this.ikConstraints.Count, transformCount = this.transformConstraints.Count, pathCount = this.pathConstraints.Count, int ikCount = this.ikConstraints.Count, transformCount = this.transformConstraints.Count, pathCount = this.pathConstraints.Count,
springCount = this.springConstraints.Count; physicsCount = this.physicsConstraints.Count;
IkConstraint[] ikConstraints = this.ikConstraints.Items; IkConstraint[] ikConstraints = this.ikConstraints.Items;
TransformConstraint[] transformConstraints = this.transformConstraints.Items; TransformConstraint[] transformConstraints = this.transformConstraints.Items;
PathConstraint[] pathConstraints = this.pathConstraints.Items; PathConstraint[] pathConstraints = this.pathConstraints.Items;
SpringConstraint[] springConstraints = this.springConstraints.Items; PhysicsConstraint[] physicsConstraints = this.physicsConstraints.Items;
int constraintCount = ikCount + transformCount + pathCount + springCount; int constraintCount = ikCount + transformCount + pathCount + physicsCount;
for (int i = 0; i < constraintCount; i++) { for (int i = 0; i < constraintCount; i++) {
for (int ii = 0; ii < ikCount; ii++) { for (int ii = 0; ii < ikCount; ii++) {
IkConstraint constraint = ikConstraints[ii]; IkConstraint constraint = ikConstraints[ii];
@ -238,10 +262,10 @@ namespace Spine {
goto continue_outer; goto continue_outer;
} }
} }
for (int ii = 0; ii < springCount; ii++) { for (int ii = 0; ii < physicsCount; ii++) {
SpringConstraint constraint = springConstraints[ii]; PhysicsConstraint constraint = physicsConstraints[ii];
if (constraint.data.order == i) { if (constraint.data.order == i) {
SortSpringConstraint(constraint); SortPhysicsConstraint(constraint);
goto continue_outer; goto continue_outer;
} }
} }
@ -355,7 +379,7 @@ namespace Spine {
} }
} }
private void SortSpringConstraint (SpringConstraint constraint) { private void SortPhysicsConstraint (PhysicsConstraint constraint) {
constraint.active = !constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data)); constraint.active = !constraint.data.skinRequired || (skin != null && skin.constraints.Contains(constraint.data));
if (!constraint.active) return; if (!constraint.active) return;
@ -491,10 +515,10 @@ namespace Spine {
constraint.mixY = data.mixY; constraint.mixY = data.mixY;
} }
SpringConstraint[] springConstraints = this.springConstraints.Items; PhysicsConstraint[] physicsConstraints = this.physicsConstraints.Items;
for (int i = 0, n = this.springConstraints.Count; i < n; i++) { for (int i = 0, n = this.physicsConstraints.Count; i < n; i++) {
SpringConstraint constraint = springConstraints[i]; PhysicsConstraint constraint = physicsConstraints[i];
SpringConstraintData data = constraint.data; PhysicsConstraintData data = constraint.data;
constraint.mix = data.mix; constraint.mix = data.mix;
constraint.friction = data.friction; constraint.friction = data.friction;
constraint.gravity = data.gravity; constraint.gravity = data.gravity;
@ -657,14 +681,14 @@ namespace Spine {
return null; return null;
} }
/// <summary>Finds a spring constraint by comparing each spring constraint's name. It is more efficient to cache the results of this /// <summary>Finds a physics constraint by comparing each physics constraint's name. It is more efficient to cache the results of this
/// method than to call it repeatedly.</summary> /// method than to call it repeatedly.</summary>
/// <returns>May be null.</returns> /// <returns>May be null.</returns>
public SpringConstraint FindSpringConstraint (String constraintName) { public PhysicsConstraint FindPhysicsConstraint (String constraintName) {
if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
SpringConstraint[] springConstraints = this.springConstraints.Items; PhysicsConstraint[] physicsConstraints = this.physicsConstraints.Items;
for (int i = 0, n = this.springConstraints.Count; i < n; i++) { for (int i = 0, n = this.physicsConstraints.Count; i < n; i++) {
SpringConstraint constraint = springConstraints[i]; PhysicsConstraint constraint = physicsConstraints[i];
if (constraint.data.name.Equals(constraintName)) return constraint; if (constraint.data.name.Equals(constraintName)) return constraint;
} }
return null; return null;

View File

@ -43,7 +43,7 @@ namespace Spine {
internal ExposedList<IkConstraintData> ikConstraints = new ExposedList<IkConstraintData>(); internal ExposedList<IkConstraintData> ikConstraints = new ExposedList<IkConstraintData>();
internal ExposedList<TransformConstraintData> transformConstraints = new ExposedList<TransformConstraintData>(); internal ExposedList<TransformConstraintData> transformConstraints = new ExposedList<TransformConstraintData>();
internal ExposedList<PathConstraintData> pathConstraints = new ExposedList<PathConstraintData>(); internal ExposedList<PathConstraintData> pathConstraints = new ExposedList<PathConstraintData>();
internal ExposedList<SpringConstraintData> springConstraints = new ExposedList<SpringConstraintData>(); internal ExposedList<PhysicsConstraintData> physicsConstraints = new ExposedList<PhysicsConstraintData>();
internal float x, y, width, height; internal float x, y, width, height;
internal string version, hash; internal string version, hash;
@ -70,12 +70,18 @@ namespace Spine {
/// <return>May be null.</return> /// <return>May be null.</return>
public Skin DefaultSkin { get { return defaultSkin; } set { defaultSkin = value; } } public Skin DefaultSkin { get { return defaultSkin; } set { defaultSkin = value; } }
/// <summary>The skeleton's events.</summary>
public ExposedList<EventData> Events { get { return events; } set { events = value; } } public ExposedList<EventData> Events { get { return events; } set { events = value; } }
/// <summary>The skeleton's animations.</summary>
public ExposedList<Animation> Animations { get { return animations; } set { animations = value; } } public ExposedList<Animation> Animations { get { return animations; } set { animations = value; } }
/// <summary>The skeleton's IK constraints.</summary>
public ExposedList<IkConstraintData> IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } } public ExposedList<IkConstraintData> IkConstraints { get { return ikConstraints; } set { ikConstraints = value; } }
/// <summary>The skeleton's transform constraints.</summary>
public ExposedList<TransformConstraintData> TransformConstraints { get { return transformConstraints; } set { transformConstraints = value; } } public ExposedList<TransformConstraintData> TransformConstraints { get { return transformConstraints; } set { transformConstraints = value; } }
/// <summary>The skeleton's path constraints.</summary>
public ExposedList<PathConstraintData> PathConstraints { get { return pathConstraints; } set { pathConstraints = value; } } public ExposedList<PathConstraintData> PathConstraints { get { return pathConstraints; } set { pathConstraints = value; } }
public ExposedList<SpringConstraintData> SpringConstraints { get { return springConstraints; } set { springConstraints = value; } } /// <summary>The skeleton's physics constraints.</summary>
public ExposedList<PhysicsConstraintData> PhysicsConstraints { get { return physicsConstraints; } set { physicsConstraints = value; } }
public float X { get { return x; } set { x = value; } } public float X { get { return x; } set { x = value; } }
public float Y { get { return y; } set { y = value; } } public float Y { get { return y; } set { y = value; } }
@ -202,18 +208,18 @@ namespace Spine {
return null; return null;
} }
// --- Spring constraints // --- Physics constraints
/// <summary> /// <summary>
/// Finds a spring constraint by comparing each spring constraint's name. It is more efficient to cache the results of this /// Finds a physics constraint by comparing each physics constraint's name. It is more efficient to cache the results of this
/// method than to call it multiple times. /// method than to call it multiple times.
/// </summary> /// </summary>
/// <returns>May be null.</returns> /// <returns>May be null.</returns>
public SpringConstraintData FindSpringConstraint (String constraintName) { public PhysicsConstraintData FindPhysicsConstraint (String constraintName) {
if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null."); if (constraintName == null) throw new ArgumentNullException("constraintName", "constraintName cannot be null.");
Object[] springConstraints = this.springConstraints.Items; Object[] physicsConstraints = this.physicsConstraints.Items;
for (int i = 0, n = this.springConstraints.Count; i < n; i++) { for (int i = 0, n = this.physicsConstraints.Count; i < n; i++) {
SpringConstraintData constraint = (SpringConstraintData)springConstraints[i]; PhysicsConstraintData constraint = (PhysicsConstraintData)physicsConstraints[i];
if (constraint.name.Equals(constraintName)) return constraint; if (constraint.name.Equals(constraintName)) return constraint;
} }
return null; return null;