Jamez0r

I'm working on making an animation of roots that run along the ground. To do it, I have a couple images of straight roots that I make into a mesh and weight to several bones that I can then position.





This is working great, but I'd like to add a shadow to the roots -> I would do this by making shadows that are also "straight" (like the vine images) and setting them up as weighted-meshes that follow the same bones. The problem is that I need the shadow to be offset slightly "downward" regardless of how the bones/weighted-mesh is positioned.

I was wondering if it is possible to change the position of the attachment at runtime (even if I had to update it each frame), so that I could shift the shadow images downward slightly.

If it isn't possible to do that with programming, might there be a way I could do it within Spine? Was thinking maybe a constraint, but constraints move bones not attachments, so I don't think I'd be able to do it. All in all, I'm looking to avoid having to manually-position an identical set of bones (slightly lower) for the shadows.

Thanks for any help!! :grinteeth:
Jamez0r
  • Сообщения: 85

Nate

Sure, you have access to the entire mesh at runtime. MeshAttachment extends VertexAttachment. You want to look at VertexAttachment vertices. For a non-weighted mesh it's just x,y values for each vertex. For a weighted mesh you also need VertexAttachment bones. Your code would look something like:
Skeleton skeleton = ...
MeshAttachment mesh = ...
Vector2 tempVector2 = new Vector2();

int[] bones = mesh.getBones();
float[] vertices = mesh.getVertices();
Array<Bone> skeletonBones = skeleton.getBones();
for (int v = 0, b = 0, n = vertices.length; v < n;) {
int boneCount = bones[b++];
for (int ii = 0; ii < boneCount; ii++, v += 3) {
Bone bone = skeletonBones.get(bones[b++]);
// For example, to move the mesh down 25 in world coordinates:
Vector2 position = bone.worldToLocal(tempVector2.set(bone.getWorldX(), bone.getWorldY() - 25));
vertices[v] += position.x;
vertices[v + 1] += position.y;
}
}
You would do this only once, not every frame (unless you want the mesh to move every frame). Note this will affect every instance of this mesh attachment, so you may want to modify a copy.

A simpler way is, as you mentioned, to move a bone that the attachments you want to move are parented to. You can move the root bone to move the whole skeleton (or set the Skeleton position) or you can create a bone specifically for moving the attachments you want to move.
Аватара пользователя
Nate

Nate
  • Сообщения: 9264

Jamez0r

Thanks for the reply Nate!
Nate писал(а):Sure, you have access to the entire mesh at runtime. MeshAttachment extends VertexAttachment. You want to look at VertexAttachment vertices. For a non-weighted mesh it's just x,y values for each vertex. For a weighted mesh you also need VertexAttachment bones. Your code would look something like:
Skeleton skeleton = ...
MeshAttachment mesh = ...
Vector2 tempVector2 = new Vector2();

int[] bones = mesh.getBones();
float[] vertices = mesh.getVertices();
Array<Bone> skeletonBones = skeleton.getBones();
for (int v = 0, b = 0, n = vertices.length; v < n;) {
int boneCount = bones[b++];
for (int ii = 0; ii < boneCount; ii++, v += 3) {
Bone bone = skeletonBones.get(bones[b++]);
// For example, to move the mesh down 25 in world coordinates:
Vector2 position = bone.worldToLocal(tempVector2.set(bone.getWorldX(), bone.getWorldY() - 25));
vertices[v] += position.x;
vertices[v + 1] += position.y;
}
}
You would do this only once, not every frame (unless you want the mesh to move every frame). Note this will affect every instance of this mesh attachment, so you may want to modify a copy.
One question with this method -> If the roots/vines are animated to wriggle a bit (thus altering the mesh), would updating the animation cancel out the position offset? (meaning I then would have to shift the meshAttachment every frame?)
A simpler way is, as you mentioned, to move a bone that the attachments you want to move are parented to. You can move the root bone to move the whole skeleton (or set the Skeleton position) or you can create a bone specifically for moving the attachments you want to move.
The issue I'm having with this sort of approach is that I'm trying to set up the "roots" (vine) mesh and the shadow mesh to be weighted to the same bones - that way I can set up their position once (and animate the bones wriggling around a bit), and somehow magically afterwards shift the shadow mesh downward slightly.

Both meshes:


Just the shadow (follows the same bones)


I don't think what I'm trying to do is possible in the Editor - so would my best bet be to try the runtime adjustment?

---

Update to this: I made a separate Skin for the shadow, and then simply positioned the skeleton downward slightly and rendered the skeleton with the shadow-skin, and then moved the skeleton back up to the normal position and rendered the regular-skin. Guess I was overthinking it a bit :scared:
Jamez0r
  • Сообщения: 85

Nate

Sorry I didn't see the earlier response. Deform keys are relative to the setup pose, which is what the code above adjusts, so you won't lose your animations. It sounds like your simpler solution is better though!
Аватара пользователя
Nate

Nate
  • Сообщения: 9264


Вернуться в Runtimes