1 /**
2 * This file is a part of the Cairo-Dock project
3 *
4 * Copyright : (C) see the 'copyright' file.
5 * E-mail    : see the 'copyright' file.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License
9 * as published by the Free Software Foundation; either version 3
10 * of the License, or (at your option) any later version.
11 *
12 * This program 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 * You should have received a copy of the GNU General Public License
17 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
18 */
19 
20 #include <stdlib.h>
21 #include <string.h>
22 #include <math.h>
23 
24 #include "applet-struct.h"
25 #include "applet-rays.h"
26 
cd_animations_init_rays(Icon * pIcon,CairoDock * pDock,double dt)27 CairoParticleSystem *cd_animations_init_rays (Icon *pIcon, CairoDock *pDock, double dt)
28 {
29 	if (myData.iRaysTexture == 0)
30 		myData.iRaysTexture = cd_animations_load_rays_texture ();
31 	CairoParticleSystem *pRaysParticleSystem = cairo_dock_create_particle_system (myConfig.iNbRaysParticles,
32 		myData.iRaysTexture,
33 		pIcon->fWidth,
34 		pDock->container.bIsHorizontal ? pIcon->image.iHeight : pIcon->image.iWidth);
35 	pRaysParticleSystem->dt = dt;
36 	pRaysParticleSystem->bDirectionUp = (pDock->container.bIsHorizontal ? pDock->container.bDirectionUp : ! pDock->container.bDirectionUp);
37 	pRaysParticleSystem->bAddLuminance = TRUE;
38 
39 	double a = myConfig.fRaysParticleSpeed;
40 	static double epsilon = 0.1;
41 	double r = myConfig.iRaysParticleSize;
42 	double fBlend, fPhase;
43 	double vmax = 1. / myConfig.iSpotDuration;
44 	CairoParticle *p;
45 	int i;
46 	for (i = 0; i < myConfig.iNbRaysParticles; i ++)
47 	{
48 		p = &(pRaysParticleSystem->pParticles[i]);
49 
50 		fPhase = (2 * g_random_double () - 1) * G_PI;
51 		p->x = .9 * sin (fPhase);
52 		p->z = cos (fPhase);
53 		p->fHeight = r*(p->z + 2)/3;
54 		p->y = ((1 - p->z) * CD_ANIMATIONS_SPOT_HEIGHT + p->fHeight/2) / pRaysParticleSystem->fHeight;
55 		p->fWidth = (p->z + 2)/2;
56 
57 
58 		p->vx = .25 * p->x / myConfig.iSpotDuration * dt;
59 		p->vy = a * vmax * ((p->z + 1)/2 * g_random_double () + epsilon) * dt;
60 		p->iInitialLife = MIN (1./ p->vy, ceil (myConfig.iSpotDuration / dt));
61 		p->iLife = p->iInitialLife;
62 
63 		if (myConfig.bMysticalRays)
64 		{
65 			p->color[0] = g_random_double ();
66 			p->color[1] = g_random_double ();
67 			p->color[2] = g_random_double ();
68 		}
69 		else
70 		{
71 			fBlend = g_random_double ();
72 			p->color[0] = fBlend * myConfig.pRaysColor1[0] + (1 - fBlend) * myConfig.pRaysColor2[0];
73 			p->color[1] = fBlend * myConfig.pRaysColor1[1] + (1 - fBlend) * myConfig.pRaysColor2[1];
74 			p->color[2] = fBlend * myConfig.pRaysColor1[2] + (1 - fBlend) * myConfig.pRaysColor2[2];
75 		}
76 		p->color[3] = 1.;
77 
78 		p->fSizeFactor = .3;
79 		p->fResizeSpeed = .1;
80 	}
81 
82 	return pRaysParticleSystem;
83 }
84 
85 
86 
cd_animations_rewind_rays_particle(CairoParticle * p,double dt,double fHeight)87 void cd_animations_rewind_rays_particle (CairoParticle *p, double dt, double fHeight)
88 {
89 	static double epsilon = 0.1;
90 	double a = myConfig.fRaysParticleSpeed/3;
91 	double r = myConfig.iRaysParticleSize;
92 	double vmax = 1. / myConfig.iSpotDuration;
93 	double fPhase = (2 * g_random_double () - 1) * G_PI;
94 	//p->x = 2 * g_random_double () - 1;
95 	p->x = .9 * sin (fPhase);
96 	p->z = cos (fPhase);
97 	p->fHeight = r*(p->z + 2)/3;
98 	p->y = ((1 - p->z) * CD_ANIMATIONS_SPOT_HEIGHT + p->fHeight/2) / fHeight;
99 	p->vy = a * vmax * ((p->z + 1)/2 * g_random_double () + epsilon) * dt;
100 	p->vx = .25 * p->x / myConfig.iSpotDuration * dt;
101 
102 	p->iInitialLife = MIN (1./ p->vy, ceil (myConfig.iSpotDuration / dt));
103 	p->iLife = p->iInitialLife;
104 
105 	p->fSizeFactor = .3;
106 }
107 
108 
cd_animations_update_rays_system(CairoParticleSystem * pParticleSystem,gboolean bContinue)109 gboolean cd_animations_update_rays_system (CairoParticleSystem *pParticleSystem, gboolean bContinue)
110 {
111 	gboolean bAllParticlesEnded = TRUE;
112 	CairoParticle *p;
113 	int i;
114 	for (i = 0; i < pParticleSystem->iNbParticles; i ++)
115 	{
116 		p = &(pParticleSystem->pParticles[i]);
117 
118 		p->x += p->vx;
119 		p->y += p->vy;
120 		p->color[3] = 1.*p->iLife / p->iInitialLife;
121 		if (p->fSizeFactor < 1)
122 			p->fSizeFactor += p->fResizeSpeed;
123 		if (p->iLife > 0)
124 		{
125 			p->iLife --;
126 			if (bContinue && p->iLife == 0)
127 			{
128 				cd_animations_rewind_rays_particle (p, pParticleSystem->dt, pParticleSystem->fHeight);
129 			}
130 			if (bAllParticlesEnded && p->iLife != 0)
131 				bAllParticlesEnded = FALSE;
132 		}
133 		else if (bContinue)
134 			cd_animations_rewind_rays_particle (p, pParticleSystem->dt, pParticleSystem->fHeight);
135 	}
136 	return ! bAllParticlesEnded;
137 }
138