-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfish.cpp
More file actions
135 lines (97 loc) · 6.08 KB
/
fish.cpp
File metadata and controls
135 lines (97 loc) · 6.08 KB
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
123
124
125
126
127
128
129
130
131
132
133
134
#include "fish.h"
Fish::Fish() {}
Fish::Fish(glm::vec2* centers, float* distances, float* radii, int id){
for(int i = 0; i < NUM_OF_JOINTS; i++){
this->joints[i] = Joint(centers[i], distances[i], radii[i]);
}
this->tail_fin_joints[0] = this->joints[NUM_OF_JOINTS-1];
this->tail_fin_joints[0].desiredDistance = 1.5f;
this->tail_fin_joints[1] = this->tail_fin_joints[0];
this->tail_fin_joints[1].desiredDistance = 1.5f;
this->fishID = id;
this->hit_checks_result = 0;
this->hit_check_distance = 8.0f * radii[0];
this->updateHitChecks();
for(int i = 0; i < NUM_OF_JOINTS + 2; i++){
this->tex_coords[i*4 ] = static_cast<float>(i)/static_cast<float>(NUM_OF_JOINTS);
// this->tex_coords[i*4+1] = 0.1;
this->tex_coords[i*4+1] = 0.1 + 0.1 * std::clamp(i-10, 0, 4);
this->tex_coords[i*4+2] = static_cast<float>(i)/static_cast<float>(NUM_OF_JOINTS);
// this->tex_coords[i*4+3] = 0.9;
this->tex_coords[i*4+3] = 0.9 - 0.1 * std::clamp(i-10, 0, 4);
}
}
Fish::~Fish(){
}
void Fish::updateMoveDir(glm::vec2 new_move_dir){
this->next_move_dir = new_move_dir;
}
void Fish::Move(float delta_time){
// moves the head of the fish in the direction passed into the function, then updates the position of the rest of the joints
this->joints[0].moveDirection = glm::normalize(next_move_dir);
this->joints[0].Center += this->joints[0].moveDirection * FISH_SPEED * delta_time;
glm::vec2 head_point;
head_point = Global::rotateVector(this->joints[0].moveDirection, -20) * this->joints[0].circleRadius * 1.3f;
this->outline_vertices[0] = head_point.x;
this->outline_vertices[1] = head_point.y;
head_point = Global::rotateVector(this->joints[0].moveDirection, 20) * this->joints[0].circleRadius * 1.3f;
this->outline_vertices[2] = head_point.x;
this->outline_vertices[3] = head_point.y;
head_point = Global::rotateVector(this->joints[0].moveDirection, -50) * this->joints[0].circleRadius;
this->outline_vertices[4] = head_point.x;
this->outline_vertices[5] = head_point.y;
head_point = Global::rotateVector(this->joints[0].moveDirection, 50) * this->joints[0].circleRadius;
this->outline_vertices[6] = head_point.x;
this->outline_vertices[7] = head_point.y;
// also calculates the vertices of the outline
glm::vec2 point = Global::CalculateNormal(this->joints[0].moveDirection);
this->outline_vertices[8] = point.x * this->joints[0].circleRadius;
this->outline_vertices[9] = point.y * this->joints[0].circleRadius;
point = -point;
this->outline_vertices[10] = point.x * this->joints[0].circleRadius;
this->outline_vertices[11] = point.y * this->joints[0].circleRadius;
this->updateJoints();
this->updateHitChecks();
// print_outline_data();
}
void Fish::updateJoints(){
// used to update the position of all of the joints (except the first one, which is updated by the move function) and updates the outline vertices
for(int i = 1; i < NUM_OF_JOINTS; i++){
float distance_between_joints = glm::distance(this->joints[i-1].Center, this->joints[i].Center);
float desired_distance = this->joints[i].desiredDistance;
this->joints[i].moveDirection = glm::normalize(this->joints[i-1].Center - this->joints[i].Center);
if(distance_between_joints - desired_distance > 1e-2 || distance_between_joints - desired_distance< 1e-3){
this->joints[i].Center += this->joints[i].moveDirection * (distance_between_joints - desired_distance);
}
// The outline vertex data is positioned in relation to the center of the head
glm::vec2 pointOnCircle = Global::CalculateNormal(this->joints[i].moveDirection);
glm::vec2 relativePosition = this->joints[i].Center - this->joints[0].Center;
this->outline_vertices[4*i+8] = relativePosition.x + pointOnCircle.x * this->joints[i].circleRadius;
this->outline_vertices[4*i+9] = relativePosition.y + pointOnCircle.y * this->joints[i].circleRadius;
pointOnCircle = -pointOnCircle;
this->outline_vertices[4*i+10] = relativePosition.x + pointOnCircle.x * this->joints[i].circleRadius;
this->outline_vertices[4*i+11] = relativePosition.y + pointOnCircle.y * this->joints[i].circleRadius;
}
if(this->tail_fin_joints[0].desiredDistance - glm::distance(this->tail_fin_joints[0].Center, this->joints[NUM_OF_JOINTS-1].Center) < 1e-2){
tail_fin_joints[0].moveDirection = glm::normalize(joints[NUM_OF_JOINTS-1].Center - tail_fin_joints[0].Center);
tail_fin_joints[0].Center += tail_fin_joints[0].moveDirection * (glm::distance(tail_fin_joints[0].Center, joints[NUM_OF_JOINTS-1].Center) - tail_fin_joints[0].desiredDistance);
}
if(this->tail_fin_joints[1].desiredDistance - glm::distance(this->tail_fin_joints[0].Center, this->tail_fin_joints[1].Center) < 1e-2){
tail_fin_joints[1].moveDirection = glm::normalize(tail_fin_joints[0].Center - tail_fin_joints[1].Center);
tail_fin_joints[1].Center += tail_fin_joints[1].moveDirection * (glm::distance(tail_fin_joints[1].Center, tail_fin_joints[0].Center) - tail_fin_joints[1].desiredDistance);
}
}
void Fish::updateHitChecks(){
this->hit_checks_result = 0;
float degreeChange = HIT_CHECK_ANGLE/(NUM_OF_HIT_CHECKS-1);
for(int i = -(NUM_OF_HIT_CHECKS/2), j = 0; j < NUM_OF_HIT_CHECKS; j++, i++){
this->hit_checks[j] = Global::rotateVector(this->joints[0].moveDirection, -degreeChange * i);
glm::vec2 hit_check_world_pos = this->joints[0].Center + this->hit_checks[j] * hit_check_distance;
// The if checks if the position of the hit check is outside a square with round corners, the exponent (4 in this case) determines the roundness (smaller exp -> rounder)
// the result of 1.0 is just on the edge of the window, less than is inside, more than is on the outside
if( powf(std::abs(hit_check_world_pos.x/FRUSTUM_HALF_WIDTH), 4) +
powf(std::abs(hit_check_world_pos.y/(FRUSTUM_HALF_WIDTH*Global::aspect_ratio)), 4) >= 1.0){
this->hit_checks_result += (i < 0) ? -1 : 1;
}
}
}