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