|
|
|
|
|
|
|
class AbstractBody { |
|
|
|
|
|
|
|
|
|
|
|
|
|
constructor(scale, motors_torque){ |
|
this.SCALE = scale; |
|
this.MOTORS_TORQUE = motors_torque; |
|
this.body_parts = []; |
|
this.motors = []; |
|
this.is_selected = false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
get_state_size(){ |
|
return this.get_motors_state().length; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
get_motors_state(){ |
|
let state = []; |
|
for(let motor of this.motors){ |
|
let motor_info = motor.GetUserData(); |
|
if(motor_info.check_contact){ |
|
let s = [ |
|
motor.GetJointAngle() + motor_info.angle_correction, |
|
motor.GetJointSpeed() / motor_info.speed_control, |
|
0.0 |
|
] |
|
if(motor_info.contact_body.GetUserData().has_contact){ |
|
s[2] = 1.0; |
|
} |
|
state = state.concat(s); |
|
} |
|
else{ |
|
state = state.concat([ |
|
motor.GetJointAngle() + motor_info.angle_correction, |
|
motor.GetJointSpeed() / motor_info.speed_control |
|
]) |
|
} |
|
} |
|
return state; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
get_action_size(){ |
|
return this.motors.length; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
activate_motors(actions){ |
|
for(let i = 0; i < this.motors.length; i++){ |
|
this.motors[i].SetMotorSpeed(this.motors[i].GetUserData().speed_control * Math.sign(actions[i])); |
|
let clamp01 = Math.max(0, Math.min(Math.abs(actions[i]), 1)); |
|
this.motors[i].SetMaxMotorTorque(this.MOTORS_TORQUE * clamp01); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
draw(world, init_x, init_y, force_to_center){} |
|
|
|
|
|
|
|
|
|
|
|
get_elements_to_render(){ |
|
return this.body_parts; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
isPosInside(pos){ |
|
for(let body of this.body_parts){ |
|
let shape = body.GetFixtureList().GetShape(); |
|
let vertices = []; |
|
for(let i = 0; i < shape.m_count; i++){ |
|
let world_pos = body.GetWorldPoint(shape.m_vertices[i]); |
|
vertices.push({x: world_pos.x, y: world_pos.y}); |
|
} |
|
|
|
|
|
let nb_intersections = 0; |
|
for(let i = 0; i < vertices.length; i++){ |
|
let v1 = vertices[i]; |
|
let v2; |
|
if(i == vertices.length - 1){ |
|
v2 = vertices[0]; |
|
} |
|
else { |
|
v2 = vertices[i+1]; |
|
} |
|
|
|
|
|
if(pos.y >= Math.min(v1.y, v2.y) && pos.y <= Math.max(v1.y, v2.y)){ |
|
let intersection_x; |
|
|
|
|
|
let a = (v2.y - v1.y) / (v2.x - v1.x); |
|
let b = v1.y - a * v1.x; |
|
|
|
|
|
if(Math.abs(a) == Infinity){ |
|
intersection_x = v1.x; |
|
} |
|
else{ |
|
intersection_x = (pos.y - b) / a; |
|
} |
|
|
|
|
|
if(intersection_x >= pos.x) { |
|
nb_intersections += 1; |
|
} |
|
} |
|
} |
|
|
|
|
|
if(nb_intersections % 2 != 0){ |
|
return true; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
|
|
|
|
|
|
|
|
destroy(world){ |
|
for(let body of this.body_parts){ |
|
world.DestroyBody(body); |
|
} |
|
this.body_parts = []; |
|
this.motors = []; |
|
} |
|
} |