summaryrefslogtreecommitdiff
path: root/movement.c
blob: 0bbc0d9d17a9950099a54e884746999559223f65 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
#include "snowglobe-internal.h"
#include "snowglobe_options.h"
#include <math.h>
#include <float.h>


void
SnowflakeTransform (snowflakeRec * snow)
{

    glTranslatef (snow->y, snow->z, snow->x);
    glRotatef (-snow->psi, 0.0, 1.0, 0.0);
    glRotatef (snow->theta, 1.0, 0.0, 0.0);
}

void
newSnowflakePosition(SnowglobeScreen *as, int i)
{
    int sector = NRAND(as->hsize);
    float ang = randf(as->arcAngle*toRadians)-0.5*as->arcAngle*toRadians;
    float r = (as->radius-0.01*as->snow[i].size/2);
    float factor = sinf(0.5*(PI-as->arcAngle*toRadians))/
    		   sinf(0.5*(PI-as->arcAngle*toRadians)+fabsf(ang));
    ang += (0.5+((float) sector))*as->arcAngle*toRadians;
    ang = fmodf(ang,2*PI);
	
    float d = randf(1);
    d=(1-d*d)*r*factor;

    as->snow[i].x = d*cosf(ang);
    as->snow[i].y = d*sinf(ang);
    as->snow[i].z = 0.5;
}

void
SnowflakeDrift (CompScreen *s, int index)
{
    SNOWGLOBE_SCREEN (s);
    CUBE_SCREEN (s);

    //float oldXRotate = as->xRotate;
    //float oldVRotate = as->vRotate;
    
    (*cs->getRotation) (s, &(as->xRotate), &(as->vRotate));

    as->xRotate = fmodf( as->xRotate-cs->invert * (360.0f / s->hsize) *
           		 ((s->x* cs->nOutput)), 360 );
    
    snowflakeRec * snow = &(as->snow[index]);

    float speed = snow->speed*as->speedFactor;
    speed/=1000;
    float x = snow->x;
    float y = snow->y;
    float z = snow->z;

    float sideways = 2*(randf(2*speed)-speed);
    float vertical = -speed;

    if (snowglobeGetShakeCube(s))
    {
	x+= sideways*cosf(as->xRotate*toRadians)*cosf(as->vRotate*toRadians)
	   -vertical*cosf(as->xRotate*toRadians)*sinf(as->vRotate*toRadians);
	
    	y+= sideways*sinf(as->xRotate*toRadians)*cosf(as->vRotate*toRadians)
    	   +vertical*sinf(as->xRotate*toRadians)*sinf(as->vRotate*toRadians);
    	
	z+= sideways*sinf(as->vRotate*toRadians)
	   +vertical*cosf(as->vRotate*toRadians);
    }
    else
    {
	x+=sideways;
    	y+=sideways;
	z+=vertical;
    }
    

    float bottom = (snowglobeGetShowGround(s) ? getHeight(as->ground, x, y) : -0.5)+0.01*snow->size/2;

    if (z<bottom)
    {
	z = 0.5;
	newSnowflakePosition(as, index);
	    
	x = snow->x;
	y = snow->y;
    }

    float top = 0.5-0.01*snow->size/2;
    if (z>top)
    {
	z = top;
    }

    
    float ang = atan2f(y, x);

    int i;
    for (i=0; i< as->hsize; i++)
    {
	float cosAng = cosf(fmodf(i*as->arcAngle*toRadians-ang, 2*PI));
	if (cosAng<=0)
	    continue;

	float r = hypotf(x, y);
	float d = r*cosAng-(as->distance-0.01*snow->size/2);
	
	if (d>0)
	{
	    x -= d*cosf(ang)*fabsf(cosf(i*as->arcAngle*toRadians));
	    y -= d*sinf(ang)*fabsf(sinf(i*as->arcAngle*toRadians));
	}
    }

    snow->x = x;
    snow->y = y;
    snow->z = z;

    snow->psi = fmodf(snow->psi+snow->dpsi*as->speedFactor, 360);
    snow->theta= fmodf(snow->theta+snow->dtheta*as->speedFactor, 360);
}