]> git.jsancho.org Git - lugaru.git/blob - Source/Animation/Muscle.cpp
Replaced muscles and joints in Skeleton by vectors
[lugaru.git] / Source / Animation / Muscle.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
4
5 This file is part of Lugaru.
6
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "Animation/Muscle.h"
22 #include "binio.h"
23
24 extern float multiplier;
25 extern bool freeze;
26
27 Muscle::Muscle()
28 {
29     length = 0;
30     targetlength = 0;
31     parent1 = 0;
32     parent2 = 0;
33     maxlength = 0;
34     minlength = 0;
35     type = boneconnect;
36     visible = 0;
37     rotate1 = 0, rotate2 = 0, rotate3 = 0;
38     lastrotate1 = 0, lastrotate2 = 0, lastrotate3 = 0;
39     oldrotate1 = 0, oldrotate2 = 0, oldrotate3 = 0;
40     newrotate1 = 0, newrotate2 = 0, newrotate3 = 0;
41
42     strength = 0;
43 }
44
45 Muscle::~Muscle()
46 {
47 }
48
49 void Muscle::load(FILE* tfile, int vertexNum, std::vector<Joint>& joints)
50 {
51     int numvertices, vertice, parentID;
52
53     // read info
54     funpackf(tfile, "Bf Bf Bf Bf Bf Bi Bi", &length, &targetlength, &minlength, &maxlength, &strength, &type, &numvertices);
55
56     // read vertices
57     for (int j = 0; j < numvertices; j++) {
58         funpackf(tfile, "Bi", &vertice);
59         if (vertice < vertexNum) {
60             vertices.push_back(vertice);
61         }
62     }
63
64     // read more info
65     funpackf(tfile, "Bb Bi", &visible, &parentID);
66     parent1 = &joints[parentID];
67     funpackf(tfile, "Bi", &parentID);
68     parent2 = &joints[parentID];
69 }
70
71 void Muscle::loadVerticesLow(FILE* tfile, int vertexNum)
72 {
73     int numvertices, vertice;
74
75     // read numvertices
76     funpackf(tfile, "Bi", &numvertices);
77
78     // read vertices
79     for (int j = 0; j < numvertices; j++) {
80         funpackf(tfile, "Bi", &vertice);
81         if (vertice < vertexNum) {
82             verticeslow.push_back(vertice);
83         }
84     }
85 }
86
87 void Muscle::loadVerticesClothes(FILE* tfile, int vertexNum)
88 {
89     int numvertices, vertice;
90
91     // read numvertices
92     funpackf(tfile, "Bi", &numvertices);
93
94     // read vertices
95     for (int j = 0; j < numvertices; j++) {
96         funpackf(tfile, "Bi", &vertice);
97         if (vertice < vertexNum) {
98             verticesclothes.push_back(vertice);
99         }
100     }
101 }
102
103
104 /* EFFECT
105  * sets strength, length,
106  *      parent1->position, parent2->position,
107  *      parent1->velocity, parent2->velocity
108  * used for ragdolls?
109  *
110  * USES:
111  * Skeleton::DoConstraints
112  */
113 void Muscle::DoConstraint(bool spinny)
114 {
115     // FIXME: relaxlength shouldn't be static, but may not always be set
116     // so I don't want to change the existing behavior even though it's probably a bug
117     static float relaxlength;
118
119     float oldlength = length;
120
121     if (type != boneconnect) {
122         relaxlength = findDistance(&parent1->position, &parent2->position);
123     }
124
125     if (type == boneconnect) {
126         strength = 1;
127     }
128     if (type == constraint) {
129         strength = 0;
130     }
131
132     // clamp strength
133     if (strength < 0)
134         strength = 0;
135     if (strength > 1)
136         strength = 1;
137
138     length -= (length - relaxlength) * (1 - strength) * multiplier * 10000;
139     length -= (length - targetlength) * (strength) * multiplier * 10000;
140     if (strength == 0)
141         length = relaxlength;
142
143     if ((relaxlength - length > 0 && relaxlength - oldlength < 0) || (relaxlength - length < 0 && relaxlength - oldlength > 0))
144         length = relaxlength;
145
146     // clamp length
147     if (length < minlength)
148         length = minlength;
149     if (length > maxlength)
150         length = maxlength;
151
152     if (length == relaxlength)
153         return;
154
155     // relax muscle?
156
157     //Find midpoint
158     XYZ midp = (parent1->position * parent1->mass + parent2->position * parent2->mass) / (parent1->mass + parent2->mass);
159
160     //Find vector from midpoint to second vector
161     XYZ vel = parent2->position - midp;
162
163     //Change to unit vector
164     Normalise(&vel);
165
166     //Apply velocity change
167     XYZ newpoint1 = midp - vel * length * (parent2->mass / (parent1->mass + parent2->mass));
168     XYZ newpoint2 = midp + vel * length * (parent1->mass / (parent1->mass + parent2->mass));
169     if (!freeze && spinny) {
170         parent1->velocity = parent1->velocity + (newpoint1 - parent1->position) / multiplier / 4;
171         parent2->velocity = parent2->velocity + (newpoint2 - parent2->position) / multiplier / 4;
172     } else {
173         parent1->velocity = parent1->velocity + (newpoint1 - parent1->position);
174         parent2->velocity = parent2->velocity + (newpoint2 - parent2->position);
175     }
176
177     //Move child point to within certain distance of parent point
178     parent1->position = newpoint1;
179     parent2->position = newpoint2;
180 }