summaryrefslogtreecommitdiff
path: root/movement.c
blob: 3711fd321678ff8fb4a2984d33f36dc459d55b3a (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
#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(hSize);
    float ang = randf(2*PI/q)-PI/q;
    float r = (radius-0.01*as->snow[i].size/2);
    float factor = sinf(PI*(0.5-1/q))/sinf(PI*(0.5-1/q)+fabsf(ang));
    ang += (0.5+((float) sector))*2*PI/q;
    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*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 = (renderGround ? 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 = atan2(y, x);

    int i;
    for (i=0; i<hSize; i++)
    {
	float cosAng = cosf(fmodf(2*i*PI/q-ang, 2*PI));
	if (cosAng<=0)
	    continue;

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

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

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