forked from AerysBat/XNALara
-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathArmature.cs
More file actions
161 lines (137 loc) · 4.82 KB
/
Copy pathArmature.cs
File metadata and controls
161 lines (137 loc) · 4.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
using System.Collections.Generic;
using Microsoft.Xna.Framework;
namespace XNALara
{
public delegate void ArmatureEventDelegate();
public class Armature
{
private Model model;
private Vector3 worldTranslation = Vector3.Zero;
private Vector3 worldScale = new Vector3(1.0f, 1.0f, 1.0f);
private Matrix worldMatrix = Matrix.Identity;
private Bone[] bones = new Bone[0];
private Matrix[] boneMatrices = new Matrix[0];
private Dictionary<string, Bone> boneDict = new Dictionary<string, Bone>();
private List<Bone> rootBones = new List<Bone>();
public event ArmatureEventDelegate ArmatureEvent;
public Armature(Model model) {
this.model = model;
}
public Model Model {
get { return model; }
}
public Vector3 WorldTranslation {
set {
worldTranslation = value;
WorldMatrix =
Matrix.CreateScale(worldScale) *
Matrix.CreateTranslation(worldTranslation);
}
get { return worldTranslation; }
}
public Vector3 WorldScale {
set {
worldScale = value;
WorldMatrix =
Matrix.CreateScale(worldScale) *
Matrix.CreateTranslation(worldTranslation);
}
get { return worldScale; }
}
public Matrix WorldMatrix {
private set {
worldMatrix = value;
if (ArmatureEvent != null) {
ArmatureEvent();
}
}
get { return worldMatrix; }
}
public Bone[] Bones {
set {
bones = new Bone[value.Length];
boneMatrices = new Matrix[bones.Length];
boneDict.Clear();
rootBones.Clear();
for (int boneID = 0; boneID < bones.Length; boneID++) {
Bone bone = value[boneID];
bones[boneID] = bone;
boneDict[bone.name] = bone;
if (bone.parent == null) {
rootBones.Add(bone);
}
}
InitMatrices();
}
get { return bones; }
}
public Bone GetBone(string boneName) {
Bone bone;
if (boneDict.TryGetValue(boneName, out bone)) {
return bone;
}
return null;
}
public Matrix[] GetBoneMatrices(Mesh mesh) {
short[] boneIndexMap = mesh.BoneIndexMap;
Matrix[] matrices = new Matrix[boneIndexMap.Length];
for (int i = 0; i < matrices.Length; i++) {
matrices[i] = boneMatrices[boneIndexMap[i]];
}
return matrices;
}
public Matrix[] BoneMatrices {
get { return boneMatrices; }
}
public void SetBoneTransform(string boneName, Matrix transform) {
boneDict[boneName].relTransform = transform;
}
public void UpdateBoneMatrices() {
foreach (Bone root in rootBones) {
CalcAbsTransform(root);
}
for (int boneID = 0; boneID < bones.Length; boneID++) {
Bone bone = bones[boneID];
boneMatrices[boneID] = bone.invMove * bone.absTransform;
}
if (ArmatureEvent != null) {
ArmatureEvent();
}
}
private void InitMatrices() {
foreach (Bone bone in bones) {
bone.relTransform = Matrix.Identity;
bone.invMove = Matrix.CreateTranslation(-bone.absPosition);
bone.relMove = bone.parent != null ?
Matrix.CreateTranslation(bone.absPosition - bone.parent.absPosition) :
Matrix.Identity;
}
UpdateBoneMatrices();
}
private void CalcAbsTransform(Bone bone) {
Bone parent = bone.parent;
if (parent != null) {
bone.absTransform = (bone.relTransform * bone.relMove) * parent.absTransform;
}
else {
bone.absTransform = bone.relTransform;
}
foreach (Bone child in bone.children) {
CalcAbsTransform(child);
}
}
public class Bone
{
public Armature armature;
public int id;
public string name;
public Vector3 absPosition;
public Bone parent;
public List<Bone> children = new List<Bone>();
public Matrix invMove;
public Matrix relMove;
public Matrix relTransform;
public Matrix absTransform;
}
}
}