source: cpp/frams/genetics/geneprops.cpp @ 1246

Last change on this file since 1246 was 1246, checked in by Maciej Komosinski, 11 months ago

Optionally normalize the four "biological" properties when propagating them along sticks (only to test legacy code, now normalization is no longer used)

File size: 9.4 KB
Line 
1// This file is a part of Framsticks SDK.  http://www.framsticks.com/
2// Copyright (C) 1999-2023  Maciej Komosinski and Szymon Ulatowski.
3// See LICENSE.txt for details.
4
5#include "geneprops.h"
6#include <algorithm>
7
8GeneProps GeneProps::standard_values;
9
10GeneProps::GeneProps()
11{
12        length = 1.0;
13        weight = 1.0;
14        friction = 0.4;
15        curvedness = 0.0;
16        twist = 0.0;
17        energy = 1.0;
18
19        muscle_power = 0.25; // "biological" property
20        assimilation = 0.25; // "biological" property
21        stamina = 0.25; // "biological" property
22        ingestion = 0.25; // "biological" property
23
24        muscle_bend_range = 1.0;
25        muscle_reset_range = true;
26
27        cred = 0.5;
28        cgreen = 0.5;
29        cblue = 0.5;
30
31        normalizeBiol4();
32}
33
34void GeneProps::normalizeBiol4()
35{
36        // make them sum to 1
37        double sum = muscle_power + assimilation + stamina + ingestion;
38        if (sum == 0)
39        {
40                muscle_power = assimilation = stamina = ingestion = 0.25;
41        }
42        else
43        {
44                muscle_power /= sum;
45                assimilation /= sum;
46                stamina /= sum;
47                ingestion /= sum;
48        }
49}
50
51int GeneProps::executeModifier_Legacy(char modif)
52{
53        switch (modif)
54        {
55#ifdef v1f1COMPATIBLE
56        case 'L': length += (3.0 - length) * 0.3;
57                length = std::min(length, Model::getMaxJoint().d.x); break;
58#else
59        case 'L': length += (2.0 - length) * 0.3; //2.0 is currently Model::getMaxJoint().d.x so min() does not limit the range
60                length = std::min(length, Model::getMaxJoint().d.x); break;
61#endif
62        case 'l': length += (0.33 - length) * 0.3;
63                length = std::max(length, Model::getMinJoint().d.x); break;
64
65        case 'W': weight += (2.0 - weight) * 0.3; break;
66        case 'w': weight += (0.5 - weight) * 0.3; break;
67        case 'F': friction += (4 - friction) * 0.2; break;
68        case 'f': friction -= friction * 0.2; break;
69        case 'C': curvedness += (2.0 - curvedness) * 0.25; break;
70        case 'c': curvedness += (-2.0 - curvedness) * 0.25; break;
71        case 'Q': twist += (M_PI_2 - twist) * 0.3; break;
72        case 'q': twist += (-M_PI_2 - twist) * 0.3; break;
73        case 'E': energy += (10.0 - energy) * 0.1; break;
74        case 'e': energy -= energy * 0.1;  break;
75
76        case 'A': assimilation += (1 - assimilation) * 0.8; normalizeBiol4(); break;
77        case 'a': assimilation -= assimilation * 0.4; normalizeBiol4(); break;
78        case 'I': ingestion += (1 - ingestion) * 0.8; normalizeBiol4(); break;
79        case 'i': ingestion -= ingestion * 0.4; normalizeBiol4(); break;
80        case 'S': stamina += (1 - stamina) * 0.8; normalizeBiol4(); break;
81        case 's': stamina -= stamina * 0.4; normalizeBiol4(); break;
82        case 'M': muscle_power += (1 - muscle_power) * 0.8; normalizeBiol4(); break;
83        case 'm': muscle_power -= muscle_power * 0.4; normalizeBiol4(); break;
84
85        case 'D': cred += (1.0 - cred) * 0.25; break;
86        case 'd': cred += (0.0 - cred) * 0.25; break;
87        case 'G': cgreen += (1.0 - cgreen) * 0.25; break;
88        case 'g': cgreen += (0.0 - cgreen) * 0.25; break;
89        case 'B': cblue += (1.0 - cblue) * 0.25; break;
90        case 'b': cblue += (0.0 - cblue) * 0.25; break;
91
92        default: return -1;
93        }
94        return 0;
95}
96
97int GeneProps::executeModifier(char modif, GenePropsOps* ops)
98{
99        if (ops == NULL)
100                ops = getStandardOps();
101
102#define APPLY(name) ops->name->apply(name, modif)
103#define APPLY_AND_MAYBE_NORMALIZEBIOL4(name) {APPLY(name); if (ops->use_normalizebiol4) normalizeBiol4();}
104
105        switch (toupper(modif))
106        {
107        case 'L': APPLY(length);
108                length = std::min(length, Model::getMaxJoint().d.x); break;
109                break;
110
111        case 'l': APPLY(length);
112                length = std::max(length, Model::getMinJoint().d.x); break;
113                break;
114
115        case 'W': APPLY(weight); break;
116        case 'F': APPLY(friction); break;
117        case 'C': APPLY(curvedness); break;
118        case 'Q': APPLY(twist); break;
119        case 'E': APPLY(energy); break;
120
121        case 'A': APPLY_AND_MAYBE_NORMALIZEBIOL4(assimilation); break;
122        case 'I': APPLY_AND_MAYBE_NORMALIZEBIOL4(ingestion); break;
123        case 'S': APPLY_AND_MAYBE_NORMALIZEBIOL4(stamina); break;
124        case 'M': APPLY_AND_MAYBE_NORMALIZEBIOL4(muscle_power); break;
125
126        case 'D': APPLY(cred); break;
127        case 'G': APPLY(cgreen); break;
128        case 'B': APPLY(cblue); break;
129
130        default: return -1;
131        }
132        return 0;
133
134#undef APPLY
135#undef APPLY_AND_MAYBE_NORMALIZEBIOL4
136}
137
138void GeneProps::propagateAlong(bool use_f1_muscle_reset_range, GenePropsOps* ops)
139{
140        length = 0.5 * length + 0.5 * standard_values.length;
141        weight += (standard_values.weight - weight) * 0.5;
142        friction = 0.8 * friction + 0.2 * standard_values.friction;
143        curvedness = 0.66 * curvedness;
144        twist = 0.66 * twist;
145
146        assimilation = 0.8 * assimilation + 0.2 * standard_values.assimilation;
147        ingestion = 0.8 * ingestion + 0.2 * standard_values.ingestion;
148        stamina = 0.8 * stamina + 0.2 * standard_values.stamina;
149        muscle_power = 0.8 * muscle_power + 0.2 * standard_values.muscle_power;
150
151        if (ops == NULL)
152                ops = getStandardOps();
153        if (ops->use_normalizebiol4) normalizeBiol4();
154
155        if (use_f1_muscle_reset_range)
156        {
157                if (muscle_reset_range) muscle_bend_range = 1.0; else muscle_reset_range = true;
158        }
159}
160
161////////////////////////////////////////////////////
162
163void GenePropsOp::apply(double &value, char modif) const
164{
165        if (isupper(modif))
166                value = increase(value);
167        else
168                value = decrease(value);
169}
170
171double GenePropsOp_Old::increase(double value) const
172{
173        return value + (maxvalue - value) * change;
174}
175
176double GenePropsOp_Old::decrease(double value) const
177{
178        return value + (minvalue - value) * revchange;
179}
180
181GenePropsOp_Old::GenePropsOp_Old(double minvalue, double maxvalue, double defvalue, double change, double revchange)
182{
183        this->minvalue = minvalue;
184        this->maxvalue = maxvalue;
185        this->defvalue = defvalue;
186        this->change = change;
187        this->revchange = (revchange < 0) ? change : revchange;
188}
189
190GenePropsOp_Exponential::GenePropsOp_Exponential(double minvalue, double maxvalue, double defvalue, double change)
191        :GenePropsOp_NormalizedAndScaled(change)
192{
193        double mid = (maxvalue + minvalue) / 2;
194        if (fabs(mid - defvalue) < 0.01)
195        {
196                linear = true;
197                a = (maxvalue - minvalue) / 2;
198                b = defvalue;
199        }
200        else
201        {
202                linear = false;
203                a = -(maxvalue - defvalue) / (minvalue - defvalue);
204                b = (minvalue * minvalue - 2 * defvalue * minvalue + defvalue * defvalue) / (minvalue + maxvalue - 2 * defvalue);
205                c = (maxvalue * minvalue - defvalue * defvalue) / (minvalue + maxvalue - 2 * defvalue);
206                log_a = log(a);
207        }
208}
209
210double GenePropsOp_Exponential::scale(double value) const
211{
212        if (linear)
213                return a * value + b;
214        else
215                return pow(a, (value + 1)) * b + c;
216}
217
218double GenePropsOp_Exponential::scaleInv(double value) const
219{
220        if (linear)
221                return (value - b) / a;
222        else
223                return -(log_a - log(value / b - c / b)) / log_a;
224}
225
226////////////////////////////////////////////////////////////////////
227
228
229GenePropsOps::~GenePropsOps()
230{
231        delete length;
232        delete curvedness;
233        delete weight;
234        delete friction;
235        delete muscle_power;
236        delete assimilation;
237        delete stamina;
238        delete ingestion;
239        delete twist;
240        delete energy;
241        delete cred;
242        delete cgreen;
243        delete cblue;
244}
245
246GenePropsOps_Old::GenePropsOps_Old()
247{
248        use_normalizebiol4 = true;
249
250        length = new GenePropsOp_Old(0.33, 2.0, GeneProps::standard_values.length, 0.3);
251        weight = new GenePropsOp_Old(0.5, 2.0, GeneProps::standard_values.weight, 0.3);
252        friction = new GenePropsOp_Old(0, 4.0, GeneProps::standard_values.friction, 0.2);
253        curvedness = new GenePropsOp_Old(-2, 2, GeneProps::standard_values.curvedness, 0.25);
254        twist = new GenePropsOp_Old(-M_PI_2, M_PI_2, GeneProps::standard_values.twist, 0.3);
255        energy = new GenePropsOp_Old(0, 10, GeneProps::standard_values.energy, 0.1);
256
257        assimilation = new GenePropsOp_Old(0, 1, GeneProps::standard_values.assimilation, 0.8, 0.4);
258        ingestion = new GenePropsOp_Old(0, 1, GeneProps::standard_values.ingestion, 0.8, 0.4);
259        stamina = new GenePropsOp_Old(0, 1, GeneProps::standard_values.stamina, 0.8, 0.4);
260        muscle_power = new GenePropsOp_Old(0, 1, GeneProps::standard_values.muscle_power, 0.8, 0.4);
261
262        cred = new GenePropsOp_Old(0, 1, GeneProps::standard_values.cred, 0.25);
263        cgreen = new GenePropsOp_Old(0, 1, GeneProps::standard_values.cgreen, 0.25);
264        cblue = new GenePropsOp_Old(0, 1, GeneProps::standard_values.cblue, 0.25);
265}
266
267GenePropsOps_New05::GenePropsOps_New05()
268{
269        use_normalizebiol4 = false;
270        auto fields = { length,curvedness,weight,friction,muscle_power,assimilation,stamina,ingestion,twist,energy,cred,cgreen,cblue };
271        for (auto f : fields)
272        {
273                auto f_gpo = dynamic_cast<GenePropsOp_Old*>(f);
274                if (f_gpo)
275                        f_gpo->change = f_gpo->revchange = 0.5;
276        }
277}
278
279GenePropsOps_Exponential::GenePropsOps_Exponential()
280{
281        length = new GenePropsOp_Exponential(0.33, 2.0, GeneProps::standard_values.length);
282        weight = new GenePropsOp_Exponential(0.5, 2.0, GeneProps::standard_values.weight);
283        friction = new GenePropsOp_Exponential(0, 4.0, GeneProps::standard_values.friction);
284        curvedness = new GenePropsOp_Exponential(-2, 2, GeneProps::standard_values.curvedness);
285        twist = new GenePropsOp_Exponential(-M_PI_2, M_PI_2, GeneProps::standard_values.twist);
286        energy = new GenePropsOp_Exponential(0, 10, GeneProps::standard_values.energy);
287
288        assimilation = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.assimilation);
289        ingestion = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.ingestion);
290        stamina = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.stamina);
291        muscle_power = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.muscle_power);
292
293        cred = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.cred);
294        cgreen = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.cgreen);
295        cblue = new GenePropsOp_Exponential(0, 1, GeneProps::standard_values.cblue);
296}
297
298
299GenePropsOps* GeneProps::standard_ops = NULL;
300GenePropsOps* GeneProps::getStandardOps()
301{
302        if (!standard_ops)
303                standard_ops = new GenePropsOps_New05();
304        return standard_ops;
305}
Note: See TracBrowser for help on using the repository browser.