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