mirror of
https://github.com/EsotericSoftware/spine-runtimes.git
synced 2025-12-20 17:26:01 +08:00
[xna][monogame] Added support for vertex effects, see #898
This commit is contained in:
parent
c06bd8f181
commit
b5f79f80c3
@ -137,6 +137,7 @@
|
|||||||
* Removed `RegionBatcher` and `SkeletonRegionRenderer`, renamed `SkeletonMeshRenderer` to `SkeletonRenderer`
|
* Removed `RegionBatcher` and `SkeletonRegionRenderer`, renamed `SkeletonMeshRenderer` to `SkeletonRenderer`
|
||||||
* Added support for two color tint. For it to work, you need to add the `SpineEffect.fx` file to your content project, then load it via `var effect = Content.Load<Effect>("SpineEffect");`, and set it on the `SkeletonRenderer`. See the example project for code.
|
* Added support for two color tint. For it to work, you need to add the `SpineEffect.fx` file to your content project, then load it via `var effect = Content.Load<Effect>("SpineEffect");`, and set it on the `SkeletonRenderer`. See the example project for code.
|
||||||
* Added support for any `Effect` to be used by `SkeletonRenderer`
|
* Added support for any `Effect` to be used by `SkeletonRenderer`
|
||||||
|
* Added support for `IVertexEffect` to modify vertices of skeletons on the CPU. `IVertexEffect` instances can be set on the `SkeletonRenderer`. See example project.
|
||||||
|
|
||||||
## Java
|
## Java
|
||||||
* **Breaking changes**
|
* **Breaking changes**
|
||||||
|
|||||||
@ -46,6 +46,8 @@ namespace Spine {
|
|||||||
const float DegToIndex = SIN_COUNT / DegFull;
|
const float DegToIndex = SIN_COUNT / DegFull;
|
||||||
static float[] sin = new float[SIN_COUNT];
|
static float[] sin = new float[SIN_COUNT];
|
||||||
|
|
||||||
|
static Random random = new Random();
|
||||||
|
|
||||||
static MathUtils () {
|
static MathUtils () {
|
||||||
for (int i = 0; i < SIN_COUNT; i++)
|
for (int i = 0; i < SIN_COUNT; i++)
|
||||||
sin[i] = (float)Math.Sin((i + 0.5f) / SIN_COUNT * RadFull);
|
sin[i] = (float)Math.Sin((i + 0.5f) / SIN_COUNT * RadFull);
|
||||||
@ -96,5 +98,49 @@ namespace Spine {
|
|||||||
if (value > max) return max;
|
if (value > max) return max;
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static public float RandomTriangle(float min, float max) {
|
||||||
|
return RandomTriangle(min, max, (min + max) * 0.5f);
|
||||||
|
}
|
||||||
|
|
||||||
|
static public float RandomTriangle(float min, float max, float mode) {
|
||||||
|
float u = (float)random.NextDouble();
|
||||||
|
float d = max - min;
|
||||||
|
if (u <= (mode - min) / d) return min + (float)Math.Sqrt(u * d * (mode - min));
|
||||||
|
return max - (float)Math.Sqrt((1 - u) * d * (max - mode));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public abstract class IInterpolation {
|
||||||
|
public static IInterpolation Pow2 = new Pow(2);
|
||||||
|
public static IInterpolation Pow2Out = new PowOut(2);
|
||||||
|
|
||||||
|
protected abstract float Apply(float a);
|
||||||
|
|
||||||
|
public float Apply(float start, float end, float a) {
|
||||||
|
return start + (end - start) * Apply(a);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Pow: IInterpolation {
|
||||||
|
public float Power { get; set; }
|
||||||
|
|
||||||
|
public Pow(float power) {
|
||||||
|
Power = power;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float Apply(float a) {
|
||||||
|
if (a <= 0.5f) return (float)Math.Pow(a * 2, Power) / 2;
|
||||||
|
return (float)Math.Pow((a - 1) * 2, Power) / (Power % 2 == 0 ? -2 : 2) + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PowOut : Pow {
|
||||||
|
public PowOut(float power) : base(power) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override float Apply(float a) {
|
||||||
|
return (float)Math.Pow(a - 1, Power) * (Power % 2 == 0 ? -1 : 1) + 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -119,7 +119,7 @@
|
|||||||
<None Include="data\coin.png">
|
<None Include="data\coin.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\coin.skel">
|
<None Include="data\coin-pro.skel">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\goblins.png">
|
<None Include="data\goblins.png">
|
||||||
@ -134,26 +134,17 @@
|
|||||||
<Content Include="data\tank.png">
|
<Content Include="data\tank.png">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</Content>
|
</Content>
|
||||||
<Content Include="data\TwoColorTest.png">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</Content>
|
|
||||||
<Content Include="Game.ico" />
|
<Content Include="Game.ico" />
|
||||||
<Content Include="GameThumbnail.png" />
|
<Content Include="GameThumbnail.png" />
|
||||||
<None Include="data\tank.atlas">
|
<None Include="data\tank.atlas">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\tank.json">
|
<None Include="data\tank-pro.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\tank.skel">
|
<None Include="data\tank-pro.skel">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\TwoColorTest.atlas">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
<None Include="data\TwoColorTest.json">
|
|
||||||
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
|
|
||||||
</None>
|
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\..\spine-csharp\spine-csharp.csproj">
|
<ProjectReference Include="..\..\spine-csharp\spine-csharp.csproj">
|
||||||
@ -201,28 +192,28 @@
|
|||||||
<None Include="data\coin.atlas">
|
<None Include="data\coin.atlas">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\coin.json">
|
<None Include="data\coin-pro.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\goblins-mesh.atlas">
|
<None Include="data\goblins-mesh.atlas">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\goblins-mesh.json">
|
<None Include="data\goblins-pro.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\goblins-mesh.skel">
|
<None Include="data\goblins-pro.skel">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\raptor.atlas">
|
<None Include="data\raptor.atlas">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\raptor.json">
|
<None Include="data\raptor-pro.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\spineboy.atlas">
|
<None Include="data\spineboy.atlas">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
<None Include="data\spineboy.json">
|
<None Include="data\spineboy-ess.json">
|
||||||
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -47,6 +47,9 @@ namespace Spine {
|
|||||||
Slot headSlot;
|
Slot headSlot;
|
||||||
AnimationState state;
|
AnimationState state;
|
||||||
SkeletonBounds bounds = new SkeletonBounds();
|
SkeletonBounds bounds = new SkeletonBounds();
|
||||||
|
JitterEffect jitter = new JitterEffect(10, 10);
|
||||||
|
SwirlEffect swirl = new SwirlEffect(600);
|
||||||
|
float swirlTime;
|
||||||
|
|
||||||
#if WINDOWS_STOREAPP
|
#if WINDOWS_STOREAPP
|
||||||
private string assetsFolder = @"Assets\";
|
private string assetsFolder = @"Assets\";
|
||||||
@ -78,23 +81,22 @@ namespace Spine {
|
|||||||
skeletonRenderer = new SkeletonRenderer(GraphicsDevice);
|
skeletonRenderer = new SkeletonRenderer(GraphicsDevice);
|
||||||
skeletonRenderer.PremultipliedAlpha = false;
|
skeletonRenderer.PremultipliedAlpha = false;
|
||||||
skeletonRenderer.Effect = spineEffect;
|
skeletonRenderer.Effect = spineEffect;
|
||||||
|
skeletonRenderer.VertexEffect = swirl;
|
||||||
|
|
||||||
// String name = "spineboy";
|
// String name = "spineboy-ess";
|
||||||
// String name = "goblins-mesh";
|
// String name = "goblins-pro";
|
||||||
// String name = "raptor";
|
String name = "raptor-pro";
|
||||||
// String name = "tank";
|
// String name = "tank-pro";
|
||||||
// String name = "coin";
|
// String name = "coin-pro";
|
||||||
String name = "TwoColorTest";
|
|
||||||
bool binaryData = false;
|
bool binaryData = false;
|
||||||
|
|
||||||
Atlas atlas = new Atlas(assetsFolder + name + ".atlas", new XnaTextureLoader(GraphicsDevice));
|
Atlas atlas = new Atlas(assetsFolder + name.Replace("-ess", "").Replace("-pro", "") + ".atlas", new XnaTextureLoader(GraphicsDevice));
|
||||||
|
|
||||||
float scale = 1;
|
float scale = 1;
|
||||||
if (name == "spineboy") scale = 0.6f;
|
if (name == "spineboy-ess") scale = 0.6f;
|
||||||
if (name == "raptor") scale = 0.5f;
|
if (name == "raptor-pro") scale = 0.5f;
|
||||||
if (name == "tank") scale = 0.3f;
|
if (name == "tank-pro") scale = 0.3f;
|
||||||
if (name == "coin") scale = 1;
|
if (name == "coin-pro") scale = 1;
|
||||||
if (name == "TwoColorTest") scale = 0.5f;
|
|
||||||
|
|
||||||
SkeletonData skeletonData;
|
SkeletonData skeletonData;
|
||||||
if (binaryData) {
|
if (binaryData) {
|
||||||
@ -107,13 +109,13 @@ namespace Spine {
|
|||||||
skeletonData = json.ReadSkeletonData(assetsFolder + name + ".json");
|
skeletonData = json.ReadSkeletonData(assetsFolder + name + ".json");
|
||||||
}
|
}
|
||||||
skeleton = new Skeleton(skeletonData);
|
skeleton = new Skeleton(skeletonData);
|
||||||
if (name == "goblins-mesh") skeleton.SetSkin("goblin");
|
if (name == "goblins-pro") skeleton.SetSkin("goblin");
|
||||||
|
|
||||||
// Define mixing between animations.
|
// Define mixing between animations.
|
||||||
AnimationStateData stateData = new AnimationStateData(skeleton.Data);
|
AnimationStateData stateData = new AnimationStateData(skeleton.Data);
|
||||||
state = new AnimationState(stateData);
|
state = new AnimationState(stateData);
|
||||||
|
|
||||||
if (name == "spineboy") {
|
if (name == "spineboy-ess") {
|
||||||
stateData.SetMix("run", "jump", 0.2f);
|
stateData.SetMix("run", "jump", 0.2f);
|
||||||
stateData.SetMix("jump", "run", 0.4f);
|
stateData.SetMix("jump", "run", 0.4f);
|
||||||
|
|
||||||
@ -123,30 +125,26 @@ namespace Spine {
|
|||||||
state.Complete += Complete;
|
state.Complete += Complete;
|
||||||
state.Event += Event;
|
state.Event += Event;
|
||||||
|
|
||||||
state.SetAnimation(0, "test", false);
|
TrackEntry entry = state.SetAnimation(0, "jump", false);
|
||||||
TrackEntry entry = state.AddAnimation(0, "jump", false, 0);
|
|
||||||
entry.End += End; // Event handling for queued animations.
|
entry.End += End; // Event handling for queued animations.
|
||||||
state.AddAnimation(0, "run", true, 0);
|
state.AddAnimation(0, "run", true, 0);
|
||||||
}
|
}
|
||||||
else if (name == "raptor") {
|
else if (name == "raptor-pro") {
|
||||||
state.SetAnimation(0, "walk", true);
|
state.SetAnimation(0, "walk", true);
|
||||||
state.AddAnimation(1, "gungrab", false, 2);
|
state.AddAnimation(1, "gun-grab", false, 2);
|
||||||
}
|
}
|
||||||
else if (name == "coin") {
|
else if (name == "coin-pro") {
|
||||||
state.SetAnimation(0, "rotate", true);
|
state.SetAnimation(0, "rotate", true);
|
||||||
}
|
}
|
||||||
else if (name == "tank") {
|
else if (name == "tank-pro") {
|
||||||
state.SetAnimation(0, "drive", true);
|
state.SetAnimation(0, "drive", true);
|
||||||
}
|
}
|
||||||
else if (name == "TwoColorTest") {
|
|
||||||
state.SetAnimation(0, "animation", true);
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
state.SetAnimation(0, "walk", true);
|
state.SetAnimation(0, "walk", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
skeleton.X = 400 + (name == "tank" ? 300: 0);
|
skeleton.X = 400 + (name == "tank" ? 300: 0);
|
||||||
skeleton.Y = 580 + (name == "TwoColorTest" ? -400 : 0);
|
skeleton.Y = 600;
|
||||||
skeleton.UpdateWorldTransform();
|
skeleton.UpdateWorldTransform();
|
||||||
|
|
||||||
headSlot = skeleton.FindSlot("head");
|
headSlot = skeleton.FindSlot("head");
|
||||||
@ -168,7 +166,13 @@ namespace Spine {
|
|||||||
protected override void Draw (GameTime gameTime) {
|
protected override void Draw (GameTime gameTime) {
|
||||||
GraphicsDevice.Clear(Color.Black);
|
GraphicsDevice.Clear(Color.Black);
|
||||||
|
|
||||||
state.Update(gameTime.ElapsedGameTime.Milliseconds / 1000f);
|
float delta = gameTime.ElapsedGameTime.Milliseconds / 1000f;
|
||||||
|
swirlTime += delta;
|
||||||
|
float percent = swirlTime % 2;
|
||||||
|
if (percent > 1) percent = 1 - (percent - 1);
|
||||||
|
swirl.Angle = (IInterpolation.Pow2.Apply(-60, 60, percent));
|
||||||
|
|
||||||
|
state.Update(delta);
|
||||||
state.Apply(skeleton);
|
state.Apply(skeleton);
|
||||||
skeleton.UpdateWorldTransform();
|
skeleton.UpdateWorldTransform();
|
||||||
if (skeletonRenderer.Effect is BasicEffect) {
|
if (skeletonRenderer.Effect is BasicEffect) {
|
||||||
@ -176,6 +180,7 @@ namespace Spine {
|
|||||||
} else {
|
} else {
|
||||||
skeletonRenderer.Effect.Parameters["Projection"].SetValue(Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 1, 0));
|
skeletonRenderer.Effect.Parameters["Projection"].SetValue(Matrix.CreateOrthographicOffCenter(0, GraphicsDevice.Viewport.Width, GraphicsDevice.Viewport.Height, 0, 1, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
skeletonRenderer.Begin();
|
skeletonRenderer.Begin();
|
||||||
skeletonRenderer.Draw(skeleton);
|
skeletonRenderer.Draw(skeleton);
|
||||||
skeletonRenderer.End();
|
skeletonRenderer.End();
|
||||||
|
|||||||
@ -110,6 +110,7 @@
|
|||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
<Compile Include="src\MeshBatcher.cs" />
|
<Compile Include="src\MeshBatcher.cs" />
|
||||||
|
<Compile Include="src\VertexEffect.cs" />
|
||||||
<Compile Include="src\XnaTextureLoader.cs" />
|
<Compile Include="src\XnaTextureLoader.cs" />
|
||||||
<Compile Include="src\Util.cs" />
|
<Compile Include="src\Util.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|||||||
@ -25,11 +25,13 @@ Global
|
|||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|Any CPU.ActiveCfg = Debug|x86
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|Any CPU.ActiveCfg = Debug|x86
|
||||||
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|Any CPU.Build.0 = Debug|x86
|
||||||
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|Mixed Platforms.ActiveCfg = Debug|x86
|
||||||
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|Mixed Platforms.Build.0 = Debug|x86
|
||||||
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|x86.ActiveCfg = Debug|x86
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|x86.ActiveCfg = Debug|x86
|
||||||
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|x86.Build.0 = Debug|x86
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Debug|x86.Build.0 = Debug|x86
|
||||||
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Release|Any CPU.ActiveCfg = Release|x86
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Release|Any CPU.ActiveCfg = Release|x86
|
||||||
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Release|Any CPU.Build.0 = Release|x86
|
||||||
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Release|Mixed Platforms.ActiveCfg = Release|x86
|
||||||
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Release|Mixed Platforms.Build.0 = Release|x86
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Release|Mixed Platforms.Build.0 = Release|x86
|
||||||
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Release|x86.ActiveCfg = Release|x86
|
{7F8F2327-C016-49C8-BB4D-F3F77971961E}.Release|x86.ActiveCfg = Release|x86
|
||||||
|
|||||||
@ -52,6 +52,7 @@ namespace Spine {
|
|||||||
|
|
||||||
Effect effect;
|
Effect effect;
|
||||||
public Effect Effect { get { return effect; } set { effect = value; } }
|
public Effect Effect { get { return effect; } set { effect = value; } }
|
||||||
|
public IVertexEffect VertexEffect { get; set; }
|
||||||
|
|
||||||
private bool premultipliedAlpha;
|
private bool premultipliedAlpha;
|
||||||
public bool PremultipliedAlpha { get { return premultipliedAlpha; } set { premultipliedAlpha = value; } }
|
public bool PremultipliedAlpha { get { return premultipliedAlpha; } set { premultipliedAlpha = value; } }
|
||||||
@ -94,6 +95,8 @@ namespace Spine {
|
|||||||
float skeletonR = skeleton.R, skeletonG = skeleton.G, skeletonB = skeleton.B, skeletonA = skeleton.A;
|
float skeletonR = skeleton.R, skeletonG = skeleton.G, skeletonB = skeleton.B, skeletonA = skeleton.A;
|
||||||
Color color = new Color();
|
Color color = new Color();
|
||||||
|
|
||||||
|
if (VertexEffect != null) VertexEffect.Begin(skeleton);
|
||||||
|
|
||||||
for (int i = 0, n = drawOrder.Count; i < n; i++) {
|
for (int i = 0, n = drawOrder.Count; i < n; i++) {
|
||||||
Slot slot = drawOrderItems[i];
|
Slot slot = drawOrderItems[i];
|
||||||
Attachment attachment = slot.Attachment;
|
Attachment attachment = slot.Attachment;
|
||||||
@ -194,11 +197,13 @@ namespace Spine {
|
|||||||
itemVertices[ii].Position.Z = 0;
|
itemVertices[ii].Position.Z = 0;
|
||||||
itemVertices[ii].TextureCoordinate.X = uvs[v];
|
itemVertices[ii].TextureCoordinate.X = uvs[v];
|
||||||
itemVertices[ii].TextureCoordinate.Y = uvs[v + 1];
|
itemVertices[ii].TextureCoordinate.Y = uvs[v + 1];
|
||||||
|
if (VertexEffect != null) VertexEffect.Transform(ref itemVertices[ii]);
|
||||||
}
|
}
|
||||||
|
|
||||||
clipper.ClipEnd(slot);
|
clipper.ClipEnd(slot);
|
||||||
}
|
}
|
||||||
clipper.ClipEnd();
|
clipper.ClipEnd();
|
||||||
|
if (VertexEffect != null) VertexEffect.End();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
99
spine-xna/src/VertexEffect.cs
Normal file
99
spine-xna/src/VertexEffect.cs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
/******************************************************************************
|
||||||
|
* Spine Runtimes Software License
|
||||||
|
* Version 2.3
|
||||||
|
*
|
||||||
|
* Copyright (c) 2013-2015, Esoteric Software
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* You are granted a perpetual, non-exclusive, non-sublicensable and
|
||||||
|
* non-transferable license to use, install, execute and perform the Spine
|
||||||
|
* Runtimes Software (the "Software") and derivative works solely for personal
|
||||||
|
* or internal use. Without the written permission of Esoteric Software (see
|
||||||
|
* Section 2 of the Spine Software License Agreement), you may not (a) modify,
|
||||||
|
* translate, adapt or otherwise create derivative works, improvements of the
|
||||||
|
* Software or develop new applications using the Software or (b) remove,
|
||||||
|
* delete, alter or obscure any trademarks or any copyright, trademark, patent
|
||||||
|
* or other intellectual property or proprietary rights notices on or in the
|
||||||
|
* Software, including any copy thereof. Redistributions in binary or source
|
||||||
|
* form must include this license and terms.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY ESOTERIC SOFTWARE "AS IS" AND ANY EXPRESS OR
|
||||||
|
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
|
||||||
|
* EVENT SHALL ESOTERIC SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||||
|
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||||
|
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||||
|
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*****************************************************************************/
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Spine {
|
||||||
|
public interface IVertexEffect {
|
||||||
|
void Begin(Skeleton skeleton);
|
||||||
|
void Transform(ref VertexPositionColorTextureColor vertex);
|
||||||
|
void End();
|
||||||
|
}
|
||||||
|
|
||||||
|
public class JitterEffect : IVertexEffect {
|
||||||
|
public float JitterX { get; set; }
|
||||||
|
public float JitterY { get; set; }
|
||||||
|
|
||||||
|
public JitterEffect(float jitterX, float jitterY) {
|
||||||
|
JitterX = jitterX;
|
||||||
|
JitterY = jitterY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Begin(Skeleton skeleton) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void End() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Transform(ref VertexPositionColorTextureColor vertex) {
|
||||||
|
vertex.Position.X += MathUtils.RandomTriangle(-JitterX, JitterY);
|
||||||
|
vertex.Position.Y += MathUtils.RandomTriangle(-JitterX, JitterY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public class SwirlEffect : IVertexEffect {
|
||||||
|
private float worldX, worldY, angle;
|
||||||
|
|
||||||
|
public float Radius { get; set; }
|
||||||
|
public float Angle { get { return angle; } set { angle = value * MathUtils.DegRad; } }
|
||||||
|
public float CenterX { get; set; }
|
||||||
|
public float CenterY { get; set; }
|
||||||
|
public IInterpolation Interpolation { get; set; }
|
||||||
|
|
||||||
|
public SwirlEffect(float radius) {
|
||||||
|
Radius = radius;
|
||||||
|
Interpolation = IInterpolation.Pow2;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Begin(Skeleton skeleton) {
|
||||||
|
worldX = skeleton.X + CenterX;
|
||||||
|
worldY = skeleton.Y + CenterY;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void End() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Transform(ref VertexPositionColorTextureColor vertex) {
|
||||||
|
float x = vertex.Position.X - worldX;
|
||||||
|
float y = vertex.Position.Y - worldY;
|
||||||
|
float dist = (float)Math.Sqrt(x * x + y * y);
|
||||||
|
if (dist < Radius) {
|
||||||
|
float theta = Interpolation.Apply(0, angle, (Radius - dist) / Radius);
|
||||||
|
float cos = MathUtils.Cos(theta), sin = MathUtils.Sin(theta);
|
||||||
|
vertex.Position.X = cos * x - sin * y + worldX;
|
||||||
|
vertex.Position.Y = sin * x + cos * y + worldY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user