1// Head 2HULL_POLYGON = [ 3 [-20, +12], [+6, +12], 4 [+15, +4], [+15, -4], 5 [+6, -12], [-20, -12] 6]; 7 8BODY_P1 = [ 9 [-8, +9], [+8, +12], 10 [+8, -12], [-8, -9] 11]; 12 13BODY_P2 = [ 14 [-8, +4], [+8, +9], 15 [+8, -9], [-8, -4] 16]; 17 18// Tail 19BODY_P3 = [ 20 [-4, +2], [+4, +4], 21 [+4, -4], [-4, -2] 22]; 23 24FIN = [ 25 [-1, -10], [-1, +10], 26 [+1, +10], [+1, -10] 27]; 28 29HULL_BOTTOM_WIDTH = 35; 30const SPEED = 6; 31 32/** 33 * @classdesc Fish morphology. 34 */ 35class FishBody extends SwimmerAbstractBody { 36 /** 37 * @constructor 38 * @param scale {number} - Scale of the environment 39 * @param motors_torque {number} 40 * @param density {number} - Density of the agent's body. 41 * @param nb_steps_outside_water {number} 42 */ 43 constructor(scale, motors_torque=80, density, nb_steps_outside_water=600) { 44 super(scale, motors_torque, density, nb_steps_outside_water); 45 this.TORQUE_PENALTY = 0.00035; 46 47 this.AGENT_WIDTH = HULL_BOTTOM_WIDTH / this.SCALE; 48 this.AGENT_HEIGHT = 18 / this.SCALE; 49 this.AGENT_CENTER_HEIGHT = 9 / this.SCALE; 50 51 this.remove_reward_on_head_angle = true; 52 53 this.fins = []; 54 this.tail = null; 55 } 56 57 draw(world, init_x, init_y){ 58 59 let vertices; 60 let rjd; 61 let joint_motor; 62 63 // HULL 64 let hull_fd = new b2.FixtureDef(); 65 hull_fd.shape = new b2.PolygonShape(); 66 vertices = []; 67 for(let vertex of HULL_POLYGON){ 68 vertices.push(new b2.Vec2(vertex[0] / this.SCALE, vertex[1] / this.SCALE)); 69 } 70 hull_fd.shape.Set(vertices, HULL_POLYGON.length); 71 hull_fd.density = this.DENSITY; 72 hull_fd.friction = 0.1; 73 hull_fd.filter.categoryBits = 0x20; 74 hull_fd.filter.maskBits = 0x000F; // 0.99 bouncy 75 76 let hull_bd = new b2.BodyDef(); 77 hull_bd.type = b2.Body.b2_dynamicBody; 78 hull_bd.position.Set(init_x, init_y); 79 let hull = world.CreateBody(hull_bd); 80 hull.CreateFixture(hull_fd); 81 hull.color1 = "#806682"; // [0.5, 0.4, 0.9] 82 hull.color2 = "#4D4D80"; 83 hull.SetUserData(new CustomBodyUserData(true, false, "head")); 84 this.body_parts.push(hull); 85 this.reference_head_object = hull; 86 87 // BODY_P1 88 let body_p1_x = init_x - 35 / 2 / this.SCALE - 16 / 2 / this.SCALE; 89 let body_p1_fd = new b2.FixtureDef(); 90 body_p1_fd.shape = new b2.PolygonShape(); 91 vertices = []; 92 for(let vertex of BODY_P1){ 93 vertices.push(new b2.Vec2(vertex[0] / this.SCALE, vertex[1] / this.SCALE)); 94 } 95 body_p1_fd.shape.Set(vertices, BODY_P1.length); 96 body_p1_fd.density = this.DENSITY; 97 body_p1_fd.restitution = 0.0; 98 body_p1_fd.filter.categoryBits = 0x20; 99 body_p1_fd.filter.maskBits = 0x000F; // 0.99 bouncy 100 101 let body_p1_bd = new b2.BodyDef(); 102 body_p1_bd.type = b2.Body.b2_dynamicBody; 103 body_p1_bd.position.Set(body_p1_x, init_y); 104 let body_p1 = world.CreateBody(body_p1_bd); 105 body_p1.CreateFixture(body_p1_fd); 106 body_p1.color1 = "#806682"; // [0.5, 0.4, 0.9] 107 body_p1.color2 = "#4D4D80"; 108 body_p1.SetUserData(new CustomBodyUserData(true, false, "body")); 109 this.body_parts.push(body_p1); 110 111 // Revolute joint between HULL and BODY_P1 112 rjd = new b2.RevoluteJointDef(); 113 rjd.Initialize(hull, body_p1, new b2.Vec2(init_x - 35 / 2 / this.SCALE, init_y)); 114 rjd.enableMotor = true; 115 rjd.enableLimit = true; 116 rjd.maxMotorTorque = this.MOTORS_TORQUE; 117 rjd.motorSpeed = 1; 118 rjd.lowerAngle = -0.1 * Math.PI; 119 rjd.upperAngle = 0.2 * Math.PI; 120 joint_motor = world.CreateJoint(rjd); 121 joint_motor.SetUserData(new CustomMotorUserData("neck", SPEED, true, 0.0, body_p1)); 122 this.motors.push(joint_motor); 123 124 // BODY_P2 125 let body_p2_x = body_p1_x - 16 / 2 / this.SCALE - 16 / 2 / this.SCALE; 126 let body_p2_fd = new b2.FixtureDef(); 127 body_p2_fd.shape = new b2.PolygonShape(); 128 vertices = []; 129 for(let vertex of BODY_P2){ 130 vertices.push(new b2.Vec2(vertex[0] / this.SCALE, vertex[1] / this.SCALE)); 131 } 132 body_p2_fd.shape.Set(vertices, BODY_P2.length); 133 body_p2_fd.density = this.DENSITY; 134 body_p2_fd.restitution = 0.0; 135 body_p2_fd.filter.categoryBits = 0x20;
136 body_p2_fd.filter.maskBits = 0x000F; 137 138 let body_p2_bd = new b2.BodyDef(); 139 body_p2_bd.type = b2.Body.b2_dynamicBody; 140 body_p2_bd.position.Set(body_p2_x, init_y); 141 let body_p2 = world.CreateBody(body_p2_bd); 142 body_p2.CreateFixture(body_p2_fd); 143 body_p2.color1 = "#806682"; // [0.5, 0.4, 0.9] 144 body_p2.color2 = "#4D4D80"; 145 body_p2.SetUserData(new CustomBodyUserData(true, false, "body")); 146 this.body_parts.push(body_p2); 147 148 // Revolute joint between BODY_P1 and BODY_P2 149 rjd = new b2.RevoluteJointDef(); 150 rjd.Initialize(body_p1, body_p2, new b2.Vec2(body_p1_x - 16 / 2 / this.SCALE, init_y)); 151 rjd.enableMotor = true; 152 rjd.enableLimit = true; 153 rjd.maxMotorTorque = this.MOTORS_TORQUE; 154 rjd.motorSpeed = 1; 155 rjd.lowerAngle = -0.15 * Math.PI; 156 rjd.upperAngle = 0.15 * Math.PI; 157 joint_motor = world.CreateJoint(rjd); 158 joint_motor.SetUserData(new CustomMotorUserData("hip", SPEED, true, 0.0, body_p2)); 159 this.motors.push(joint_motor); 160 161 // BODY_P3 - TAIL 162 let body_p3_x = body_p2_x - 16 / 2 / this.SCALE - 8 / 2 / this.SCALE; 163 let body_p3_fd = new b2.FixtureDef(); 164 body_p3_fd.shape = new b2.PolygonShape(); 165 vertices = []; 166 for(let vertex of BODY_P3){ 167 vertices.push(new b2.Vec2(vertex[0] / this.SCALE, vertex[1] / this.SCALE)); 168 } 169 body_p3_fd.shape.Set(vertices, BODY_P3.length); 170 body_p3_fd.density = this.DENSITY; 171 body_p3_fd.restitution = 0.0; 172 body_p3_fd.filter.categoryBits = 0x20; 173 body_p3_fd.filter.maskBits = 0x000F; 174 175 let body_p3_bd = new b2.BodyDef(); 176 body_p3_bd.type = b2.Body.b2_dynamicBody; 177 body_p3_bd.position.Set(body_p3_x, init_y); 178 let body_p3 = world.CreateBody(body_p3_bd); 179 body_p3.CreateFixture(body_p3_fd); 180 body_p3.color1 = "#806682"; // [0.5, 0.4, 0.9] 181 body_p3.color2 = "#4D4D80"; 182 body_p3.SetUserData(new CustomBodyUserData(true, false, "body")); 183 this.body_parts.push(body_p3); 184 this.tail = body_p3; 185 186 // Revolute joint between BODY_P2 and BODY_P3 187 rjd = new b2.RevoluteJointDef(); 188 rjd.Initialize(body_p2, body_p3, new b2.Vec2(body_p2_x - 16 / 2 / this.SCALE, init_y)); 189 rjd.enableMotor = true; 190 rjd.enableLimit = true; 191 rjd.maxMotorTorque = this.MOTORS_TORQUE; 192 rjd.motorSpeed = 1; 193 rjd.lowerAngle = -0.3 * Math.PI; 194 rjd.upperAngle = 0.3 * Math.PI; 195 joint_motor = world.CreateJoint(rjd); 196 joint_motor.SetUserData(new CustomMotorUserData("knee", SPEED, true, 0.0, body_p3)); 197 this.motors.push(joint_motor); 198 199 // FINS 200 let fin_fd = new b2.FixtureDef(); 201 fin_fd.shape = new b2.PolygonShape(); 202 vertices = []; 203 for(let vertex of FIN){ 204 vertices.push(new b2.Vec2(vertex[0] / this.SCALE, vertex[1] / this.SCALE)); 205 } 206 fin_fd.shape.Set(vertices, FIN.length); 207 fin_fd.density = this.DENSITY; 208 fin_fd.restitution = 0.0; 209 fin_fd.filter.categoryBits = 0x20; 210 fin_fd.filter.maskBits = 0x000F; 211 212 let fin_positions = [ 213 [init_x, init_y - 22 / 2 / this.SCALE + 0.2], 214 ]; 215 let fin_angle = -0.2 * Math.PI; 216 let middle_fin_x_distance = Math.sin(fin_angle) * 20 / 2 / this.SCALE; 217 let middle_fin_y_distance = Math.cos(fin_angle) * 20 / 2 / this.SCALE; 218 219 for(let fin_pos of fin_positions){ 220 let current_fin_x = fin_pos[0] + middle_fin_x_distance; 221 let current_fin_y = fin_pos[1] - middle_fin_y_distance; 222 223 let fin_bd = new b2.BodyDef(); 224 fin_bd.type = b2.Body.b2_dynamicBody; 225 fin_bd.position.Set(current_fin_x, current_fin_y); 226 let fin = world.CreateBody(fin_bd); 227 fin.CreateFixture(fin_fd); 228 fin.color1 = "#806682"; // [0.5, 0.4, 0.9] 229 fin.color2 = "#4D4D80"; 230 fin.SetUserData(new CustomBodyUserData(true, false, "fin")); 231 this.body_parts.push(fin); 232 this.fins.push(fin); 233 234 // Revolute joint between HULL and FIN 235 rjd = new b2.RevoluteJointDef(); 236 rjd.Initialize(hull, fin, new b2.Vec2(fin_pos[0], fin_pos[1])); 237 rjd.enableMotor = true; 238 rjd.enableLimit = true; 239 rjd.maxMotorTorque = this.MOTORS_TORQUE; 240 rjd.motorSpeed = 1; 241 rjd.lowerAngle = -0.3 * Math.PI; 242 rjd.upperAngle = 0.2 * Math.PI; 243 joint_motor = world.CreateJoint(rjd); 244 joint_motor.SetUserData(new CustomMotorUserData("shoulder", SPEED, true, 0.0, fin)); 245 this.motors.push(joint_motor); 246 } 247 } 248}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.