1 /**
2  * Mandelbulber v2, a 3D fractal generator       ,=#MKNmMMKmmßMNWy,
3  *                                             ,B" ]L,,p%%%,,,§;, "K
4  * Copyright (C) 2014-21 Mandelbulber Team     §R-==%w["'~5]m%=L.=~5N
5  *                                        ,=mm=§M ]=4 yJKA"/-Nsaj  "Bw,==,,
6  * This file is part of Mandelbulber.    §R.r= jw",M  Km .mM  FW ",§=ß., ,TN
7  *                                     ,4R =%["w[N=7]J '"5=],""]]M,w,-; T=]M
8  * Mandelbulber is free software:     §R.ß~-Q/M=,=5"v"]=Qf,'§"M= =,M.§ Rz]M"Kw
9  * you can redistribute it and/or     §w "xDY.J ' -"m=====WeC=\ ""%""y=%"]"" §
10  * modify it under the terms of the    "§M=M =D=4"N #"%==A%p M§ M6  R' #"=~.4M
11  * GNU General Public License as        §W =, ][T"]C  §  § '§ e===~ U  !§[Z ]N
12  * published by the                    4M",,Jm=,"=e~  §  §  j]]""N  BmM"py=ßM
13  * Free Software Foundation,          ]§ T,M=& 'YmMMpM9MMM%=w=,,=MT]M m§;'§,
14  * either version 3 of the License,    TWw [.j"5=~N[=§%=%W,T ]R,"=="Y[LFT ]N
15  * or (at your option)                   TW=,-#"%=;[  =Q:["V""  ],,M.m == ]N
16  * any later version.                      J§"mr"] ,=,," =="""J]= M"M"]==ß"
17  *                                          §= "=C=4 §"eM "=B:m|4"]#F,§~
18  * Mandelbulber is distributed in            "9w=,,]w em%wJ '"~" ,=,,ß"
19  * the hope that it will be useful,                 . "K=  ,=RMMMßM"""
20  * but WITHOUT ANY WARRANTY;                            .'''
21  * without even the implied warranty
22  * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
23  *
24  * See the GNU General Public License for more details.
25  * You should have received a copy of the GNU General Public License
26  * along with Mandelbulber. If not, see <http://www.gnu.org/licenses/>.
27  *
28  * ###########################################################################
29  *
30  * Authors: Krzysztof Marczak (buddhi1980@gmail.com)
31  *
32  * Class to store settings for animation frames
33  *
34  * Handles the 2D matrix of the list of parameters / list of frames
35  * and exposes functions to modify this matrix.
36  */
37 
38 #include "animation_frames.hpp"
39 
40 #include <memory>
41 
42 #include <QDir>
43 #include <QDirIterator>
44 
45 #include "audio_track.h"
46 #include "audio_track_collection.h"
47 #include "fractal_container.hpp"
48 #include "initparameters.hpp"
49 #include "system.hpp"
50 
51 std::shared_ptr<cAnimationFrames> gAnimFrames;
52 
53 cAnimationFrames::cAnimationFrames() = default;
54 
55 cAnimationFrames::~cAnimationFrames() = default;
56 
AddFrame(const std::shared_ptr<cParameterContainer> params,const std::shared_ptr<cFractalContainer> fractal,int numberOfSubFrames,int index)57 void cAnimationFrames::AddFrame(const std::shared_ptr<cParameterContainer> params,
58 	const std::shared_ptr<cFractalContainer> fractal, int numberOfSubFrames, int index)
59 {
60 	sAnimationFrame frame;
61 
62 	for (auto &parameterDescription : listOfParameters)
63 	{
64 		std::shared_ptr<cParameterContainer> container =
65 			ContainerSelector(parameterDescription.containerName, params, fractal);
66 
67 		if (container)
68 		{
69 			const QString parameterName = parameterDescription.parameterName;
70 			const QString fullParameterName = container->GetContainerName() + "_" + parameterName;
71 			cOneParameter oneParameter = container->GetAsOneParameter(parameterName);
72 
73 			// getting morph type from existing frame
74 			parameterContainer::enumMorphType morphType;
75 			if (frames.size() > 0)
76 			{
77 				morphType = frames[0].parameters.GetAsOneParameter(fullParameterName).GetMorphType();
78 			}
79 			else // if no frames yet
80 			{
81 				morphType = oneParameter.GetMorphType();
82 			}
83 
84 			oneParameter.SetMorphType(morphType);
85 			frame.parameters.AddParamFromOneParameter(fullParameterName, oneParameter);
86 			frame.numberOfSubFrames = numberOfSubFrames;
87 		}
88 		else
89 		{
90 			qCritical() << "cAnimationFrames::AddFrame(const cParameterContainer &params, const "
91 										 "cFractalContainer &fractal): Wrong container name: "
92 									<< parameterDescription.containerName;
93 		}
94 	}
95 	int indexTemp = index;
96 	if (index == -1) indexTemp = frames.size();
97 	frames.insert(indexTemp, frame);
98 }
99 
AddAnimatedParameter(const QString & parameterName,const cOneParameter & defaultValue,std::shared_ptr<cParameterContainer> params)100 void cAnimationFrames::AddAnimatedParameter(const QString &parameterName,
101 	const cOneParameter &defaultValue, std::shared_ptr<cParameterContainer> params)
102 {
103 	if (IndexOnList(parameterName, defaultValue.GetOriginalContainerName()) == -1)
104 	{
105 		listOfParameters.append(
106 			sParameterDescription(parameterName, defaultValue.GetOriginalContainerName(),
107 				defaultValue.GetValueType(), defaultValue.GetMorphType()));
108 		for (auto &frame : frames)
109 		{
110 			frame.parameters.AddParamFromOneParameter(
111 				defaultValue.GetOriginalContainerName() + "_" + parameterName, defaultValue);
112 		}
113 
114 		// if parameter container is nullptr then will be used default global container for sound
115 		// parameters
116 		if (!params) params = gPar;
117 
118 		AddAudioParameter(
119 			parameterName, defaultValue.GetValueType(), defaultValue.GetOriginalContainerName(), params);
120 	}
121 	else
122 	{
123 		qWarning() << "cAnimationFrames::AddAnimatedParameter(const QString &parameterName, const "
124 									"cOneParameter &defaultValue): element '"
125 							 << parameterName << "' already exists";
126 	}
127 }
128 
AddAnimatedParameter(const QString & fullParameterName,std::shared_ptr<cParameterContainer> param,std::shared_ptr<cFractalContainer> fractal)129 bool cAnimationFrames::AddAnimatedParameter(const QString &fullParameterName,
130 	std::shared_ptr<cParameterContainer> param, std::shared_ptr<cFractalContainer> fractal)
131 {
132 	const int firstUnderscore = fullParameterName.indexOf('_');
133 	const QString containerName = fullParameterName.left(firstUnderscore);
134 	const QString parameterName = fullParameterName.mid(firstUnderscore + 1);
135 
136 	const std::shared_ptr<cParameterContainer> container =
137 		ContainerSelector(containerName, param, fractal);
138 	if (container)
139 	{
140 		cOneParameter parameter = container->GetAsOneParameter(parameterName);
141 		if (parameter.IsEmpty())
142 		{
143 			qWarning() << "cAnimationFrames::AddAnimatedParameter(const QString &fullParameterName, "
144 										"const std::shared_ptr<cParameterContainer> param, const "
145 										"std::shared_ptr<cFractalContainer> fractal): unknown "
146 										"parameter"
147 								 << fullParameterName;
148 			return false;
149 		}
150 		else
151 		{
152 			AddAnimatedParameter(parameterName, container->GetAsOneParameter(parameterName), param);
153 			return true;
154 		}
155 	}
156 	else
157 	{
158 		qCritical() << "cAnimationFrames::AddAnimatedParameter(const QString &fullParameterName, const "
159 									 "std::shared_ptr<cParameterContainer> param, const "
160 									 "std::shared_ptr<cFractalContainer> fractal): Wrong container "
161 									 "name: "
162 								<< containerName;
163 		return false;
164 	}
165 }
166 
RegenerateAudioTracks(std::shared_ptr<cParameterContainer> param)167 void cAnimationFrames::RegenerateAudioTracks(std::shared_ptr<cParameterContainer> param)
168 {
169 	for (auto &parameterDescription : listOfParameters)
170 	{
171 		AddAudioParameter(parameterDescription.parameterName, parameterDescription.varType,
172 			parameterDescription.containerName, param);
173 	}
174 
175 	audioTracks.LoadAllAudioFiles(param);
176 }
177 
RefreshAllAudioTracks(std::shared_ptr<cParameterContainer> param)178 void cAnimationFrames::RefreshAllAudioTracks(std::shared_ptr<cParameterContainer> param)
179 {
180 	audioTracks.RefreshAllAudioTracks(param);
181 }
182 
GetNumberOfFrames() const183 int cAnimationFrames::GetNumberOfFrames() const
184 {
185 	return frames.count();
186 }
187 
Clear()188 void cAnimationFrames::Clear()
189 {
190 	frames.clear();
191 }
192 
ClearAll()193 void cAnimationFrames::ClearAll()
194 {
195 	frames.clear();
196 	listOfParameters.clear();
197 }
198 
IndexOnList(QString parameterName,QString containerName)199 int cAnimationFrames::IndexOnList(QString parameterName, QString containerName)
200 {
201 	int index = -1;
202 	for (int i = 0; i < listOfParameters.size(); ++i)
203 	{
204 		if (listOfParameters[i].parameterName == parameterName
205 				&& listOfParameters[i].containerName == containerName)
206 		{
207 			index = i;
208 			break;
209 		}
210 	}
211 	return index;
212 }
213 
ContainerSelector(QString containerName,std::shared_ptr<const cParameterContainer> params,std::shared_ptr<const cFractalContainer> fractal)214 std::shared_ptr<const cParameterContainer> cAnimationFrames::ContainerSelector(
215 	QString containerName, std::shared_ptr<const cParameterContainer> params,
216 	std::shared_ptr<const cFractalContainer> fractal)
217 {
218 	std::shared_ptr<const cParameterContainer> container;
219 	if (containerName == "main")
220 	{
221 		container = params;
222 	}
223 	else if (containerName.indexOf("fractal") >= 0)
224 	{
225 		const int index = containerName.rightRef(1).toInt();
226 		if (index < NUMBER_OF_FRACTALS)
227 		{
228 			container = fractal->at(index);
229 		}
230 		else
231 		{
232 			qWarning() << "cAnimationFrames::ContainerSelector(QString containerName, const "
233 										"std::shared_ptr<cParameterContainer> params, const "
234 										"std::shared_ptr<cFractalContainer> fractal): wrong fractal "
235 										"container index"
236 								 << containerName << index;
237 		}
238 	}
239 	else
240 	{
241 		qWarning() << "cAnimationFrames::ContainerSelector(QString containerName, const "
242 									"std::shared_ptr<cParameterContainer> params, const "
243 									"std::shared_ptr<cFractalContainer> fractal): wrong container "
244 									"name"
245 							 << containerName;
246 	}
247 
248 	return container;
249 }
250 
ContainerSelector(QString containerName,std::shared_ptr<cParameterContainer> params,std::shared_ptr<cFractalContainer> fractal)251 std::shared_ptr<cParameterContainer> cAnimationFrames::ContainerSelector(QString containerName,
252 	std::shared_ptr<cParameterContainer> params, std::shared_ptr<cFractalContainer> fractal)
253 {
254 	std::shared_ptr<cParameterContainer> container;
255 	if (containerName == "main" || containerName == "material")
256 	{
257 		container = params;
258 	}
259 	else if (containerName.indexOf("fractal") >= 0)
260 	{
261 		const int index = containerName.rightRef(1).toInt();
262 		if (index < NUMBER_OF_FRACTALS)
263 		{
264 			container = fractal->at(index);
265 		}
266 		else
267 		{
268 			qWarning() << "cAnimationFrames::ContainerSelector(QString containerName, "
269 										"std::shared_ptr<cParameterContainer> params, "
270 										"std::shared_ptr<cFractalContainer> fractal): wrong fractal "
271 										"container index"
272 								 << containerName << index;
273 		}
274 	}
275 	else
276 	{
277 		qWarning() << "cAnimationFrames::ContainerSelector(QString containerName, cParameterContainer "
278 									"*params, std::shared_ptr<cFractalContainer> fractal): wrong container name"
279 							 << containerName;
280 	}
281 
282 	return container;
283 }
284 
GetFrame(int index) const285 cAnimationFrames::sAnimationFrame cAnimationFrames::GetFrame(int index) const
286 {
287 	if (index >= 0 && index < frames.count())
288 	{
289 		return frames.at(index);
290 	}
291 	else
292 	{
293 		qWarning() << "cAnimationFrames::GetFrame(int index): wrong index" << index;
294 		return sAnimationFrame();
295 	}
296 }
297 
GetFrameAndConsolidate(int index,std::shared_ptr<cParameterContainer> params,std::shared_ptr<cFractalContainer> fractal)298 void cAnimationFrames::GetFrameAndConsolidate(int index,
299 	std::shared_ptr<cParameterContainer> params, std::shared_ptr<cFractalContainer> fractal)
300 {
301 	if (index >= 0 && index < frames.count())
302 	{
303 		cParameterContainer frame = frames.at(index).parameters;
304 
305 		for (auto &listOfParameter : listOfParameters)
306 		{
307 			std::shared_ptr<cParameterContainer> container =
308 				ContainerSelector(listOfParameter.containerName, params, fractal);
309 			const QString parameterName = listOfParameter.parameterName;
310 			const cOneParameter oneParameter =
311 				frame.GetAsOneParameter(listOfParameter.containerName + "_" + parameterName);
312 			container->SetFromOneParameter(parameterName, oneParameter);
313 		}
314 	}
315 	else
316 	{
317 		qWarning() << "cAnimationFrames::GetFrame(int index): wrong index" << index;
318 	}
319 }
320 
RemoveAnimatedParameter(const QString & fullParameterName)321 void cAnimationFrames::RemoveAnimatedParameter(const QString &fullParameterName)
322 {
323 
324 	for (auto &frame : frames)
325 	{
326 		frame.parameters.DeleteParameter(fullParameterName);
327 	}
328 
329 	for (int i = 0; i < listOfParameters.size(); ++i)
330 	{
331 		if (listOfParameters[i].containerName + "_" + listOfParameters[i].parameterName
332 				== fullParameterName)
333 		{
334 			RemoveAudioParameter(listOfParameters[i]);
335 			listOfParameters.removeAt(i);
336 			break;
337 		}
338 	}
339 }
340 
DeleteFrames(int begin,int end)341 void cAnimationFrames::DeleteFrames(int begin, int end)
342 {
343 	for (int i = end; i >= begin; i--)
344 	{
345 		frames.removeAt(i);
346 	}
347 }
348 
ModifyFrame(int index,sAnimationFrame & frame)349 void cAnimationFrames::ModifyFrame(int index, sAnimationFrame &frame)
350 {
351 	if (index >= 0 && index < frames.size())
352 	{
353 		frames[index] = frame;
354 	}
355 }
356 
AddFrame(const sAnimationFrame & frame)357 void cAnimationFrames::AddFrame(const sAnimationFrame &frame)
358 {
359 	frames.append(frame);
360 }
361 
AddAudioParameter(const QString & parameterName,enumVarType paramType,const QString originalContainerName,std::shared_ptr<cParameterContainer> params)362 void cAnimationFrames::AddAudioParameter(const QString &parameterName, enumVarType paramType,
363 	const QString originalContainerName, std::shared_ptr<cParameterContainer> params)
364 {
365 
366 	setAudioParameterPrefix();
367 	const QString fullParameterName = originalContainerName + "_" + parameterName;
368 
369 	switch (paramType)
370 	{
371 		case typeVector3:
372 			audioTracks.AddAudioTrack(fullParameterName + "_x", params);
373 			audioTracks.AddAudioTrack(fullParameterName + "_y", params);
374 			audioTracks.AddAudioTrack(fullParameterName + "_z", params);
375 			break;
376 		case typeVector4:
377 			audioTracks.AddAudioTrack(fullParameterName + "_x", params);
378 			audioTracks.AddAudioTrack(fullParameterName + "_y", params);
379 			audioTracks.AddAudioTrack(fullParameterName + "_z", params);
380 			audioTracks.AddAudioTrack(fullParameterName + "_w", params);
381 			break;
382 		case typeRgb:
383 			audioTracks.AddAudioTrack(fullParameterName + "_R", params);
384 			audioTracks.AddAudioTrack(fullParameterName + "_G", params);
385 			audioTracks.AddAudioTrack(fullParameterName + "_B", params);
386 			break;
387 		default: audioTracks.AddAudioTrack(fullParameterName, params); break;
388 	}
389 }
390 
RemoveAudioParameter(const sParameterDescription & parameter,std::shared_ptr<cParameterContainer> params)391 void cAnimationFrames::RemoveAudioParameter(
392 	const sParameterDescription &parameter, std::shared_ptr<cParameterContainer> params)
393 {
394 	if (!params) params = gPar;
395 	const QString fullParameterName = parameter.containerName + "_" + parameter.parameterName;
396 	const enumVarType paramType = parameter.varType;
397 
398 	switch (paramType)
399 	{
400 		case typeVector3:
401 			audioTracks.DeleteAudioTrack(fullParameterName + "_x", params);
402 			audioTracks.DeleteAudioTrack(fullParameterName + "_y", params);
403 			audioTracks.DeleteAudioTrack(fullParameterName + "_z", params);
404 			break;
405 		case typeVector4:
406 			audioTracks.DeleteAudioTrack(fullParameterName + "_x", params);
407 			audioTracks.DeleteAudioTrack(fullParameterName + "_y", params);
408 			audioTracks.DeleteAudioTrack(fullParameterName + "_z", params);
409 			audioTracks.DeleteAudioTrack(fullParameterName + "_w", params);
410 			break;
411 		case typeRgb:
412 			audioTracks.DeleteAudioTrack(fullParameterName + "_R", params);
413 			audioTracks.DeleteAudioTrack(fullParameterName + "_G", params);
414 			audioTracks.DeleteAudioTrack(fullParameterName + "_B", params);
415 			break;
416 		default: audioTracks.DeleteAudioTrack(fullParameterName, params); break;
417 	}
418 }
419 
GetAudioPtr(const QString fullParameterName) const420 std::shared_ptr<cAudioTrack> cAnimationFrames::GetAudioPtr(const QString fullParameterName) const
421 {
422 	return audioTracks.GetAudioTrackPtr(fullParameterName);
423 }
424 
ApplyAudioAnimation(int frame,const cOneParameter & parameter,const QString & parameterName,const std::shared_ptr<cParameterContainer> params) const425 cOneParameter cAnimationFrames::ApplyAudioAnimation(int frame, const cOneParameter &parameter,
426 	const QString &parameterName, const std::shared_ptr<cParameterContainer> params) const
427 {
428 	cOneParameter newValue = parameter;
429 	const QString fullParameterName = parameter.GetOriginalContainerName() + "_" + parameterName;
430 	const enumVarType paramType = parameter.GetValueType();
431 	QString fullParameterNameWithSuffix;
432 
433 	switch (paramType)
434 	{
435 		case typeInt:
436 		{
437 			int value = parameter.Get<int>(valueActual);
438 			fullParameterNameWithSuffix = fullParameterName;
439 			value = ApplyAudioAnimationOneComponent(frame, value, fullParameterNameWithSuffix, params);
440 			newValue.Set(value, valueActual);
441 			break;
442 		}
443 		case typeDouble:
444 		{
445 			double value = parameter.Get<double>(valueActual);
446 			fullParameterNameWithSuffix = fullParameterName;
447 			value = ApplyAudioAnimationOneComponent(frame, value, fullParameterNameWithSuffix, params);
448 			newValue.Set(value, valueActual);
449 			break;
450 		}
451 		case typeVector3:
452 		{
453 			CVector3 value = parameter.Get<CVector3>(valueActual);
454 			fullParameterNameWithSuffix = fullParameterName + "_x";
455 			value.x =
456 				ApplyAudioAnimationOneComponent(frame, value.x, fullParameterNameWithSuffix, params);
457 			fullParameterNameWithSuffix = fullParameterName + "_y";
458 			value.y =
459 				ApplyAudioAnimationOneComponent(frame, value.y, fullParameterNameWithSuffix, params);
460 			fullParameterNameWithSuffix = fullParameterName + "_z";
461 			value.z =
462 				ApplyAudioAnimationOneComponent(frame, value.z, fullParameterNameWithSuffix, params);
463 			newValue.Set(value, valueActual);
464 			break;
465 		}
466 		case typeVector4:
467 		{
468 			CVector4 value = parameter.Get<CVector4>(valueActual);
469 			fullParameterNameWithSuffix = fullParameterName + "_x";
470 			value.x =
471 				ApplyAudioAnimationOneComponent(frame, value.x, fullParameterNameWithSuffix, params);
472 			fullParameterNameWithSuffix = fullParameterName + "_y";
473 			value.y =
474 				ApplyAudioAnimationOneComponent(frame, value.y, fullParameterNameWithSuffix, params);
475 			fullParameterNameWithSuffix = fullParameterName + "_z";
476 			value.z =
477 				ApplyAudioAnimationOneComponent(frame, value.z, fullParameterNameWithSuffix, params);
478 			fullParameterNameWithSuffix = fullParameterName + "_w";
479 			value.w =
480 				ApplyAudioAnimationOneComponent(frame, value.w, fullParameterNameWithSuffix, params);
481 			newValue.Set(value, valueActual);
482 			break;
483 		}
484 		case typeRgb:
485 		{
486 			sRGB value = parameter.Get<sRGB>(valueActual);
487 			fullParameterNameWithSuffix = fullParameterName + "_R";
488 			value.R =
489 				ApplyAudioAnimationOneComponent(frame, value.R, fullParameterNameWithSuffix, params);
490 			fullParameterNameWithSuffix = fullParameterName + "_G";
491 			value.G =
492 				ApplyAudioAnimationOneComponent(frame, value.G, fullParameterNameWithSuffix, params);
493 			fullParameterNameWithSuffix = fullParameterName + "_B";
494 			value.B =
495 				ApplyAudioAnimationOneComponent(frame, value.B, fullParameterNameWithSuffix, params);
496 			newValue.Set(value, valueActual);
497 			break;
498 		}
499 		default:
500 		{
501 			// not possible to use animation by audio
502 			break;
503 		}
504 	}
505 
506 	return newValue;
507 }
508 
509 template <typename T>
ApplyAudioAnimationOneComponent(int frame,T oldVal,const QString & fullParameterNameWithSuffix,const std::shared_ptr<cParameterContainer> params) const510 T cAnimationFrames::ApplyAudioAnimationOneComponent(int frame, T oldVal,
511 	const QString &fullParameterNameWithSuffix,
512 	const std::shared_ptr<cParameterContainer> params) const
513 {
514 	T newVal = oldVal;
515 	const bool isEnabled =
516 		params->Get<bool>(QString("animsound_enable_%1").arg(fullParameterNameWithSuffix));
517 	if (isEnabled)
518 	{
519 		const double additionFactor =
520 			params->Get<double>(QString("animsound_additionfactor_%1").arg(fullParameterNameWithSuffix));
521 		const double multFactor =
522 			params->Get<double>(QString("animsound_multfactor_%1").arg(fullParameterNameWithSuffix));
523 
524 		int soundDelay = audioTracks.GetAudioTrackPtr(fullParameterNameWithSuffix)->getSoundDelay();
525 
526 		int soundFrame = frame - soundDelay;
527 
528 		if (soundFrame >= 0
529 				&& soundFrame
530 						 < audioTracks.GetAudioTrackPtr(fullParameterNameWithSuffix)->getNumberOfFrames())
531 		{
532 			const double animSound =
533 				double(audioTracks.GetAudioTrackPtr(fullParameterNameWithSuffix)->getAnimation(soundFrame));
534 
535 			if (params->Get<bool>(QString("animsound_negative_%1").arg(fullParameterNameWithSuffix)))
536 			{
537 				newVal = oldVal / (1.0 + multFactor * animSound) - additionFactor * animSound;
538 			}
539 			else
540 			{
541 				newVal = oldVal * (1.0 + multFactor * animSound) + additionFactor * animSound;
542 			}
543 		}
544 	}
545 	return newVal;
546 }
547 
548 template int cAnimationFrames::ApplyAudioAnimationOneComponent(int frame, int oldVal,
549 	const QString &fullParameterNameWithSuffix,
550 	const std::shared_ptr<cParameterContainer> params) const;
551 template double cAnimationFrames::ApplyAudioAnimationOneComponent(int frame, double oldVal,
552 	const QString &fullParameterNameWithSuffix,
553 	const std::shared_ptr<cParameterContainer> params) const;
554 
RemoveAllAudioParameters(std::shared_ptr<cParameterContainer> params)555 void cAnimationFrames::RemoveAllAudioParameters(std::shared_ptr<cParameterContainer> params)
556 {
557 	if (!params) params = gPar;
558 	audioTracks.DeleteAllAudioTracks(params);
559 }
560 
LoadAllAudioFiles(std::shared_ptr<cParameterContainer> params)561 void cAnimationFrames::LoadAllAudioFiles(std::shared_ptr<cParameterContainer> params)
562 {
563 	if (!params) params = gPar;
564 	audioTracks.LoadAllAudioFiles(params);
565 }
566 
setAudioParameterPrefix()567 void cAnimationFrames::setAudioParameterPrefix()
568 {
569 	audioTracks.SetPrefix("flightanimsound");
570 }
571 
SetListOfParametersAndClear(QList<sParameterDescription> _listOfParameters,std::shared_ptr<cParameterContainer> params)572 void cAnimationFrames::SetListOfParametersAndClear(
573 	QList<sParameterDescription> _listOfParameters, std::shared_ptr<cParameterContainer> params)
574 {
575 	listOfParameters = _listOfParameters;
576 	frames.clear();
577 	audioTracks.DeleteAllAudioTracks(params);
578 	RegenerateAudioTracks(params);
579 }
580 
WipeFramesFromFolder(QString folder)581 void cAnimationFrames::WipeFramesFromFolder(QString folder)
582 {
583 	// frames start with the string "frame_" followed by a number sequence
584 	// then an optional suffix (e.g. "_alpha") followed by the image file extension
585 	QString regex = "^frame_[0-9]+(?:_[a-z]+)?\\..+$";
586 	DeleteAllFilesFromDirectory(folder, regex, QRegExp::RegExp);
587 	DeleteAllFilesFromDirectory(
588 		folder + QDir::separator() + gPar->Get<QString>("alpha_postfix"), regex, QRegExp::RegExp);
589 	DeleteAllFilesFromDirectory(
590 		folder + QDir::separator() + gPar->Get<QString>("zbuffer_postfix"), regex, QRegExp::RegExp);
591 	DeleteAllFilesFromDirectory(
592 		folder + QDir::separator() + gPar->Get<QString>("normal_postfix"), regex, QRegExp::RegExp);
593 	DeleteAllFilesFromDirectory(
594 		folder + QDir::separator() + gPar->Get<QString>("specular_postfix"), regex, QRegExp::RegExp);
595 }
596 
WipeFramesFromFolder(QString folder,int start,int end)597 void cAnimationFrames::WipeFramesFromFolder(QString folder, int start, int end)
598 {
599 	// frames start with the string "frame_" followed by a number sequence
600 	// then an optional suffix (e.g. "_alpha") followed by the image file extension
601 	for (int i = start; i <= end; i++)
602 	{
603 
604 		QString regex = QString("^frame_%1+(?:_[a-z]+)?\\..+$").arg(i, 7, 10, QChar('0'));
605 		DeleteAllFilesFromDirectory(folder, regex, QRegExp::RegExp);
606 		DeleteAllFilesFromDirectory(
607 			folder + QDir::separator() + gPar->Get<QString>("alpha_postfix"), regex, QRegExp::RegExp);
608 		DeleteAllFilesFromDirectory(
609 			folder + QDir::separator() + gPar->Get<QString>("zbuffer_postfix"), regex, QRegExp::RegExp);
610 		DeleteAllFilesFromDirectory(
611 			folder + QDir::separator() + gPar->Get<QString>("normal_postfix"), regex, QRegExp::RegExp);
612 		DeleteAllFilesFromDirectory(
613 			folder + QDir::separator() + gPar->Get<QString>("specular_postfix"), regex, QRegExp::RegExp);
614 	}
615 }
616