]> git.jsancho.org Git - lugaru.git/blob - Source/Animation/Muscle.cpp
Applied clang-format on all files
[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.hpp"
22
23 #include "Utils/binio.h"
24
25 extern float multiplier;
26 extern bool freeze;
27
28 Muscle::Muscle()
29     : length(0)
30     , targetlength(0)
31     , parent1(0)
32     , parent2(0)
33     , maxlength(0)
34     , minlength(0)
35     , type(boneconnect)
36     , visible(false)
37     , rotate1(0)
38     , rotate2(0)
39     , rotate3(0)
40     , lastrotate1(0)
41     , lastrotate2(0)
42     , lastrotate3(0)
43     , oldrotate1(0)
44     , oldrotate2(0)
45     , oldrotate3(0)
46     , newrotate1(0)
47     , newrotate2(0)
48     , newrotate3(0)
49     ,
50
51     strength(0)
52 {
53 }
54
55 void Muscle::load(FILE* tfile, int vertexNum, std::vector<Joint>& joints)
56 {
57     int numvertices, vertice, parentID;
58
59     // read info
60     funpackf(tfile, "Bf Bf Bf Bf Bf Bi Bi", &length, &targetlength, &minlength, &maxlength, &strength, &type, &numvertices);
61
62     // read vertices
63     for (int j = 0; j < numvertices; j++) {
64         funpackf(tfile, "Bi", &vertice);
65         if (vertice < vertexNum) {
66             vertices.push_back(vertice);
67         }
68     }
69
70     // read more info
71     funpackf(tfile, "Bb Bi", &visible, &parentID);
72     parent1 = &joints[parentID];
73     funpackf(tfile, "Bi", &parentID);
74     parent2 = &joints[parentID];
75 }
76
77 void Muscle::loadVerticesLow(FILE* tfile, int vertexNum)
78 {
79     int numvertices, vertice;
80
81     // read numvertices
82     funpackf(tfile, "Bi", &numvertices);
83
84     // read vertices
85     for (int j = 0; j < numvertices; j++) {
86         funpackf(tfile, "Bi", &vertice);
87         if (vertice < vertexNum) {
88             verticeslow.push_back(vertice);
89         }
90     }
91 }
92
93 void Muscle::loadVerticesClothes(FILE* tfile, int vertexNum)
94 {
95     int numvertices, vertice;
96
97     // read numvertices
98     funpackf(tfile, "Bi", &numvertices);
99
100     // read vertices
101     for (int j = 0; j < numvertices; j++) {
102         funpackf(tfile, "Bi", &vertice);
103         if (vertice < vertexNum) {
104             verticesclothes.push_back(vertice);
105         }
106     }
107 }
108
109 /* EFFECT
110  * sets strength, length,
111  *      parent1->position, parent2->position,
112  *      parent1->velocity, parent2->velocity
113  * used for ragdolls?
114  *
115  * USES:
116  * Skeleton::DoConstraints
117  */
118 void Muscle::DoConstraint(bool spinny)
119 {
120     // FIXME: relaxlength shouldn't be static, but may not always be set
121     // so I don't want to change the existing behavior even though it's probably a bug
122     static float relaxlength;
123
124     float oldlength = length;
125
126     if (type != boneconnect) {
127         relaxlength = findDistance(&parent1->position, &parent2->position);
128     }
129
130     if (type == boneconnect) {
131         strength = 1;
132     }
133     if (type == constraint) {
134         strength = 0;
135     }
136
137     // clamp strength
138     if (strength < 0)
139         strength = 0;
140     if (strength > 1)
141         strength = 1;
142
143     length -= (length - relaxlength) * (1 - strength) * multiplier * 10000;
144     length -= (length - targetlength) * strength * multiplier * 10000;
145     if (strength == 0)
146         length = relaxlength;
147
148     if ((relaxlength - length > 0 && relaxlength - oldlength < 0) || (relaxlength - length < 0 && relaxlength - oldlength > 0))
149         length = relaxlength;
150
151     // clamp length
152     if (length < minlength)
153         length = minlength;
154     if (length > maxlength)
155         length = maxlength;
156
157     if (length == relaxlength)
158         return;
159
160     // relax muscle?
161
162     //Find midpoint
163     XYZ midp = (parent1->position * parent1->mass + parent2->position * parent2->mass) / (parent1->mass + parent2->mass);
164
165     //Find vector from midpoint to second vector
166     XYZ vel = parent2->position - midp;
167
168     //Change to unit vector
169     Normalise(&vel);
170
171     //Apply velocity change
172     XYZ newpoint1 = midp - vel * length * (parent2->mass / (parent1->mass + parent2->mass));
173     XYZ newpoint2 = midp + vel * length * (parent1->mass / (parent1->mass + parent2->mass));
174     if (!freeze && spinny) {
175         parent1->velocity = parent1->velocity + (newpoint1 - parent1->position) / multiplier / 4;
176         parent2->velocity = parent2->velocity + (newpoint2 - parent2->position) / multiplier / 4;
177     } else {
178         parent1->velocity = parent1->velocity + (newpoint1 - parent1->position);
179         parent2->velocity = parent2->velocity + (newpoint2 - parent2->position);
180     }
181
182     //Move child point to within certain distance of parent point
183     parent1->position = newpoint1;
184     parent2->position = newpoint2;
185 }