-
Notifications
You must be signed in to change notification settings - Fork 0
/
physics.c
112 lines (94 loc) · 2.98 KB
/
physics.c
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
#include "inc/physics.h"
float Vector_norm( Vector2 vec ) {
return sqrtf( vec.x * vec.x + vec.y * vec.y );
}
void Physic_computeDelta( Object* obj ) {
obj->delta.x = floorf( obj->cp.x ) - floorf( obj->oldcp.x );
obj->delta.y = floorf( obj->cp.y ) - floorf( obj->oldcp.y );
if( obj->delta.x > 0 )
obj->dir.x = 1;
else if( obj->delta.x < 0 )
obj->dir.x = -1;
else
obj->dir.x = 0;
if( obj->delta.y > 0 )
obj->dir.y = 1;
else if( obj->delta.y < 0 )
obj->dir.y = -1;
else
obj->dir.y = 0;
}
void Physic_updatePosition( Object* obj ) {
/* p2 p3
* +---+
* | | cp
* | x |_ angle
* | | |
* +---+----
* p1 p4
*/
obj->diagonal = Vector_norm( obj->size );
float diagonal_2 = obj->diagonal / 2;
float inner_angle = atanf( obj->size.x / obj->size.y );
Vector2 CPtoP1 = { - diagonal_2 * cosf( obj->angle - inner_angle ), diagonal_2 * sinf( obj->angle - inner_angle ) };
Vector2 CPtoP2 = { diagonal_2 * cosf( obj->angle + inner_angle ), - diagonal_2 * sinf( obj->angle + inner_angle ) };
obj->p[ P_UP_LEFT ].x = obj->cp.x + CPtoP1.x;
obj->p[ P_UP_LEFT ].y = obj->cp.y + CPtoP1.y;
obj->p[ P_UP_RIGHT ].x = obj->cp.x + CPtoP2.x;
obj->p[ P_UP_RIGHT ].y = obj->cp.y + CPtoP2.y;
obj->p[ P_DOWN_RIGHT ].x = obj->cp.x - CPtoP1.x;
obj->p[ P_DOWN_RIGHT ].y = obj->cp.y - CPtoP1.y;
obj->p[ P_DOWN_LEFT ].x = obj->cp.x - CPtoP2.x;
obj->p[ P_DOWN_LEFT ].y = obj->cp.y - CPtoP2.y;
obj->propcp = (Vector2) { 0, 0 };
}
void Physic_initMovement( Object *obj, Vector2 gravity, Vector2 movement ) {
Physic_updatePosition( obj );
switch( obj->state ) {
case STATE_DYING:
case STATE_FALLDYING:
case STATE_EXITING:
case STATE_BLOWING:
case STATE_DEAD:
case STATE_GONE:
obj->force.x = 0;
obj->force.y = 0;
obj->v.x = 0;
obj->v.y = 0;
obj->should_move = 0;
break;
case STATE_DIGGING:
obj->force.x = gravity.x;
obj->force.y = gravity.y;
obj->should_move = 1;
if( obj->v.y >= -0.1 && obj->v.y <= 0.1 ) { //FLOAT_AROUND( obj->v.y, 0.0, 0.1 )
obj->v.x = ( obj->direction == DIRECTION_RIGHT ? 1 : -1 ) * movement.x / 2.0;
obj->v.y = ( obj->direction == DIRECTION_RIGHT ? 1 : -1 ) * movement.y / 2.0;
}
break;
default:
obj->force.x = gravity.x;
obj->force.y = gravity.y;
obj->should_move = 1;
if( obj->v.y >= -0.1 && obj->v.y <= 0.1 ) { //FLOAT_AROUND( obj->v.y, 0.0, 0.1 )
obj->v.x = ( obj->direction == DIRECTION_RIGHT ? 1 : -1 ) * movement.x;
obj->v.y = ( obj->direction == DIRECTION_RIGHT ? 1 : -1 ) * movement.y;
}
break;
}
}
void Physic_compute( Object *obj, double dt ) {
//obj->torque = obj->cp.x * obj->force.y - obj->cp.y * obj->force.x;
obj->a.x = obj->force.x / obj->mass;
obj->a.y = obj->force.y / obj->mass;
obj->v.x += obj->a.x * dt;
obj->v.y += obj->a.y * dt;
obj->oldcp.x = obj->cp.x;
obj->oldcp.y = obj->cp.y;
obj->cp.x += obj->v.x * dt;
obj->cp.y += obj->v.y * dt;
/*float aa = obj->torque / obj->moment_of_inertia;
obj->av += aa * dt;
obj->angle += obj->av * dt;*/
Physic_computeDelta( obj );
}