]> git.jsancho.org Git - lugaru.git/blob - Source/Animation/Muscle.cpp
In case the resolution settings in the config file have wrong values,
[lugaru.git] / Source / Animation / Muscle.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2017 - 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     }
141     if (strength > 1) {
142         strength = 1;
143     }
144
145     length -= (length - relaxlength) * (1 - strength) * multiplier * 10000;
146     length -= (length - targetlength) * strength * multiplier * 10000;
147     if (strength == 0) {
148         length = relaxlength;
149     }
150
151     if ((relaxlength - length > 0 && relaxlength - oldlength < 0) || (relaxlength - length < 0 && relaxlength - oldlength > 0)) {
152         length = relaxlength;
153     }
154
155     // clamp length
156     if (length < minlength) {
157         length = minlength;
158     }
159     if (length > maxlength) {
160         length = maxlength;
161     }
162
163     if (length == relaxlength) {
164         return;
165     }
166
167     // relax muscle?
168
169     //Find midpoint
170     XYZ midp = (parent1->position * parent1->mass + parent2->position * parent2->mass) / (parent1->mass + parent2->mass);
171
172     //Find vector from midpoint to second vector
173     XYZ vel = parent2->position - midp;
174
175     //Change to unit vector
176     Normalise(&vel);
177
178     //Apply velocity change
179     XYZ newpoint1 = midp - vel * length * (parent2->mass / (parent1->mass + parent2->mass));
180     XYZ newpoint2 = midp + vel * length * (parent1->mass / (parent1->mass + parent2->mass));
181     if (!freeze && spinny) {
182         parent1->velocity = parent1->velocity + (newpoint1 - parent1->position) / multiplier / 4;
183         parent2->velocity = parent2->velocity + (newpoint2 - parent2->position) / multiplier / 4;
184     } else {
185         parent1->velocity = parent1->velocity + (newpoint1 - parent1->position);
186         parent2->velocity = parent2->velocity + (newpoint2 - parent2->position);
187     }
188
189     //Move child point to within certain distance of parent point
190     parent1->position = newpoint1;
191     parent2->position = newpoint2;
192 }