Commit d6ce1354 authored by Roque's avatar Roque

[WEB-WORKER] [WIP] Drone simulator

parent 46586276
/// <reference path="./GameManager.ts" />
TAKEOFF_RADIUS = 60;
LOITER_LIMIT = 30;
LOITER_RADIUS_FACTOR = 0.60;
LOITER_SPEED_FACTOR = 1.5;
var DroneAaileFixeAPI = /** @class */ (function () {
//*************************************************** CONSTRUCTOR **************************************************
function DroneAaileFixeAPI(gameManager, team, flight_parameters) {
this._gameManager = gameManager;
this._team = team;
this._flight_parameters = flight_parameters;
this._loiter_radius = 0;
this._last_loiter_point_reached = -1;
this._last_altitude_point_reached = -1;
}
Object.defineProperty(DroneAaileFixeAPI.prototype, "team", {
//*************************************************** ACCESSOR *****************************************************
get: function () {
if (this._team == "L")
return this._gameManager.teamLeft;
else if (this._team == "R")
return this._gameManager.teamRight;
},
enumerable: true,
configurable: true
});
//*************************************************** FUNCTIONS ****************************************************
//#region ------------------ Internal
DroneAaileFixeAPI.prototype.internal_sendMsg = function (msg, to) {
var _this = this;
_this._gameManager.delay(function () {
if (to < 0) {
// Send to all drones
_this.team.forEach(function (drone) {
if (drone.infosMesh) {
try {
drone.onGetMsg(msg);
}
catch (error) {
console.warn('Drone crashed on sendMsg due to error:', error);
drone._internal_crash();
}
}
});
}
else {
// Send to specific drone
if (drone.infosMesh) {
try {
_this.team[to].onGetMsg(msg);
}
catch (error) {
console.warn('Drone crashed on sendMsg due to error:', error);
_this.team[to]._internal_crash();
}
}
}
}, GAMEPARAMETERS.latency.communication);
};
//#endregion
//#region ------------------ Accessible from AI
DroneAaileFixeAPI.prototype.log = function (msg) {
console.log("API say : " + msg);
};
DroneAaileFixeAPI.prototype.getGameParameter = function (name) {
if (["gameTime", "mapSize", "teamSize", "derive", "meteo", "initialHumanAreaPosition"].includes(name))
return this._gameManager.gameParameter[name];
};
DroneAaileFixeAPI.prototype._isWithinDroneView = function (drone_position, element_position) {
// Check if element is under the drone cone-view
var angle = GAMEPARAMETERS.drone.viewAngle ? GAMEPARAMETERS.drone.viewAngle : 60,
radius = drone_position.z * Math.tan(angle/2 * Math.PI/180),
distance = (drone_position.x - element_position.x) * (drone_position.x - element_position.x) +
(drone_position.y - element_position.y) * (drone_position.y - element_position.y);
if (distance < (radius*radius))
return true;
return false;
};
DroneAaileFixeAPI.prototype._getProbabilityOfDetection = function (drone_position) {
var h = drone_position.z,
km = GAMEPARAMETERS.meteo;
prob = 20 * (1 + (110-h)/25) * km;
return prob;
};
DroneAaileFixeAPI.prototype.isHumanPositionSpottedCalculation = function (drone) {
var context = this,
result = false,
drone_position = drone.infosMesh.position;
//swap axes back
drone_position = {
x: drone_position.x,
y: drone_position.z,
z: drone_position.y
};
context._gameManager.teamRight.forEach(function (human) {
if (human.infosMesh && context._isWithinDroneView(drone_position, human.position)) {
var prob = context._getProbabilityOfDetection(drone_position),
random = Math.floor(Math.random()*101);
if (random < prob)
result = true;
}
});
return result;
};
DroneAaileFixeAPI.prototype.isHumanPositionSpotted = function (drone) {
var context = this,
human_detected;
if (drone.__is_calculating_human_position !== true) {
drone.__is_calculating_human_position = true;
//human detection is done with the info captured by the drone
//at the moment this method is called
human_detected = context.isHumanPositionSpottedCalculation(drone);
context._gameManager.delay(function () {
drone.__is_calculating_human_position = false;
try {
drone.onCapture(human_detected);
} catch (error) {
console.warn('Drone crashed on capture due to error:', error);
drone._internal_crash();
}
}, 2000);
}
};
DroneAaileFixeAPI.prototype.processCoordinates = function (lat, lon, z, r) {
if(isNaN(lat) || isNaN(lon) || isNaN(z)){
throw new Error('Target coordinates must be numbers');
}
var flightParameters = this.getFlightParameters();
function longitudToX(lon, flightParameters) {
return (flightParameters.MAP_SIZE / 360.0) * (180 + lon);
}
function latitudeToY(lat, flightParameters) {
return (flightParameters.MAP_SIZE / 180.0) * (90 - lat);
}
function normalizeToMap(x, y, flightParameters) {
var n_x = (x - flightParameters.MIN_X) / (flightParameters.MAX_X - flightParameters.MIN_X),
n_y = (y - flightParameters.MIN_Y) / (flightParameters.MAX_Y - flightParameters.MIN_Y);
return [n_x * 1000 - flightParameters.MAP_SIZE / 2, n_y * 1000 - flightParameters.MAP_SIZE / 2];
}
var x = longitudToX(lon, flightParameters),
y = latitudeToY(lat, flightParameters),
position = normalizeToMap(x, y, flightParameters);
if (z > flightParameters.start_AMSL) {
z -= flightParameters.start_AMSL;
}
var processed_coordinates = {
x: position[0],
y: position[1],
z: z
};
if (r && r > LOITER_LIMIT) {
this._loiter_radius = r * LOITER_RADIUS_FACTOR;
this._loiter_center = processed_coordinates;
this._loiter_coordinates = [];
this._last_loiter_point_reached = -1;
var x1, y1;
//for (var angle = 0; angle <360; angle+=8){ //counter-clockwise
for (var angle = 360; angle > 0; angle-=8){ //clockwise
x1 = this._loiter_radius * Math.cos(angle * (Math.PI / 180)) + this._loiter_center.x;
y1 = this._loiter_radius * Math.sin(angle * (Math.PI / 180)) + this._loiter_center.y;
this._loiter_coordinates.push(this.processCurrentPosition(x1, y1, z));
}
}
this._last_altitude_point_reached = -1;
this.takeoff_path = [];
return processed_coordinates;
};
DroneAaileFixeAPI.prototype.processCurrentPosition = function (x, y, z) {
//convert x-y coordinates into latitud-longitude
var flightParameters = this.getFlightParameters();
var lon = x + flightParameters.map_width / 2;
lon = lon / 1000;
lon = lon * (flightParameters.MAX_X - flightParameters.MIN_X) + flightParameters.MIN_X;
lon = lon / (flightParameters.map_width / 360.0) - 180;
var lat = y + flightParameters.map_height / 2;
lat = lat / 1000;
lat = lat * (flightParameters.MAX_Y - flightParameters.MIN_Y) + flightParameters.MIN_Y;
lat = 90 - lat / (flightParameters.map_height / 180.0);
return {
x: lat,
y: lon,
z: z
};
};
DroneAaileFixeAPI.prototype.loiter = function (drone) {
function distance(c1, c2) {
var R = 6371e3,
q1 = c1[0] * Math.PI / 180,
q2 = c2[0] * Math.PI / 180,
dq = (c2[0] - c1[0]) * Math.PI / 180,
dl = (c2[1] - c1[1]) * Math.PI / 180,
a = Math.sin(dq / 2) * Math.sin(dq / 2) +
Math.cos(q1) * Math.cos(q2) *
Math.sin(dl / 2) * Math.sin(dl / 2),
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
if (this._loiter_radius > LOITER_LIMIT) {
var drone_pos = drone.getCurrentPosition();
//shift loiter circle to nearest point
if (this._last_loiter_point_reached === -1) {
if (!this.shifted) {
drone._maxSpeed = drone._maxSpeed * LOITER_SPEED_FACTOR;
var min = 9999, min_i;
for (var i = 0; i < this._loiter_coordinates.length; i++){
var d = distance([drone_pos.x, drone_pos.y], [this._loiter_coordinates[i].x, this._loiter_coordinates[i].y]);
if (d < min) {
min = d;
min_i = i;
}
}
this._loiter_coordinates = this._loiter_coordinates.concat(this._loiter_coordinates.splice(0,min_i));
this.shifted = true;
}
} else {
this.shifted = false;
}
//stop
if (this._last_loiter_point_reached === this._loiter_coordinates.length - 1) {
if (drone._maxSpeed !== this.getMaxSpeed()) {
drone._maxSpeed = this.getMaxSpeed();
}
drone.setDirection(0, 0, 0);
return;
}
//loiter
var next_point = this._loiter_coordinates[this._last_loiter_point_reached + 1];
drone.setTargetCoordinates(next_point.x, next_point.y, next_point.z, -1);
if (distance([drone_pos.x, drone_pos.y], [next_point.x, next_point.y]) < 1) {
this._last_loiter_point_reached += 1;
if (this._last_loiter_point_reached === this._loiter_coordinates.length - 1) {
return;
}
next_point = this._loiter_coordinates[this._last_loiter_point_reached + 1];
drone.setTargetCoordinates(next_point.x, next_point.y, next_point.z, -1);
}
}
};
DroneAaileFixeAPI.prototype.getDroneAI = function () {
return null;
};
DroneAaileFixeAPI.prototype.setAltitude = function (altitude, drone, skip_loiter) {
this.takeoff_path = [];
if (skip_loiter) {
var drone_pos = drone.getCurrentPosition();
drone.setTargetCoordinates(drone_pos.x, drone_pos.y, altitude);
return;
}
var x1, y1,
LOOPS = 1,
CIRCLE_ANGLE = 8,
current_point = 0,
total_points = 360/CIRCLE_ANGLE*LOOPS,
initial_altitude = drone.getAltitudeAbs(),
center = {
x: drone._controlMesh.position.x,
y: drone._controlMesh.position.z,
z: drone._controlMesh.position.y
};
for (var l = 0; l <= LOOPS; l+=1){
for (var angle = 360; angle > 0; angle-=CIRCLE_ANGLE){ //clockwise sense
current_point++;
x1 = TAKEOFF_RADIUS * Math.cos(angle * (Math.PI / 180)) + center.x;
y1 = TAKEOFF_RADIUS * Math.sin(angle * (Math.PI / 180)) + center.y;
if (current_point < total_points/3) {
var FACTOR = 0.5;
x1 = center.x*FACTOR + x1*(1-FACTOR);
y1 = center.y*FACTOR + y1*(1-FACTOR);
}
this.takeoff_path.push({x: x1, y: y1, z: initial_altitude + current_point * (altitude-initial_altitude)/total_points});
}
}
};
DroneAaileFixeAPI.prototype.reachAltitude = function (drone) {
function distance(p1, p2) {
return Math.sqrt(Math.pow(p1[0] - p2[0], 2) +
Math.pow(p1[1] - p2[1], 2));
}
//stop
if (this._last_altitude_point_reached === this.takeoff_path.length - 1) {
this._last_altitude_point_reached = -1;
this.takeoff_path = [];
drone._start_altitude = 0;
drone.setDirection(0, 0, 0);
return;
}
//loiter
var drone_pos = {
x: drone._controlMesh.position.x,
y: drone._controlMesh.position.z,
z: drone._controlMesh.position.y
};
var next_point = this.takeoff_path[this._last_altitude_point_reached + 1];
drone.internal_setTargetCoordinates(next_point.x, next_point.y, next_point.z);
if (distance([drone_pos.x, drone_pos.y], [next_point.x, next_point.y]) < 1) {
this._last_altitude_point_reached += 1;
if (this._last_altitude_point_reached === this.takeoff_path.length - 1) {
return;
}
next_point = this.takeoff_path[this._last_altitude_point_reached + 1];
drone.internal_setTargetCoordinates(next_point.x, next_point.y, next_point.z);
}
};
DroneAaileFixeAPI.prototype.getMaxSpeed = function () {
return GAMEPARAMETERS.drone.maxSpeed;
};
DroneAaileFixeAPI.prototype.doParachute = function (drone) {
//TODO what to do here?
drone.setDirection(0, 0, 0);
};
DroneAaileFixeAPI.prototype.landed = function (drone) {
var drone_pos = drone.getCurrentPosition();
return Math.floor(drone_pos.z) === 0;
};
DroneAaileFixeAPI.prototype.exit = function (drone) {
//TODO what to do here?
drone.setDirection(0, 0, 0);
};
DroneAaileFixeAPI.prototype.getInitialAltitude = function () {
return 0;
};
DroneAaileFixeAPI.prototype.getAltitudeAbs = function (altitude) {
return altitude;
};
DroneAaileFixeAPI.prototype.getMinHeight = function () {
return 0;
};
DroneAaileFixeAPI.prototype.getMaxHeight = function () {
return 800;
};
DroneAaileFixeAPI.prototype.getFlightParameters = function () {
return this._flight_parameters;
};
return DroneAaileFixeAPI;
}());
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>DroneAaileFixeAPI.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>drone_web_worker_aaile_fixe_api_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Drone Aaile Fixe API JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662556209.39</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1003.4484.47794.56558</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1663611202.23</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>empty</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662555990.53</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
This source diff could not be displayed because it is too large. You can view the blob instead.
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>babylon.gui.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>drone_web_worker_babylon_gui_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Babylon Gui JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662735315.78</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1002.61149.33084.18500</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1663092330.73</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>detect_converted_file</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>converted</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662735269.07</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/// <reference path="./GameManager.ts" />
var DroneAPI = /** @class */ (function () {
//*************************************************** CONSTRUCTOR **************************************************
function DroneAPI(gameManager, team) {
this._gameManager = gameManager;
this._team = team;
}
Object.defineProperty(DroneAPI.prototype, "team", {
//*************************************************** ACCESSOR *****************************************************
get: function () {
if (this._team == "L")
return this._gameManager.teamLeft;
else if (this._team == "R")
return this._gameManager.teamRight;
},
enumerable: true,
configurable: true
});
//*************************************************** FUNCTIONS ****************************************************
//#region ------------------ Internal
DroneAPI.prototype.internal_sendMsg = function (msg, to) {
var _this = this;
_this._gameManager.delay(function () {
if (to < 0) {
// Send to all drones
_this.team.forEach(function (drone) {
if (drone.infosMesh) {
try {
drone.onGetMsg(msg);
}
catch (error) {
console.warn('Drone crashed on sendMsg due to error:', error);
drone._internal_crash();
}
}
});
}
else {
// Send to specific drone
if (drone.infosMesh) {
try {
_this.team[to].onGetMsg(msg);
}
catch (error) {
console.warn('Drone crashed on sendMsg due to error:', error);
_this.team[to]._internal_crash();
}
}
}
}, GAMEPARAMETERS.latency.communication);
};
//#endregion
//#region ------------------ Accessible from AI
DroneAPI.prototype.log = function (msg) {
console.log("API say : " + msg);
};
DroneAPI.prototype.getGameParameter = function (name) {
if (["gameTime", "mapSize", "teamSize", "derive", "meteo", "initialHumanAreaPosition"].includes(name))
return this._gameManager.gameParameter[name];
};
DroneAPI.prototype._isWithinDroneView = function (drone_position, element_position) {
// Check if element is under the drone cone-view
var angle = GAMEPARAMETERS.drone.viewAngle ? GAMEPARAMETERS.drone.viewAngle : 60,
radius = drone_position.z * Math.tan(angle/2 * Math.PI/180),
distance = (drone_position.x - element_position.x) * (drone_position.x - element_position.x) +
(drone_position.y - element_position.y) * (drone_position.y - element_position.y);
if (distance < (radius*radius))
return true;
return false;
};
DroneAPI.prototype._getProbabilityOfDetection = function (drone_position) {
var h = drone_position.z,
km = GAMEPARAMETERS.meteo;
prob = 20 * (1 + (110-h)/25) * km;
return prob;
};
DroneAPI.prototype.isHumanPositionSpottedCalculation = function (drone) {
var context = this,
result = false,
drone_position = drone.infosMesh.position;
//swap axes back
drone_position = {
x: drone_position.x,
y: drone_position.z,
z: drone_position.y
};
context._gameManager.teamRight.forEach(function (human) {
if (human.infosMesh && context._isWithinDroneView(drone_position, human.position)) {
var prob = context._getProbabilityOfDetection(drone_position),
random = Math.floor(Math.random()*101);
if (random < prob)
result = true;
}
});
return result;
};
DroneAPI.prototype.isHumanPositionSpotted = function (drone) {
var context = this,
human_detected;
if (drone.__is_calculating_human_position !== true) {
drone.__is_calculating_human_position = true;
//human detection is done with the info captured by the drone
//at the moment this method is called
human_detected = context.isHumanPositionSpottedCalculation(drone);
context._gameManager.delay(function () {
drone.__is_calculating_human_position = false;
try {
drone.onCapture(human_detected);
} catch (error) {
console.warn('Drone crashed on capture due to error:', error);
drone._internal_crash();
}
}, 2000);
}
};
DroneAPI.prototype.getDirectionFromCoordinates = function (x, y, z, drone_position) {
if(isNaN(x) || isNaN(y) || isNaN(z)){
throw new Error('Target coordinates must be numbers');
}
x -= drone_position.x;
y -= drone_position.y;
z -= drone_position.z;
if (this._team == "R")
y = -y;
return {
x: x,
y: y,
z: z
};
};
DroneAPI.prototype.setAltitude = function (altitude) {
//TODO
return;
};
DroneAPI.prototype.getInitialAltitude = function () {
return 0;
};
DroneAPI.prototype.getAltitudeAbs = function () {
return 0;
};
DroneAPI.prototype.getMinHeight = function () {
return 9;
};
DroneAPI.prototype.getMaxHeight = function () {
return 220;
};
DroneAPI.prototype.getDroneAI = function () {
return null;
};
DroneAPI.prototype.getMaxSpeed = function () {
return GAMEPARAMETERS.drone.maxSpeed;
};
return DroneAPI;
}());
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>DroneAPI.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>drone_web_worker_drone_api_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Drone API JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662556207.86</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1002.52438.8605.21913</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662556286.54</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>empty</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662555993.71</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/// <reference path="./typings/babylon.3.1.d.ts" />
/// <reference path="./DroneAPI.ts" />
/// <reference path="./DroneLogAPI.ts" />
/// <reference path="./DroneAaileFixeAPI.ts" />
var DroneManager = /** @class */ (function () {
//*************************************************** CONSTRUCTOR **************************************************
function DroneManager(scene, id, team, API) {
var _this = this;
// Mesh
this._mesh = null;
this._controlMesh = null;
this._colliderBackMesh = null;
this._canPlay = false;
this._canCommunicate = false;
this._maxAcceleration = 0;
this._maxSpeed = 0;
this._speed = 0;
this._acceleration = 0;
this._direction = BABYLON.Vector3.Zero();
this._rotationSpeed = 0.4;
this._maxOrientation = Math.PI / 4;
this._scene = scene;
this._canUpdate = true;
this._id = id;
this._leader_id = 0;
this._team = team;
this._start_loiter = 0;
this._start_altitude = 0;
this._API = API; // var API created on AI evel
// Create the control mesh
this._controlMesh = BABYLON.Mesh.CreateBox("droneControl_" + id, 0.01, this._scene);
this._controlMesh.isVisible = false;
if (this._team == "R")
this._controlMesh.rotation = new BABYLON.Vector3(0, Math.PI, 0);
this._controlMesh.computeWorldMatrix(true);
// Create the mesh from the drone prefab
this._mesh = DroneManager.Prefab.clone("drone_" + id, this._controlMesh);
this._mesh.position = BABYLON.Vector3.Zero();
this._mesh.isVisible = false;
this._mesh.computeWorldMatrix(true);
// Get the back collider
this._mesh.getChildMeshes().forEach(function (mesh) {
if (mesh.name.substring(mesh.name.length - 13) == "Dummy_arriere") {
_this._colliderBackMesh = mesh;
_this._colliderBackMesh.isVisible = false;
}
else {
if (_this._team !== "R") {
mesh.isVisible = true;
} else {
mesh.isVisible = false;
_this._colliderBackMesh = mesh;
_this._colliderBackMesh.isVisible = false;
}
}
});
// Team color
if (!DroneManager.PrefabBlueMat || !DroneManager.PrefabRedMat) {
DroneManager.PrefabBlueMat = new BABYLON.StandardMaterial("blueTeamMat", scene);
DroneManager.PrefabBlueMat.diffuseTexture = new BABYLON.Texture("assets/drone/drone_bleu.jpg", scene);
DroneManager.PrefabRedMat = new BABYLON.StandardMaterial("redTeamMat", scene);
DroneManager.PrefabRedMat.diffuseTexture = new BABYLON.Texture("assets/drone/drone_rouge.jpg", scene);
}
this._propellerAnimMeshes = [];
this._mesh.getChildren().forEach(function (mesh) {
// Propeller animation
if (mesh.name.substring(mesh.name.length - 7, mesh.name.length - 1) == "helice") {
var anim = new BABYLON.Animation("propellerTurning_" + mesh.name, "rotation.y", 20, BABYLON.Animation.ANIMATIONTYPE_FLOAT, BABYLON.Animation.ANIMATIONLOOPMODE_CYCLE);
var keys = [
{ frame: 0, value: 0 },
{ frame: 2, value: Math.PI },
{ frame: 4, value: Math.PI * 2 }
];
anim.setKeys(keys);
mesh.animations.push(anim);
_this._scene.beginAnimation(mesh, 0, 4, true);
_this._propellerAnimMeshes.push(mesh);
}
else {
if (_this._team == "L") {
mesh.material = DroneManager.PrefabBlueMat;
}
else if (_this._team == "R") {
mesh.material = DroneManager.PrefabRedMat;
}
}
});
}
DroneManager.prototype._swapAxe = function (vector) {
return new BABYLON.Vector3(vector.x, vector.z, vector.y);
};
Object.defineProperty(DroneManager.prototype, "leader_id", {
//*************************************************** ACCESSOR *****************************************************
get: function () { return this._leader_id; },
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "id", {
//*************************************************** ACCESSOR *****************************************************
get: function () { return this._id; },
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "team", {
get: function () { return this._team; },
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "colliderMesh", {
get: function () { return this._mesh; },
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "colliderBackMesh", {
get: function () { return this._colliderBackMesh; },
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "infosMesh", {
get: function () { return this._controlMesh; },
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "position", {
get: function () {
if (this._controlMesh !== null) {
return this._swapAxe(this._controlMesh.position);
}
return null;
},
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "rotation", {
get: function () { return this._swapAxe(this._controlMesh.rotation); },
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "speed", {
get: function () { return this._speed; },
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "direction", {
get: function () { return this._swapAxe(this._direction); },
enumerable: true,
configurable: true
});
Object.defineProperty(DroneManager.prototype, "worldDirection", {
get: function () {
var t = this.team === "L" ? 1 : -1;
return new BABYLON.Vector3(t * this._direction.x, this._direction.y, t * this._direction.z);
},
enumerable: true,
configurable: true
});
//*************************************************** FUNCTIONS ****************************************************
//#region ------------------ Internal
// Function called by the GameManager
// Set internal variables then call API function
DroneManager.prototype.internal_start = function () {
this._maxAcceleration = GAMEPARAMETERS.drone.maxAcceleration;
if (this._team == "R") {
if (GAMEPARAMETERS.derive) {
this._maxSpeed = GAMEPARAMETERS.derive.speed;
} else {
this._maxSpeed = 0;
}
} else {
this._maxSpeed = this._API.getMaxSpeed();
}
this._canPlay = true;
this._canCommunicate = true;
try {
return this.onStart();
} catch (error) {
console.warn('Drone crashed on start due to error:', error);
this._internal_crash();
}
};
/**
* Set a target point to move
*/
DroneManager.prototype.internal_setTargetCoordinates = function (x, y, z) {
if (!this._canPlay)
return;
x -= this._controlMesh.position.x;
y -= this._controlMesh.position.z;
z -= this._controlMesh.position.y;
this.setDirection(x, y, z);
this.setAcceleration(this._maxAcceleration);
return;
};
DroneManager.prototype.internal_update = function (delta_time) {
var context = this;
if (this._controlMesh) {
if (context._rotationTarget) {
var rotStep = BABYLON.Vector3.Zero();
var diff = context._rotationTarget.subtract(context._controlMesh.rotation);
if (diff.x >= 1)
rotStep.x = 1;
else
rotStep.x = diff.x;
if (diff.y >= 1)
rotStep.y = 1;
else
rotStep.y = diff.y;
if (diff.z >= 1)
rotStep.z = 1;
else
rotStep.z = diff.z;
if (rotStep == BABYLON.Vector3.Zero()) {
context._rotationTarget = null;
return;
}
var newrot = new BABYLON.Vector3(context._controlMesh.rotation.x + (rotStep.x * context._rotationSpeed), context._controlMesh.rotation.y + (rotStep.y * context._rotationSpeed), context._controlMesh.rotation.z + (rotStep.z * context._rotationSpeed));
context._controlMesh.rotation = newrot;
}
context._speed += context._acceleration * delta_time / 1000;
if (context._speed > context._maxSpeed)
context._speed = context._maxSpeed;
if (context._speed < -context._maxSpeed)
context._speed = -context._maxSpeed;
var updateSpeed = context._speed * delta_time / 1000;
if (context._direction.x != 0
|| context._direction.y != 0
|| context._direction.z != 0) {
context._controlMesh.position.addInPlace(new BABYLON.Vector3(context._direction.x * updateSpeed, context._direction.y * updateSpeed, context._direction.z * updateSpeed));
}
var orientationValue = context._maxOrientation * (context._speed / context._maxSpeed);
context._mesh.rotation = new BABYLON.Vector3(orientationValue * context._direction.z, 0, -orientationValue * context._direction.x);
context._controlMesh.computeWorldMatrix(true);
context._mesh.computeWorldMatrix(true);
if (context._canUpdate) {
context._canUpdate = false;
return new RSVP.Queue()
.push(function () {
return context.onUpdate(context._API._gameManager._game_duration);
})
.push(function () {
context._canUpdate = true;
}, function (err) {
console.warn('Drone crashed on update due to error:', err);
context._internal_crash();
})
.push(function () {
if (context._start_loiter > 0) {
context._API.loiter(context);
}
if (context._start_altitude > 0) {
context._API.reachAltitude(context);
}
});
}
return;
}
return;
};
DroneManager.prototype.internal_touch = function () {
var _this = this;
this.setRotationBy(0, 0, 0);
this.setDirection(0, 0, -1);
this.setAcceleration(this._maxAcceleration);
this._canPlay = false;
if (this._propellerAnimMeshes != null) {
try {
this._propellerAnimMeshes.forEach(function (mesh) {
_this._scene.stopAnimation(mesh);
});
}
catch (ex) { }
this._propellerAnimMeshes = null;
}
this._canCommunicate = false;
this._controlMesh = null;
this._mesh = null;
this.onTouched();
};
DroneManager.prototype._internal_crash = function () {
var _this = this;
if (this._propellerAnimMeshes !== null) {
try {
this._propellerAnimMeshes.forEach(function (mesh) {
_this._scene.stopAnimation(mesh);
});
}
catch (ex) { }
this._propellerAnimMeshes = null;
}
this._canCommunicate = false;
this._controlMesh = null;
this._mesh = null;
this._canPlay = false;
this.onTouched();
this._API._gameManager._onDroneInternalCrash(this);
};
DroneManager.prototype._internal_dispose = function () {
if (this._mesh) {
this._mesh.dispose();
this._mesh = null;
this._controlMesh.dispose();
this._controlMesh = null;
}
};
DroneManager.prototype.internal_finish = function () {
this._canPlay = false;
this._canCommunicate = false;
this._controlMesh = null;
};
DroneManager.prototype.can_play = function () {
return this._canPlay;
};
//#endregion
//#region ------------------ Accessible from AI
// Function callable by "me.functionName()" in AI code
// -- Starting info
/**
* Set the starting position of the drone
* Take x,y,z coordinates as parameters
*/
DroneManager.prototype.setStartingPosition = function (x, y, z) {
if(isNaN(x) || isNaN(y) || isNaN(z)){
throw new Error('Position coordinates must be numbers');
}
if (!this._canPlay) {
if (z <= 0.05)
z = 0.05;
this._controlMesh.position = new BABYLON.Vector3(x, z, y);
}
this._controlMesh.computeWorldMatrix(true);
this._mesh.computeWorldMatrix(true);
};
//#region -- Movements
/**
* Set the drone acceleration
* It is in meter / second
*/
DroneManager.prototype.setAcceleration = function (factor) {
if (!this._canPlay)
return;
if (isNaN(factor)){
throw new Error('Acceleration must be a number');
}
if (factor > this._maxAcceleration)
factor = this._maxAcceleration;
this._acceleration = factor;
};
//#region -- Movements
/**
* Set the human derive acceleration
* It is in meter / second
* It has no cap to allow constant speed
*/
DroneManager.prototype.setHumanAcceleration = function (factor) {
if (!this._canPlay)
return;
if (isNaN(factor)){
throw new Error('Acceleration must be a number');
}
this._acceleration = factor;
};
/**
* Set the drone direction
*/
DroneManager.prototype.setDirection = function (x, y, z) {
if (!this._canPlay)
return;
if(isNaN(x) || isNaN(y) || isNaN(z)){
throw new Error('Direction coordinates must be numbers');
}
this._direction = new BABYLON.Vector3(x, z, y).normalize();
};
/**
* Set the drone rotation
*/
DroneManager.prototype.setRotation = function (x, y, z) {
if (!this._canPlay)
return;
if (this._team == "R")
y += Math.PI;
this._rotationTarget = new BABYLON.Vector3(x, z, y);
};
/**
* Add this rotation to the actual drone rotation
*/
DroneManager.prototype.setRotationBy = function (x, y, z) {
if (!this._canPlay)
return;
this._rotationTarget = new BABYLON.Vector3(this.rotation.x + x, this.rotation.y + z, this.rotation.z + y);
};
/**
* Set a target point to move
*/
DroneManager.prototype.setTargetCoordinates = function (x, y, z, r) {
if (!this._canPlay)
return;
//HACK too specific for DroneAaileFixe, should be a flag: (bool)process?
if (r !== -1) {
this._start_loiter = 0;
this._maxSpeed = this._API.getMaxSpeed();
}
this._start_altitude = 0;
var coordinates = this._API.processCoordinates(x, y, z, r);
coordinates.x -= this._controlMesh.position.x;
coordinates.y -= this._controlMesh.position.z;
coordinates.z -= this._controlMesh.position.y;
if (this.team == "R")
coordinates.y = -coordinates.y;
this.setDirection(coordinates.x, coordinates.y, coordinates.z);
this.setAcceleration(this._maxAcceleration);
return;
};
//#endregion
//#region -- Messaging
/**
* Send a message to team drones
* @param msg The message to send
* @param id The targeted drone. -1 or nothing to broadcast
*/
DroneManager.prototype.sendMsg = function (msg, id) {
//TODO
return;
var _this = this;
if (!this._canCommunicate)
return;
if (id >= 0) { }
else
id = -1;
if (_this.infosMesh) {
return _this._API.internal_sendMsg(JSON.parse(JSON.stringify(msg)), id);
}
};
/**
* Perform a console.log with drone id + the message
*/
DroneManager.prototype.log = function (msg) { };
//#endregion
//#region -- Game informations
/**
* Get drone max height
*/
DroneManager.prototype.getMaxHeight = function () {
return this._API.getMaxHeight();
};
/**
* Get drone min height
*/
DroneManager.prototype.getMinHeight = function () {
return this._API.getMinHeight();
};
/**
* Get drone initial altitude
*/
DroneManager.prototype.getInitialAltitude = function () {
return this._API.getInitialAltitude();
};
/**
* Get drone absolute altitude
*/
DroneManager.prototype.getAltitudeAbs = function () {
if (this._controlMesh) {
var altitude = this._controlMesh.position.y;
return this._API.getAltitudeAbs(altitude);
}
return null;
};
/**
* Get a game parameter by name
* @param name Name of the parameter to retrieve
*/
DroneManager.prototype.getGameParameter = function (name) {
if (!this._canCommunicate)
return;
return this._API.getGameParameter(name);
};
/**
* get if drone detects the human position
*/
DroneManager.prototype.isHumanPositionSpotted = function () {
if (!this._canCommunicate)
return;
return this._API.isHumanPositionSpotted(this);
};
/**
* get current drone position
*/
DroneManager.prototype.getCurrentPosition = function () {
if (this._controlMesh)
return this._API.processCurrentPosition(
this._controlMesh.position.x,
this._controlMesh.position.z,
this._controlMesh.position.y
);
return null;
};
/**
* Set the drone altitude
* @param altitude information to be set
*/
DroneManager.prototype.setAltitude = function (altitude, skip_loiter) {
if (!this._canPlay)
return;
if (this._start_altitude === 0) {
this._start_altitude = 1;
}
altitude = this._API.setAltitude(altitude, this, skip_loiter);
return;
};
/**
* Make the drone loiter
*/
DroneManager.prototype.loiter = function () {
if (!this._canPlay)
return;
if (this._start_loiter === 0) {
this._start_loiter = 1;
}
};
/**
* Set the reported human position
* @param position information to be set
*/
DroneManager.prototype.reportHumanPosition = function (position) {
this._API._gameManager.reportHumanPosition(position);
};
/**
* get log flight parameters
*/
DroneManager.prototype.getFlightParameters = function () {
if (this._API.getFlightParameters)
return this._API.getFlightParameters();
return null;
};
/**
* get yaw flight parameters
*/
DroneManager.prototype.getYaw = function () {
//TODO
return 0;
};
/**
* do parachute
*/
DroneManager.prototype.doParachute = function () {
return this._API.doParachute(this);
};
/**
* exit
*/
DroneManager.prototype.exit = function () {
return this._API.exit(this);
};
/**
* landed
*/
DroneManager.prototype.landed = function () {
return this._API.landed(this);
};
/**
* Set the drone last checkpoint reached
* @param checkpoint to be set
*/
DroneManager.prototype.setCheckpoint = function (checkpoint) {
//TODO
return null;
};
//#endregion
//#endregion
//#region ------------------ To be defined in AI code
// Function called on evt.
// These functions must be defined in the AI code
/**
* Function called on game start
*/
DroneManager.prototype.onStart = function () { };
;
/**
* Function called on game update
*/
DroneManager.prototype.onUpdate = function (timestamp) { };
;
/**
* Function called when drone die (crash or collision)
*/
DroneManager.prototype.onTouched = function () { };
;
/**
* Function called when a message is received
* @param msg The message
*/
DroneManager.prototype.onGetMsg = function (msg) { };
;
/**
* Function called when drone finishes the detection process
* @param human_detected true or false
*/
DroneManager.prototype.onCapture = function (human_detected) { };
;
return DroneManager;
}());
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>DroneManager.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>drone_web_worker_drone_manager_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Drone Manager JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662556210.06</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1003.4485.30969.53230</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1663614606.63</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>empty</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662555985.78</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
var GAMEPARAMETERS = {};
function randomSpherePoint(x0, y0, z0, rx0, ry0, rz0) {
var u = Math.random(), v = Math.random(),
rx = Math.random() * rx0, ry = Math.random() * ry0,
rz = Math.random() * rz0, theta = 2 * Math.PI * u,
phi = Math.acos(2 * v - 1),
x = x0 + (rx * Math.sin(phi) * Math.cos(theta)),
y = y0 + (ry * Math.sin(phi) * Math.sin(theta)),
z = z0 + (rz * Math.cos(phi));
return new BABYLON.Vector3(x, y, z);
}
var GameManager = /** @class */ (function () {
// *** CONSTRUCTOR ***
function GameManager(canvas, script, game_parameters_json, simulation_speed) {
var _this = this;
this._canvas = canvas;
this._scene = null;
this._ground_truth_target = null;
this._engine = null;
this._teamLeft = [];
this._teamRight = [];
this._canUpdate = false;
if (!simulation_speed) { simulation_speed = 5; }
this._max_step_animation_frame = simulation_speed;
Object.assign(GAMEPARAMETERS, game_parameters_json);
this._game_parameters_json = game_parameters_json;
this._map_swapped = false;
this._script = script;
this._last_position_drawn = [];
this._log_count = [];
this._flight_log = [];
if (GAMEPARAMETERS.compareFlights) {
for (var count = 0; count < GAMEPARAMETERS.teamSize; count++) {
this._flight_log[count] = [];
this._log_count[count] = 0;
this._last_position_drawn[count] = null;
}
this._colors = [
new BABYLON.Color3(255, 165, 0),
new BABYLON.Color3(0, 0, 255),
new BABYLON.Color3(255, 0, 0),
new BABYLON.Color3(0, 255, 0)
];
}
this.APIs_dict = {
DroneAaileFixeAPI: DroneAaileFixeAPI,
DroneLogAPI: DroneLogAPI,
DroneAPI: DroneAPI
};
}
Object.defineProperty(GameManager.prototype, "gameParameter", {
get: function () {
return this._gameParameter;
},
enumerable: true,
configurable: true
});
GameManager.prototype.run = function () {
var gadget = this;
return gadget._init();
};
GameManager.prototype.event = function (event) {
var _this = this;
//TODO
console.log("[GM] Event. this._camera:", this._camera);
console.log("[GM] Event. event:", event);
};
GameManager.prototype.update = function () {
var _this = this;
// To increase the game speed, increase this value
_this._max_step_animation_frame = 10;
// time delta means that drone are updated every virtual second
// This is fixed and must not be modified
// otherwise, it will lead to different scenario results
// (as drone calculations may be triggered less often)
var TIME_DELTA = 1000 / 60, i;
// init the value on the first step
_this.waiting_update_count = _this._max_step_animation_frame;
function triggerUpdateIfPossible() {
if ((_this._canUpdate) && (_this.ongoing_update_promise === null) && (0 < _this.waiting_update_count)) {
_this.ongoing_update_promise = _this._update(TIME_DELTA, (_this.waiting_update_count === 1))
.push(function () {
_this.waiting_update_count -= 1;
_this.ongoing_update_promise = null;
triggerUpdateIfPossible();
})
.push(undefined, _this.finish_deferred.reject.bind(_this.finish_deferred));
}
}
triggerUpdateIfPossible();
};
GameManager.prototype.delay = function (callback, millisecond) {
this._delayed_defer_list.push([callback, millisecond]);
};
GameManager.prototype._updateDisplayedInfo = function (delta_time, update_dom) {
this._game_duration += delta_time;
var seconds = Math.floor(this._game_duration / 1000);
//TODO Timing display?
/*if (update_dom) {
this._timeDisplay.textContent = this._formatTimeToMinutesAndSeconds(this._game_duration);
}*/
if (GAMEPARAMETERS.compareFlights) {
for (var count = 0; count < GAMEPARAMETERS.teamSize; count++) {
if (this._teamLeft[count]._controlMesh) {
var drone_position_x = this._teamLeft[count]._controlMesh.position.x,
drone_position_z = this._teamLeft[count]._controlMesh.position.y,
drone_position_y = this._teamLeft[count]._controlMesh.position.z;
if (GAMEPARAMETERS.compareFlights.log) {
if (this._log_count[count] === 0 || this._game_duration / this._log_count[count] > 1) {
this._log_count[count] += GAMEPARAMETERS.compareFlights.log_interval_time;
//convert x-y coordinates into latitud-longitude
var lon = drone_position_x + GAMEPARAMETERS.compareFlights.map_width / 2;
lon = lon / 1000;
lon = lon * (GAMEPARAMETERS.compareFlights.MAX_X - GAMEPARAMETERS.compareFlights.MIN_X) + GAMEPARAMETERS.compareFlights.MIN_X;
lon = lon / (GAMEPARAMETERS.compareFlights.map_width / 360.0) - 180;
var lat = drone_position_y + GAMEPARAMETERS.compareFlights.map_height / 2;
lat = lat / 1000;
lat = lat * (GAMEPARAMETERS.compareFlights.MAX_Y - GAMEPARAMETERS.compareFlights.MIN_Y) + GAMEPARAMETERS.compareFlights.MIN_Y;
lat = 90 - lat / (GAMEPARAMETERS.compareFlights.map_height / 180.0);
this._flight_log[count].push([lat, lon, drone_position_z]);
}
}
if (GAMEPARAMETERS.compareFlights.draw) {
//draw drone position every second
if (this._last_position_drawn[count] !== seconds) {
this._last_position_drawn[count] = seconds;
var position_obj = BABYLON.MeshBuilder.CreateSphere("obs_" + seconds, {
'diameterX': 3.5,
'diameterY': 3.5,
'diameterZ': 3.5
}, this._scene);
position_obj.position = new BABYLON.Vector3(drone_position_x, drone_position_z, drone_position_y);
position_obj.scaling = new BABYLON.Vector3(3.5, 3.5, 3.5);
var material = new BABYLON.StandardMaterial(this._scene);
material.alpha = 1;
var color = new BABYLON.Color3(255, 0, 0);
if (this._colors[count]) {
color = this._colors[count];
}
material.diffuseColor = color;
position_obj.material = material;
}
}
}
}
}
};
GameManager.prototype._update = function (delta_time, update_dom) {
var _this = this,
queue = new RSVP.Queue(),
i;
this._updateDisplayedInfo(delta_time, update_dom);
// trigger all deferred calls if it is time
for (i = _this._delayed_defer_list.length - 1; 0 <= i; i -= 1) {
_this._delayed_defer_list[i][1] = _this._delayed_defer_list[i][1] - delta_time;
if (_this._delayed_defer_list[i][1] <= 0) {
queue.push(_this._delayed_defer_list[i][0]);
_this._delayed_defer_list.splice(i, 1);
}
}
function updateDrone(drone) {
var msg = '';
drone._tick += 1;
if (drone.can_play()) {
//TODO check collisions
}
return drone.internal_update(delta_time);
}
function updateHuman(human) {
var result = human.internal_update(delta_time);
_this._ground_truth_target = {
x: human.position.x,
y: human.position.y,
z: human.position.z
};
return result;
}
// Check collisions -- Drone swarm
this._teamLeft.forEach(function (drone) {
queue.push(function () {
return updateDrone(drone);
});
});
// Update position -- Human
this._teamRight.forEach(function (human) {
queue.push(function () {
return updateHuman(human);
});
});
return queue
//TODO finish
/*.push(function () {
if (_this._allDroneAreOut()) {
return _this._finish();
}
})*/;
};
GameManager.prototype._dispose = function () {
if (this._scene) {
this._scene.dispose();
}
};
GameManager.prototype._init = function () {
var _this = this,
center = GAMEPARAMETERS.randomSpawn.rightTeam.position,
dispertion = GAMEPARAMETERS.randomSpawn.rightTeam.dispertion;
if (GAMEPARAMETERS.randomSpawn.rightTeam.dispersed)
dispertion = {x: 0, y: 0, z: 0};
this._ground_truth_target =
randomSpherePoint(center.x, center.y, center.z,
dispertion.x, dispertion.y, dispertion.z);
this._delayed_defer_list = [];
this._dispose();
var canvas = this._canvas;
// Create the Babylon engine
this._engine = new BABYLON.Engine(canvas, true, {
stencil: true,
disableWebGL2Support: false,
audioEngine: false
});
this._engine.enableOfflineSupport = false;
this._scene = new BABYLON.Scene(this._engine);
this._scene.clearColor = new BABYLON.Color4(88/255,171/255,217/255,255/255);
this._scene.collisionsEnabled = true;
// Lights
var hemi_north = new BABYLON.HemisphericLight(
"hemiN", new BABYLON.Vector3(1, -1, 1), this._scene);
hemi_north.intensity = 0.75;
var hemi_south = new BABYLON.HemisphericLight(
"hemiS", new BABYLON.Vector3(-1, 1, -1), this._scene);
hemi_south.intensity = 0.75;
var radius = (GAMEPARAMETERS.mapSize.width/3 < 75) ?
75 : GAMEPARAMETERS.mapSize.width/3,
vector_x = (this._ground_truth_target.x > -50 &&
this._ground_truth_target.x < 50) ?
0 : this._ground_truth_target.x,
vector_y = (this._ground_truth_target.y > -50 &&
this._ground_truth_target.y < 50) ?
0 : this._ground_truth_target.y,
camera, x_rotation;
if (this._ground_truth_target.x > 0 && this._ground_truth_target.y > 0) {
x_rotation = 1;
} else if (this._ground_truth_target.x > 0 &&
this._ground_truth_target.y < 0) {
x_rotation = 200;
} else if (this._ground_truth_target.x < 0 &&
this._ground_truth_target.y < 0) {
x_rotation = 400;
} else {
x_rotation = 750;
}
//cap camera distance to 1km
if (radius > 800) radius = 800;
var target = new BABYLON.Vector3(vector_x, 0, vector_y);
if (GAMEPARAMETERS.compareFlights) {
target = BABYLON.Vector3.Zero();
}
camera = new BABYLON.ArcRotateCamera("camera", x_rotation, 1.25, radius,
target, this._scene);
camera.wheelPrecision = 10;
camera.attachControl(this._scene.getEngine().getRenderingCanvas());
camera.maxz = 40000;
this._camera = camera;
// Render loop
this._engine.runRenderLoop(function () {
_this._scene.render();
});
// -------------------------------- SIMULATION - Prepare API, Map and Teams
var on3DmodelsReady = function (ctx) {
console.log("on3DmodelsReady!");
// Get the game parameters
if (!ctx._map_swapped) {
GAMEPARAMETERS = ctx._getGameParameter();
ctx._map_swapped = true;
}
// Create the API
var lAPI = new DroneAPI(ctx, "L");
var rAPI = new DroneAPI(ctx, "R");
console.log("APIs created");
// Set the AI code into drones
var AIcodeEval, AIcodeRight, AIcodeLeft;
AIcodeLeft = ctx._script;
//set AI for the target (derive or do nothing)
if (GAMEPARAMETERS.derive) {
AIcodeRight = `me.onStart = function() { me.setHumanAcceleration(99999); me.setDirection(${GAMEPARAMETERS.derive.direction.x},${GAMEPARAMETERS.derive.direction.y},0); }`;
} else {
AIcodeRight = "me.onStart = function() { me.setAcceleration(0); me.setDirection(0,0,0); }";
}
// Init the map
_this._mapManager = new MapManager(ctx._scene);
console.log("Map manager instantiated");
if (GAMEPARAMETERS.randomSpawn) {
ctx._setRandomSpawnPosition(GAMEPARAMETERS.randomSpawn.leftTeam, GAMEPARAMETERS.teamSize, lAPI, AIcodeLeft, "L");
ctx._setRandomSpawnPosition(GAMEPARAMETERS.randomSpawn.rightTeam, GAMEPARAMETERS.teamSize, rAPI, AIcodeRight, "R");
}
// Hide the drone prefab
DroneManager.Prefab.isVisible = false;
//GUI for drones ID display
//Hack to make advanced texture work
const documentTmp = document;
document = undefined;
var advancedTexture = BABYLON.GUI.AdvancedDynamicTexture.CreateFullscreenUI("UI", true, ctx._scene);
document = documentTmp;
for (var count = 0; count < GAMEPARAMETERS.teamSize; count++) {
var controlMeshBlue = ctx._teamLeft[count].infosMesh;
//set only one drone for right team (the target)
if (count === 0) {
var controlMeshRed = ctx._teamRight[count].infosMesh;
var ellipse = new BABYLON.GUI.Ellipse();
ellipse.height = "10px";
ellipse.width = "15px";
ellipse.thickness = 4;
ellipse.color = "red";
ellipse.linkOffsetY = 0;
advancedTexture.addControl(ellipse);
ellipse.linkWithMesh(controlMeshRed);
}
var rectBlue = new BABYLON.GUI.Rectangle();
if (count < 100)
rectBlue.width = "10px";
else
rectBlue.width = "14px";
rectBlue.height = "10px";
rectBlue.cornerRadius = 20;
rectBlue.color = "white";
rectBlue.thickness = 0.5;
rectBlue.background = "blue";
advancedTexture.addControl(rectBlue);
var labelBlue = new BABYLON.GUI.TextBlock();
labelBlue.text = count.toString();
labelBlue.fontSize = 7;
rectBlue.addControl(labelBlue);
rectBlue.linkWithMesh(controlMeshBlue);
rectBlue.linkOffsetY = 0;
}
console.log("advaced textures added");
return ctx;
};
// ----------------------------------- SIMULATION - Load 3D models
return new RSVP.Queue()
.push(function () {
return new RSVP.Promise(function (resolve) {
return _this._load3DModel(resolve);
});
})
.push(function () {
on3DmodelsReady(_this);
// 3,2,1,GO before start. To animate.
var result = new RSVP.Queue(),
i;
function countdown (count) {
return function () {
console.log(count + " ...");
return RSVP.delay(200);
};
}
for (i = 5; 0 <= i; i -= 1) {
result.push(countdown(i));
}
return result.push(_this._start.bind(_this));
});
};
GameManager.prototype._start = function () {
var _this = this;
_this.waiting_update_count = 0;
_this.ongoing_update_promise = null;
_this.finish_deferred = RSVP.defer();
console.log("Simulation started.");
// Timing
this._game_duration = 0;
this._totalTime = GAMEPARAMETERS.gameTime;
this._canUpdate = true;
return new RSVP.Queue()
.push(function () {
promise_list = [];
_this._teamLeft.forEach(function (drone) {
drone._tick = 0;
promise_list.push(drone.internal_start());
});
_this._teamRight.forEach(function (drone) {
drone._tick = 0;
promise_list.push(drone.internal_start());
});
return RSVP.all(promise_list);
})
.push(function () {
//The loop is handle from the outside (webworker)
//_this._scene.registerBeforeRender(function () { console.log("loop"); });
/*_this._scene.registerBeforeRender(function () {
// To increase the game speed, increase this value
_this._max_step_animation_frame = 10;
// time delta means that drone are updated every virtual second
// This is fixed and must not be modified
// otherwise, it will lead to different scenario results
// (as drone calculations may be triggered less often)
var TIME_DELTA = 1000 / 60, i;
// init the value on the first step
_this.waiting_update_count = _this._max_step_animation_frame;
function triggerUpdateIfPossible() {
if ((_this._canUpdate) && (_this.ongoing_update_promise === null) && (0 < _this.waiting_update_count)) {
_this.ongoing_update_promise = _this._update(TIME_DELTA, (_this.waiting_update_count === 1))
.push(function () {
_this.waiting_update_count -= 1;
_this.ongoing_update_promise = null;
triggerUpdateIfPossible();
})
.push(undefined, _this.finish_deferred.reject.bind(_this.finish_deferred));
}
}
triggerUpdateIfPossible();
});*/
//TODO solving promise so game-start finishes and web worker can update
_this.finish_deferred.resolve();
return _this.finish_deferred.promise;
});
};
GameManager.prototype._load3DModel = function (callback) {
console.log("_load3DModel!");
var _this = this, droneTask, mapTask, obstacleTask,
assetManager = new BABYLON.AssetsManager(this._scene);
assetManager.useDefaultLoadingScreen = true;
// DRONE
droneTask = assetManager.addMeshTask("loadingDrone", "", "assets/drone/", "drone.babylon");
droneTask.onSuccess = function (task) {
task.loadedMeshes.forEach(function (mesh) {
mesh.isPickable = false;
mesh.isVisible = false;
});
DroneManager.Prefab = _this._scene.getMeshByName("Dummy_Drone");
DroneManager.Prefab.scaling = new BABYLON.Vector3(0.006, 0.006, 0.006);
DroneManager.Prefab.position = new BABYLON.Vector3(0, -5, 0);
};
droneTask.onError = function () {
console.log("Error loading 3D model for Drone");
};
// MAP
mapTask = assetManager.addMeshTask("loadingMap", "", "assets/map/", "map.babylon");
mapTask.onSuccess = function (task) {
task.loadedMeshes.forEach(function (mesh) {
mesh.isPickable = false;
mesh.isVisible = false;
});
};
mapTask.onError = function () {
console.log("Error loading 3D model for Map");
};
// OBSTACLE
obstacleTask = assetManager.addMeshTask("loadingObstacle", "", "assets/obstacle/", "boat.babylon");
obstacleTask.onSuccess = function (task) {
task.loadedMeshes.forEach(function (mesh) {
mesh.isPickable = false;
mesh.isVisible = false;
});
ObstacleManager.Prefab = _this._scene.getMeshByName("car");
};
obstacleTask.onError = function () {
console.log("Error loading 3D model for Obstacle");
};
assetManager.onFinish = function () {
return callback();
};
assetManager.load();
console.log("asset manager loaded (tasks for map, drones and obstacles)");
};
GameManager.prototype._getGameParameter = function () {
var parameter = {}, i,
swap = function (pos) {
return {
x: pos.x,
y: pos.z,
z: pos.y
};
};
Object.assign(parameter, this._game_parameters_json);
this._gameParameter = {};
Object.assign(this._gameParameter, this._game_parameters_json);
//TODO obstacle is kept as real flight log uses for path draw. Refactor this
for (i = 0; i < parameter.obstacles.length; i += 1) {
parameter.obstacles[i].position = swap(parameter.obstacles[i].position);
if (parameter.obstacles[i].scale) {
parameter.obstacles[i].scale = swap(parameter.obstacles[i].scale);
}
if (parameter.obstacles[i].rotation) {
parameter.obstacles[i].rotation = swap(parameter.obstacles[i].rotation);
}
}
return parameter;
};
GameManager.prototype._setRandomSpawnPosition = function (randomSpawn, team_size, api, code, team) {
var position, i, position_list = [], center = randomSpawn.position, max_collision = randomSpawn.maxCollision || 10 * team_size, collision_nb = 0;
function checkCollision(position, list) {
var i;
for (i = 0; i < list.length; i += 1) {
if (position.equalsWithEpsilon(list[i], 0.5)) {
return true;
}
}
return false;
}
for (i = 0; i < team_size; i += 1) {
//set only one element for right team (the human)
if (team === "L" || i === 0) {
if (GAMEPARAMETERS.randomSpawn.rightTeam.dispersed) {
position = randomSpherePoint(center.x + i, center.y + i, center.z + i, 0, 0, 0);
} else {
position = randomSpherePoint(center.x, center.y, center.z, randomSpawn.dispertion.x, randomSpawn.dispertion.y, randomSpawn.dispertion.z);
}
if (team === "R") {
this._setSpawnDrone(this._ground_truth_target.x, this._ground_truth_target.y, this._ground_truth_target.z, i, api, code, team);
} else {
if (checkCollision(position, position_list) || position.z < 0.05) {
collision_nb += 1;
if (collision_nb < max_collision) {
i -= 1;
}
}
else {
position_list.push(position);
var lAPI = api;
if (randomSpawn.types) {
if (randomSpawn.types[i] in this.APIs_dict) {
lAPI = new this.APIs_dict[randomSpawn.types[i]](this, "L", GAMEPARAMETERS.compareFlights);
}
}
this._setSpawnDrone(position.x, position.y, position.z, i, lAPI, code, team);
}
}
}
}
};
GameManager.prototype._setSpawnDrone = function (x, y, z, index, api, code, team) {
var default_drone_AI = api.getDroneAI();
if (default_drone_AI) {
code = default_drone_AI;
}
var ctx = this, base, code_eval = "let drone = new DroneManager(ctx._scene, " +
index + ', "' + team + '", api);' +
"let droneMe = function(NativeDate, me, Math, window, DroneManager, GameManager, DroneAPI, DroneLogAPI, DroneAaileFixeAPI, BABYLON, GAMEPARAMETERS) {" +
"var start_time = (new Date(2070, 0, 0, 0, 0, 0, 0)).getTime();" +
"Date.now = function () {return start_time + drone._tick * 1000/60;}; " +
"function Date() {if (!(this instanceof Date)) {throw new Error('Missing new operator');} " +
"if (arguments.length === 0) {return new NativeDate(Date.now());} else {return new NativeDate(...arguments);}}";
// Simple desactivation of direct access of all globals
// It is still accessible in reality, but it will me more visible
// if people really access them
if (x !== null && y !== null && z !== null) {
code_eval += "me.setStartingPosition(" + x + ", " + y + ", " + z + ");";
}
base = code_eval;
code_eval += code + "}; droneMe(Date, drone, Math, {});";
if (team == "R") {
base += "};ctx._teamRight.push(drone)";
code_eval += "ctx._teamRight.push(drone)";
}
else {
base += "};ctx._teamLeft.push(drone)";
code_eval += "ctx._teamLeft.push(drone)";
}
try {
eval(code_eval);
}
catch (error) {
eval(base);
}
};
return GameManager;
}());
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>GameManager.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>drone_web_worker_game_manager_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Game Manager JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662555757.05</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1003.10032.46857.65518</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1663944101.22</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>empty</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662555715.03</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/// <reference path="./GameManager.ts" />
var DroneLogAPI = /** @class */ (function () {
//*************************************************** CONSTRUCTOR **************************************************
function DroneLogAPI(gameManager, team, flight_parameters) {
this._gameManager = gameManager;
this._team = team;
this._flight_parameters = flight_parameters;
}
Object.defineProperty(DroneLogAPI.prototype, "team", {
//*************************************************** ACCESSOR *****************************************************
get: function () {
if (this._team == "L")
return this._gameManager.teamLeft;
else if (this._team == "R")
return this._gameManager.teamRight;
},
enumerable: true,
configurable: true
});
//*************************************************** FUNCTIONS ****************************************************
//#region ------------------ Internal
DroneLogAPI.prototype.internal_sendMsg = function (msg, to) {
var _this = this;
_this._gameManager.delay(function () {
if (to < 0) {
// Send to all drones
_this.team.forEach(function (drone) {
if (drone.infosMesh) {
try {
drone.onGetMsg(msg);
}
catch (error) {
console.warn('Drone crashed on sendMsg due to error:', error);
drone._internal_crash();
}
}
});
}
else {
// Send to specific drone
if (drone.infosMesh) {
try {
_this.team[to].onGetMsg(msg);
}
catch (error) {
console.warn('Drone crashed on sendMsg due to error:', error);
_this.team[to]._internal_crash();
}
}
}
}, GAMEPARAMETERS.latency.communication);
};
//#endregion
//#region ------------------ Accessible from AI
DroneLogAPI.prototype.log = function (msg) {
console.log("API say : " + msg);
};
DroneLogAPI.prototype.getGameParameter = function (name) {
if (["gameTime", "mapSize", "teamSize", "derive", "meteo", "initialHumanAreaPosition"].includes(name))
return this._gameManager.gameParameter[name];
};
DroneLogAPI.prototype._isWithinDroneView = function (drone_position, element_position) {
// Check if element is under the drone cone-view
var angle = GAMEPARAMETERS.drone.viewAngle ? GAMEPARAMETERS.drone.viewAngle : 60,
radius = drone_position.z * Math.tan(angle/2 * Math.PI/180),
distance = (drone_position.x - element_position.x) * (drone_position.x - element_position.x) +
(drone_position.y - element_position.y) * (drone_position.y - element_position.y);
if (distance < (radius*radius))
return true;
return false;
};
DroneLogAPI.prototype._getProbabilityOfDetection = function (drone_position) {
var h = drone_position.z,
km = GAMEPARAMETERS.meteo;
prob = 20 * (1 + (110-h)/25) * km;
return prob;
};
DroneLogAPI.prototype.isHumanPositionSpottedCalculation = function (drone) {
var context = this,
result = false,
drone_position = drone.infosMesh.position;
//swap axes back
drone_position = {
x: drone_position.x,
y: drone_position.z,
z: drone_position.y
};
context._gameManager.teamRight.forEach(function (human) {
if (human.infosMesh && context._isWithinDroneView(drone_position, human.position)) {
var prob = context._getProbabilityOfDetection(drone_position),
random = Math.floor(Math.random()*101);
if (random < prob)
result = true;
}
});
return result;
};
DroneLogAPI.prototype.isHumanPositionSpotted = function (drone) {
var context = this,
human_detected;
if (drone.__is_calculating_human_position !== true) {
drone.__is_calculating_human_position = true;
//human detection is done with the info captured by the drone
//at the moment this method is called
human_detected = context.isHumanPositionSpottedCalculation(drone);
context._gameManager.delay(function () {
drone.__is_calculating_human_position = false;
try {
drone.onCapture(human_detected);
} catch (error) {
console.warn('Drone crashed on capture due to error:', error);
drone._internal_crash();
}
}, 2000);
}
};
DroneLogAPI.prototype.processCoordinates = function (x, y, z) {
if(isNaN(x) || isNaN(y) || isNaN(z)){
throw new Error('Target coordinates must be numbers');
}
return {
x: x,
y: y,
z: z
};
};
DroneLogAPI.prototype.getDroneAI = function () {
return 'function distance(p1, p2) {' +
'var a = p1[0] - p2[0],' +
'b = p1[1] - p2[1];' +
'return Math.sqrt(a * a + b * b);' +
'}' +
'me.onStart = function() {' +
'console.log("DRONE LOG START!");' +
'if (!me.getFlightParameters())' +
'throw "DroneLog API must implement getFlightParameters";' +
'me.flightParameters = me.getFlightParameters();' +
'me.checkpoint_list = me.flightParameters.converted_log_point_list;' +
'me.startTime = new Date();' +
'me.initTimestamp = me.flightParameters.converted_log_point_list[0][3];' +
'me.setTargetCoordinates(me.checkpoint_list[0][0], me.checkpoint_list[0][1], me.checkpoint_list[0][2]);' +
'me.last_checkpoint_reached = -1;' +
'me.setAcceleration(10);' +
'};' +
'me.onUpdate = function () {' +
'var next_checkpoint = me.checkpoint_list[me.last_checkpoint_reached+1];' +
'if (distance([me.position.x, me.position.y], next_checkpoint) < 12) {' +
'var log_elapsed = next_checkpoint[3] - me.initTimestamp,' +
'time_elapsed = new Date() - me.startTime;' +
'if (time_elapsed < log_elapsed) {' +
'me.setDirection(0, 0, 0);' +
'return;' +
'}' +
'if (me.last_checkpoint_reached + 1 === me.checkpoint_list.length - 1) {' +
'me.setTargetCoordinates(me.position.x, me.position.y, me.position.z);' +
'return;' +
'}' +
'me.last_checkpoint_reached += 1;' +
'next_checkpoint = me.checkpoint_list[me.last_checkpoint_reached+1];' +
'me.setTargetCoordinates(next_checkpoint[0], next_checkpoint[1], next_checkpoint[2]);' +
'} else {' +
'me.setTargetCoordinates(next_checkpoint[0], next_checkpoint[1], next_checkpoint[2]);' +
'}' +
'};';
};
DroneLogAPI.prototype.setAltitude = function (altitude) {
return altitude;
};
DroneLogAPI.prototype.getMaxSpeed = function () {
return 3000;
};
DroneLogAPI.prototype.getInitialAltitude = function () {
return 0;
};
DroneLogAPI.prototype.getAltitudeAbs = function () {
return 0;
};
DroneLogAPI.prototype.getMinHeight = function () {
return 0;
};
DroneLogAPI.prototype.getMaxHeight = function () {
return 220;
};
DroneLogAPI.prototype.getFlightParameters = function () {
return this._flight_parameters;
};
return DroneLogAPI;
}());
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>DroneLogAPI.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>drone_web_worker_log_api_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Drone Log API JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662556208.64</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1003.194.53408.47940</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1663355083.2</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>empty</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662555993.19</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/*global window, rJS, jIO, RSVP, domsugar, console,
requestAnimationFrame, cancelAnimationFrame,
Worker,
DroneGameManager*/
/*global GameManager, console*/
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
var runGame;
var runGame, updateGame, eventGame, game_manager_instance;
// game.js
(function () {
"use strict";
console.log('game logic');
runGame = function (canvas, script, game_parameters_json, log) {
runGame = function (canvas) {
function processLog(game_parameters_json, log) {
var MAP_SIZE = 1000,
MIN_HEIGHT = 15,
MIN_X,
MAX_X,
MIN_Y,
MAX_Y,
SPEED_FACTOR = 0.75,
log_point_list = [],
converted_log_point_list = [];
function longitudToX(lon) {
return (MAP_SIZE / 360.0) * (180 + lon);
}
function latitudeToY(lat) {
return (MAP_SIZE / 180.0) * (90 - lat);
}
function normalizeToMap(x, y) {
var n_x = (x - MIN_X) / (MAX_X - MIN_X),
n_y = (y - MIN_Y) / (MAX_Y - MIN_Y);
return [n_x * 1000 - MAP_SIZE / 2, n_y * 1000 - MAP_SIZE / 2];
}
function latLonDistance(c1, c2) {
var R = 6371e3,
q1 = c1[0] * Math.PI / 180,
q2 = c2[0] * Math.PI / 180,
dq = (c2[0] - c1[0]) * Math.PI / 180,
dl = (c2[1] - c1[1]) * Math.PI / 180,
a = Math.sin(dq / 2) * Math.sin(dq / 2) +
Math.cos(q1) * Math.cos(q2) *
Math.sin(dl / 2) * Math.sin(dl / 2),
c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
function distance(p1, p2) {
return Math.sqrt(Math.pow(p1[0] - p2[0], 2) +
Math.pow(p1[1] - p2[1], 2));
}
var path_point_list = [], max_width, max_height,
line_list = log.split('\n'), log_entry_list = [],
i, start_time, end_time, log_entry, splitted_log_entry,
lat, lon, x, y, position, min_lon = 99999, min_lat = 99999,
max_lon = 0, max_lat = 0, previous, start_position, dist = 0,
path_point, average_speed = 0, flight_time, log_interval_time,
previous_log_time, height, timestamp, destination_lon,
destination_lat, log_header_found, time_offset = 1,
flight_dist = 0, start_AMSL = 0;
for (i = 0; i < line_list.length; i += 1) {
if (!log_header_found && !line_list[i].includes("timestamp;")) {
continue;
} else {
log_header_found = true;
}
if (line_list[i].indexOf("AMSL") >= 0 ||
!line_list[i].includes(";")) {
continue;
}
log_entry = line_list[i].trim();
if (log_entry) {
log_entry_list.push(log_entry);
splitted_log_entry = log_entry.split(";");
lat = parseFloat(splitted_log_entry[1]);
lon = parseFloat(splitted_log_entry[2]);
//get min and max lat and lon
if (lon < min_lon) {
min_lon = lon;
}
if (lat < min_lat) {
min_lat = lat;
}
if (lon > max_lon) {
max_lon = lon;
}
if (lat > max_lat) {
max_lat = lat;
}
}
}
//get map size from max distance
max_width = latLonDistance([min_lat, min_lon], [min_lat, max_lon]);
max_height = latLonDistance([min_lat, min_lon], [max_lat, min_lon]);
MAP_SIZE = Math.ceil(Math.max(max_width, max_height)) * 0.6;
MIN_X = longitudToX(min_lon);
MAX_X = longitudToX(max_lon);
MIN_Y = latitudeToY(min_lat);
MAX_Y = latitudeToY(max_lat);
if (log_entry_list[0] && log_entry_list[1]) {
var entry_1 = log_entry_list[0].split(";"),
entry_2 = log_entry_list[1].split(";"),
interval = parseInt(entry_2[0], 10) - parseInt(entry_1[0], 10);
//if interval > 1' then timestamp is in microseconds
if (Math.floor(interval / 1000) > 60) {
time_offset = 1000;
}
}
for (i = 0; i < log_entry_list.length; i += 1) {
splitted_log_entry = log_entry_list[i].split(";");
timestamp = parseInt(splitted_log_entry[0], 10);
if (i === 0) {
log_interval_time = 0;
start_time = timestamp;
} else {
log_interval_time += (parseInt(splitted_log_entry[0], 10) -
previous_log_time);
}
previous_log_time = parseInt(splitted_log_entry[0], 10);
average_speed += parseFloat(splitted_log_entry[8]);
lat = parseFloat(splitted_log_entry[1]);
lon = parseFloat(splitted_log_entry[2]);
if (i === log_entry_list.length - 1) {
destination_lon = lon;
destination_lat = lat;
end_time = timestamp;
}
height = parseFloat(splitted_log_entry[4]);
if (height < MIN_HEIGHT) {
height = MIN_HEIGHT;
} else {
height = height;
}
x = longitudToX(lon);
y = latitudeToY(lat);
position = normalizeToMap(x, y);
if (!previous) {
start_AMSL = parseFloat(splitted_log_entry[3]);
start_position = position;
start_position.push(height);
previous = position;
}
dist = distance(previous, position);
flight_dist += dist;
if (dist > 15) {
previous = position;
path_point = {
"type": "box",
"position": {
"x": position[0],
"y": position[1],
"z": height
},
"scale": {
"x": 3.5,
"y": 3.5,
"z": 3.5
},
"rotation": {
"x": 0,
"y": 0,
"z": 0
},
"color": {
"r": 0,
"g": 255,
"b": 0
},
"timestamp": timestamp
};
path_point_list.push(path_point);
}
converted_log_point_list.push([position[0],
position[1],
height, timestamp / time_offset]);
log_point_list.push([parseFloat(splitted_log_entry[1]),
parseFloat(splitted_log_entry[2]),
height, timestamp]);
}
average_speed = average_speed / log_entry_list.length;
log_interval_time = log_interval_time / log_entry_list.length / time_offset;
flight_time = (end_time - start_time) / 1000 / time_offset;
game_parameters_json.compareFlights = {
log: true,
draw: true,
map_width: MAP_SIZE,
map_height: MAP_SIZE,
MAP_SIZE: MAP_SIZE,
MIN_X: MIN_X,
MAX_X: MAX_X,
MIN_Y: MIN_Y,
MAX_Y: MAX_Y,
start_AMSL: start_AMSL,
flight_time: flight_time,
average_speed: average_speed,
log_interval_time: log_interval_time,
path: path_point_list,
full_log: log_point_list,
converted_log_point_list: converted_log_point_list
};
game_parameters_json.drone.maxSpeed = (flight_dist / flight_time) * SPEED_FACTOR;
game_parameters_json.obstacles = path_point_list;
game_parameters_json.randomSpawn.leftTeam.position.x = start_position[0];
game_parameters_json.randomSpawn.leftTeam.position.y = start_position[1];
game_parameters_json.randomSpawn.leftTeam.position.z = start_position[2];
game_parameters_json.gameTime = flight_time;
//give map some margin from the flight
game_parameters_json.mapSize.width = MAP_SIZE * 1.10;
game_parameters_json.mapSize.depth = MAP_SIZE * 1.10;
//flight destination
var destination_x = longitudToX(destination_lon),
destination_y = latitudeToY(destination_lat),
destination = normalizeToMap(destination_x, destination_y);
game_parameters_json.randomSpawn.rightTeam.position.x = destination[0];
game_parameters_json.randomSpawn.rightTeam.position.y = destination[1];
return game_parameters_json;
}
console.log('runGame', canvas);
// Create the Babylon engine
var engine = new BABYLON.Engine(canvas, true);
engine.enableOfflineSupport = false;
// Create the base scene
var scene = new BABYLON.Scene(engine);
scene.clearColor = new BABYLON.Color4(88/255,171/255,217/255,255/255);
// this._scene.debugLayer.show();
// Collisions
scene.collisionsEnabled = true;
// Camera
//cap camera distance to 1km
var camera = new BABYLON.ArcRotateCamera("camera", 3, 1.25, 800, new BABYLON.Vector3(1, 0, 1), scene);
camera.wheelPrecision = 10;
//camera.attachControl(scene.getEngine().getRenderingCanvas());
camera.maxz = 40000
scene.render();
game_parameters_json = processLog(game_parameters_json, log);
if (!game_manager_instance) {
game_manager_instance = new GameManager(canvas, script,
game_parameters_json, 5);
}
return game_manager_instance.run();
};
/*
// Resize canvas on window resize
window.addEventListener('resize', function () {
engine.resize();
});
*/
updateGame = function () {
return game_manager_instance.update();
};
eventGame = function (event) {
return game_manager_instance.event(event);
};
/*// Resize canvas on window resize
window.addEventListener('resize', function () {
engine.resize();
});*/
}(this));
\ No newline at end of file
......@@ -244,7 +244,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1002.51126.415.26214</string> </value>
<value> <string>1003.8464.37017.2594</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -262,7 +262,7 @@
</tuple>
<state>
<tuple>
<float>1662499095.93</float>
<float>1663849971.49</float>
<string>UTC</string>
</tuple>
</state>
......
/// <reference path="./typings/babylon.3.1.d.ts" />
var MapManager = /** @class */ (function () {
//*************************************************** CONSTRUCTOR **************************************************
function MapManager(scene) {
var _this = this;
var max = GAMEPARAMETERS.mapSize.width;
if (GAMEPARAMETERS.mapSize.depth > max)
max = GAMEPARAMETERS.mapSize.depth;
if (GAMEPARAMETERS.mapSize.height > max)
max = GAMEPARAMETERS.mapSize.height;
max = max < GAMEPARAMETERS.mapSize.depth ? GAMEPARAMETERS.mapSize.depth : max;
// Skybox
var max_sky = (max * 10 < 20000) ? max * 10 : 20000,
skybox = BABYLON.Mesh.CreateBox("skyBox", max_sky, scene);
skybox.infiniteDistance = true;
skybox.renderingGroupId = 0;
var skyboxMat = new BABYLON.StandardMaterial("skybox", scene);
skyboxMat.backFaceCulling = false;
skyboxMat.disableLighting = true;
skyboxMat.reflectionTexture = new BABYLON.CubeTexture("./assets/skybox/sky", scene);
skyboxMat.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
skyboxMat.infiniteDistance = true;
skybox.material = skyboxMat;
// Plane from bottom
var largeGroundMat = new BABYLON.StandardMaterial("largeGroundMat", scene);
largeGroundMat.specularColor = BABYLON.Color3.Black();
largeGroundMat.alpha = 0.4;
var largeGroundBottom = BABYLON.Mesh.CreatePlane("largeGroundBottom", max * 11, scene);
largeGroundBottom.position.y = -0.01;
largeGroundBottom.rotation.x = -Math.PI / 2;
largeGroundBottom.rotation.y = Math.PI;
largeGroundBottom.material = largeGroundMat;
// Camera
scene.activeCamera.upperRadiusLimit = max * 4;
// Terrain
var width = GAMEPARAMETERS.mapSize.width,
depth = GAMEPARAMETERS.mapSize.depth,
height = GAMEPARAMETERS.mapSize.height,
terrain = scene.getMeshByName("terrain001");
terrain.isVisible = true;
terrain.position = BABYLON.Vector3.Zero();
terrain.scaling = new BABYLON.Vector3(depth / 50000, depth / 50000, width / 50000);
// Goals
this._rGoal = BABYLON.Mesh.CreateSphere("rightGoal", 32, GAMEPARAMETERS.goalDiameter, scene);
var rGoalMat = new BABYLON.StandardMaterial("rGoalMat", scene);
rGoalMat.alpha = 0.0;
rGoalMat.diffuseColor = BABYLON.Color3.Red();
this._rGoal.material = rGoalMat;
this._rGoal.position = new BABYLON.Vector3(GAMEPARAMETERS.goalPositionRightTeam.x, GAMEPARAMETERS.goalPositionRightTeam.y, GAMEPARAMETERS.goalPositionRightTeam.z);
this._rGoal.computeWorldMatrix(true);
this._lGoal = BABYLON.Mesh.CreateSphere("leftGoal", 32, GAMEPARAMETERS.goalDiameter, scene);
goal_x = GAMEPARAMETERS.goalPositionLeftTeam.x;
goal_y = GAMEPARAMETERS.goalPositionLeftTeam.y;
goal_z = GAMEPARAMETERS.goalPositionLeftTeam.z;
this._lGoal.position = new BABYLON.Vector3(goal_x, goal_y, goal_z);
var lGoalMat = new BABYLON.StandardMaterial("lGoalMat", scene);
lGoalMat.alpha = 0.0;
lGoalMat.diffuseColor = BABYLON.Color3.Blue();
this._lGoal.material = lGoalMat;
this._lGoal.computeWorldMatrix(true);
//base is now a boat (special object)
ObstacleManager.Prefab.rotation = new BABYLON.Vector3(20.4, 0, 0);
ObstacleManager.Prefab.scaling = new BABYLON.Vector3(15, 15, 15);
goalPart1 = new ObstacleManager("goal_1", scene);
goalPart1.setStartingPosition(goal_x, goal_y, goal_z);
goalPart2 = BABYLON.MeshBuilder.CreateBox("goal_2", { 'size': 1 }, scene);
goalPart2.position = new BABYLON.Vector3(goal_x - 0.5, goal_y + 1.5, goal_z + 1.5);
goalPart2.rotation = new BABYLON.Vector3(0, 0, 0);
goalPart2.scaling = new BABYLON.Vector3(2, 2, 1.5);
goalPart3 = BABYLON.MeshBuilder.CreateCylinder("goal_3", {
'diameterBottom': 1.5,
'diameterTop': 1.5,
'height': 1
}, scene);
goalPart3.position = new BABYLON.Vector3(goal_x + 2.5, goal_y + 1.5, goal_z + 1.5);
goalPart3.rotation = new BABYLON.Vector3(0, 0, 0);
goalPart3.scaling = new BABYLON.Vector3(1.5, 3.5, 1.5);
// Obstacles
var count = 0;
this._obstacles = [];
GAMEPARAMETERS.obstacles.forEach(function (obs) {
var newObj;
switch (obs.type) {
case "box":
newObj = BABYLON.MeshBuilder.CreateBox("obs_" + count, { 'size': 1 }, scene);
break;
case "cylinder":
newObj = BABYLON.MeshBuilder.CreateCylinder("obs_" + count, {
'diameterBottom': obs.diameterBottom,
'diameterTop': obs.diameterTop,
'height': 1
}, scene);
break;
case "sphere":
newObj = BABYLON.MeshBuilder.CreateSphere("obs_" + count, {
'diameterX': obs.scale.x,
'diameterY': obs.scale.y,
'diameterZ': obs.scale.z
}, scene);
break;
case "boat":
ObstacleManager.Prefab.rotation = new BABYLON.Vector3(obs.rotation.x, obs.rotation.y, obs.rotation.z);
ObstacleManager.Prefab.scaling = new BABYLON.Vector3(obs.scale.x * 2, obs.scale.y * 2, obs.scale.z * 2);
newObj = new ObstacleManager("obs_" + count, scene);
newObj.setStartingPosition(obs.position.x, obs.position.y, obs.position.z);
break;
default:
return;
}
newObj["obsType"] = obs.type;
var convertion = Math.PI / 180;
if ("position" in obs)
newObj.position = new BABYLON.Vector3(obs.position.x, obs.position.y, obs.position.z);
if ("rotation" in obs)
newObj.rotation = new BABYLON.Vector3(obs.rotation.x * convertion, obs.rotation.y * convertion, obs.rotation.z * convertion);
if ("scale" in obs)
newObj.scaling = new BABYLON.Vector3(obs.scale.x, obs.scale.y, obs.scale.z);
if ("color" in obs) {
var material = new BABYLON.StandardMaterial(scene);
material.alpha = 1;
material.diffuseColor = new BABYLON.Color3(obs.color.r, obs.color.g, obs.color.b);
newObj.material = material;
}
_this._obstacles.push(newObj);
});
}
Object.defineProperty(MapManager.prototype, "lGoal", {
get: function () { return this._lGoal; },
enumerable: true,
configurable: true
});
Object.defineProperty(MapManager.prototype, "rGoal", {
get: function () { return this._rGoal; },
enumerable: true,
configurable: true
});
Object.defineProperty(MapManager.prototype, "obstacles", {
get: function () { return this._obstacles; },
enumerable: true,
configurable: true
});
return MapManager;
}());
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>MapManager.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>drone_web_worker_map_manager_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Map Manager JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662556210.78</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1002.54126.42371.36932</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662993125.49</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>empty</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662555978.78</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
/// <reference path="./typings/babylon.3.1.d.ts" />
var ObstacleManager = /** @class */ (function () {
//*************************************************** CONSTRUCTOR **************************************************
function ObstacleManager(id, scene) {
// Mesh
this._mesh = null;
this._controlMesh = null;
this._colliderBackMesh = null;
this._maxOrientation = Math.PI / 4;
this._scene = scene;
this._id = id;
// Create the control mesh
this._controlMesh = BABYLON.Mesh.CreateBox("obstacleControl_" + id, 0.01, this._scene);
this._controlMesh.isVisible = false;
this._controlMesh.rotation = new BABYLON.Vector3(0, Math.PI, 0);
this._controlMesh.computeWorldMatrix(true);
// Create the mesh from the obstacle prefab
console.log("ObstacleManager.Prefab:", ObstacleManager.Prefab);
this._mesh = ObstacleManager.Prefab.clone("obstacle_" + id, this._controlMesh);
this._mesh.position = BABYLON.Vector3.Zero();
this._mesh.isVisible = true;
this._mesh.computeWorldMatrix(true);
this._propellerAnimMeshes = [];
}
// API
ObstacleManager.prototype._swapAxe = function (vector) {
return new BABYLON.Vector3(vector.x, vector.z, vector.y);
};
Object.defineProperty(ObstacleManager.prototype, "colliderMesh", {
//*************************************************** ACCESSOR *****************************************************
get: function () { return this._mesh; },
enumerable: true,
configurable: true
});
Object.defineProperty(ObstacleManager.prototype, "colliderBackMesh", {
get: function () { return this._colliderBackMesh; },
enumerable: true,
configurable: true
});
Object.defineProperty(ObstacleManager.prototype, "infosMesh", {
get: function () { return this._controlMesh; },
enumerable: true,
configurable: true
});
Object.defineProperty(ObstacleManager.prototype, "position", {
get: function () {
if (this._controlMesh !== null) {
return this._swapAxe(this._controlMesh.position);
}
return null;
},
enumerable: true,
configurable: true
});
//*************************************************** FUNCTIONS ****************************************************
// -- Starting info
/**
* Set the starting position of the obstacle
* Take x,y,z coordinates as parameters
*/
ObstacleManager.prototype.setStartingPosition = function (x, y, z) {
this._controlMesh.position = new BABYLON.Vector3(x, y, z);
this._controlMesh.computeWorldMatrix(true);
this._mesh.computeWorldMatrix(true);
};
return ObstacleManager;
}());
<?xml version="1.0"?>
<ZopeData>
<record id="1" aka="AAAAAAAAAAE=">
<pickle>
<global name="Web Script" module="erp5.portal_type"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_Access_contents_information_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Add_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Change_local_roles_Permission</string> </key>
<value>
<tuple>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_Modify_portal_content_Permission</string> </key>
<value>
<tuple>
<string>Assignee</string>
<string>Assignor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>_View_Permission</string> </key>
<value>
<tuple>
<string>Anonymous</string>
<string>Assignee</string>
<string>Assignor</string>
<string>Associate</string>
<string>Auditor</string>
<string>Manager</string>
</tuple>
</value>
</item>
<item>
<key> <string>content_md5</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>content_type</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>default_reference</string> </key>
<value> <string>ObstacleManager.js</string> </value>
</item>
<item>
<key> <string>description</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>id</string> </key>
<value> <string>drone_web_worker_obstacle_manager_js</string> </value>
</item>
<item>
<key> <string>language</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>portal_type</string> </key>
<value> <string>Web Script</string> </value>
</item>
<item>
<key> <string>short_title</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Obstacle Manager JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>workflow_history</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAI=</string> </persistent>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="2" aka="AAAAAAAAAAI=">
<pickle>
<global name="PersistentMapping" module="Persistence.mapping"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>data</string> </key>
<value>
<dictionary>
<item>
<key> <string>document_publication_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAM=</string> </persistent>
</value>
</item>
<item>
<key> <string>edit_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAQ=</string> </persistent>
</value>
</item>
<item>
<key> <string>processing_status_workflow</string> </key>
<value>
<persistent> <string encoding="base64">AAAAAAAAAAU=</string> </persistent>
</value>
</item>
</dictionary>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="3" aka="AAAAAAAAAAM=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>publish_alive</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662651834.74</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
<item>
<key> <string>validation_state</string> </key>
<value> <string>published_alive</string> </value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="4" aka="AAAAAAAAAAQ=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>edit</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value>
<none/>
</value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1002.54032.1793.9847</string> </value>
</item>
<item>
<key> <string>state</string> </key>
<value> <string>current</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662657167.12</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
<record id="5" aka="AAAAAAAAAAU=">
<pickle>
<global name="WorkflowHistoryList" module="Products.ERP5Type.Workflow"/>
</pickle>
<pickle>
<dictionary>
<item>
<key> <string>_log</string> </key>
<value>
<list>
<dictionary>
<item>
<key> <string>action</string> </key>
<value> <string>detect_converted_file</string> </value>
</item>
<item>
<key> <string>actor</string> </key>
<value> <string>zope</string> </value>
</item>
<item>
<key> <string>comment</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>error_message</string> </key>
<value> <string></string> </value>
</item>
<item>
<key> <string>external_processing_state</string> </key>
<value> <string>converted</string> </value>
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>0.0.0.0</string> </value>
</item>
<item>
<key> <string>time</string> </key>
<value>
<object>
<klass>
<global name="DateTime" module="DateTime.DateTime"/>
</klass>
<tuple>
<none/>
</tuple>
<state>
<tuple>
<float>1662651770.1</float>
<string>UTC</string>
</tuple>
</state>
</object>
</value>
</item>
</dictionary>
</list>
</value>
</item>
</dictionary>
</pickle>
</record>
</ZopeData>
......@@ -103,7 +103,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Play Drone in WebWorker</string> </value>
<value> <string>Drone in WebWorker Page</string> </value>
</item>
<item>
<key> <string>version</string> </key>
......@@ -242,7 +242,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1002.51126.10432.54818</string> </value>
<value> <string>1002.51488.47400.14882</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -260,7 +260,7 @@
</tuple>
<state>
<tuple>
<float>1662499005.88</float>
<float>1662499250.39</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -9,6 +9,51 @@
"use strict";
console.log('game');
// Events props to send to worker
const mouseEventFields = new Set([
'altKey',
'bubbles',
'button',
'buttons',
'cancelBubble',
'cancelable',
'clientX',
'clientY',
'composed',
'ctrlKey',
'defaultPrevented',
'detail',
'eventPhase',
'fromElement',
'isTrusted',
'layerX',
'layerY',
'metaKey',
'movementX',
'movementY',
'offsetX',
'offsetY',
'pageX',
'pageY',
'relatedTarget',
'returnValue',
'screenX',
'screenY',
'shiftKey',
'timeStamp',
'type',
'which',
'x',
'y',
'wheelDelta',
'wheelDeltaX',
'wheelDeltaY',
'deltaX',
'deltaY',
'deltaZ',
'deltaMode',
]);
//////////////////////////////////////////
// Webworker
//////////////////////////////////////////
......@@ -124,10 +169,62 @@
var message_error_handler_defer = RSVP.defer(),
update_defer = null;
worker.onmessage = workerToMain;
// Always quit the game when the worker callback usage is over
// to prevent trying to call pause
//context.quit();
return message_error_handler_defer.promise;
/*options.canvas_original.addEventListener("mousewheel", (evt) => {
console.log("[MAIN] canvas mousewheel. event:", evt);
const eventClone = cloneEvent(evt);
worker.postMessage({
type: 'mousewheel',
eventClone: eventClone
});
});*/
function workerToMain(evt) {
switch (evt.data.type) {
case 'loaded':
return worker.postMessage({
type: 'start',
logic_url: options.logic_url,
canvas: options.canvas,
width: options.width,
height: options.height,
script: options.script,
game_parameters_json: options.game_parameters_json,
log: options.log
}, [options.canvas]);
break;
case 'started':
console.log('GAME: started');
context.unpause();
return step();
break;
case 'updated':
return update_defer.resolve('updated');
break;
case 'event':
bindEvent(evt.data);
break;
case 'canvasMethod':
options.canvas_original[evt.data.method](...evt.data.args);
break;
case 'canvasStyle':
options.canvas_original.style[evt.data.name] = evt.data.value;
break;
default:
message_error_handler_defer.reject(
new Error('Unsupported message ' + JSON.stringify(evt.data))
);
}
};
function step() {
context.loop_promise
.push(function () {
console.log('loop step');
worker.postMessage({
type: 'update'
});
......@@ -142,35 +239,48 @@
});
}
console.log('got worker ', worker, options);
worker.onmessage = function (evt) {
//console.log('Message received from worker', evt.data);
var type = evt.data.type;
if (type === 'loaded') {
console.log('loaded');
return worker.postMessage({
type: 'start',
logic_url: options.logic_url,
canvas: options.canvas
}, [options.canvas]);
function bindEvent(data) {
let target;
switch (data.targetName) {
case 'window':
target = window;
break;
case 'canvas':
target = options.canvas_original;
break;
case 'document':
target = document;
break;
}
if (type === 'started') {
console.log('started');
context.unpause();
return step();
if (!target) {
console.error('Unknown target: ' + data.targetName);
return;
}
if (type === 'updated') {
return update_defer.resolve('updated');
target.addEventListener(data.eventName, function (e) {
// We can`t pass original event to the worker
const eventClone = cloneEvent(e);
if (eventClone.type === "pointerout") {
console.log("ignoring pointerout event");
return;
}
console.log("[MAIN][LISTENER] event(cloned)-target:", data.eventName, data.targetName);
worker.postMessage({
type: 'event',
targetName: data.targetName,
eventName: data.eventName,
eventClone: eventClone,
});
}, data.opt);
}
function cloneEvent(event) {
event.preventDefault();
const eventClone = {};
for (let field of mouseEventFields) {
eventClone[field] = event[field];
}
message_error_handler_defer.reject(
new Error('Unsupported message ' + JSON.stringify(evt.data))
);
};
// Always quit the game when the worker callback usage is over
// to prevent trying to call pause
//context.quit();
return message_error_handler_defer.promise;
return eventClone;
}
})
]))
.push(undefined, function (error) {
......@@ -187,10 +297,12 @@
window.DroneGameManager = DroneGameManager;
}(RSVP, requestAnimationFrame, cancelAnimationFrame));
/*********************************************************************************************/
// droneaailefixe.js
(function () {
"use strict";
console.log('droneaailefixe');
//console.log('droneaailefixe');
}());
// page gadget.js
......@@ -202,6 +314,7 @@
// Acquired methods
/////////////////////////////////////////////////////////////////
.declareAcquiredMethod("updateHeader", "updateHeader")
.declareAcquiredMethod("jio_get", "jio_get")
.declareMethod('render', function renderHeader() {
var gadget = this,
......@@ -211,21 +324,46 @@
canvas = domsugar('canvas'),
offscreen;
domsugar(gadget.element, [canvas]);
/*
canvas.width = canvas.clientWidth;
canvas.height = canvas.clientHeight;
*/
//TODO fix hardcoded
canvas.width = 680;//canvas.clientWidth; <-- this is 0
canvas.height = 340;//canvas.clientHeight; <-- this is 0
offscreen = canvas.transferControlToOffscreen();
gadget.runGame({
logic_url: parameter_gamelogic,
canvas: offscreen
});
//TODO this should be in game logic BUT gadget can't be accessed from WW
var script_content, game_parameters_json, log_content;
return new RSVP.Queue()
.push(function () {
return gadget.jio_get("rescue_swarm_script_module/" + "web_worker");
})
.push(function (script) {
script_content = script.text_content;
return gadget.jio_get("rescue_swarm_map_module/" + "compare_map");
})
.push(function (parameters_doc) {
game_parameters_json = JSON.parse(parameters_doc.text_content);
return gadget.jio_get("rescue_swarm_script_module/" + "lp_loiter");
})
.push(function (log) {
log_content = log.text_content;
gadget.runGame({
logic_url: parameter_gamelogic,
canvas: offscreen,
canvas_original: canvas,
width: canvas.width,
height: canvas.height,
script: script_content,
game_parameters_json: game_parameters_json,
log: log_content
});
return gadget.updateHeader({
page_title: 'Game',
page_icon: 'puzzle-piece'
});
return gadget.updateHeader({
page_title: 'Game',
page_icon: 'puzzle-piece'
});
});
})
.declareJob('runGame', function runGame(options) {
......
......@@ -105,7 +105,7 @@
</item>
<item>
<key> <string>title</string> </key>
<value> <string>Play Drone in WebWorker JS</string> </value>
<value> <string>Drone in WebWorker Page JS</string> </value>
</item>
<item>
<key> <string>version</string> </key>
......@@ -244,7 +244,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1002.51485.29446.12083</string> </value>
<value> <string>1003.10118.17019.16759</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -262,7 +262,7 @@
</tuple>
<state>
<tuple>
<float>1662499048.26</float>
<float>1663954426.68</float>
<string>UTC</string>
</tuple>
</state>
......
......@@ -4,33 +4,172 @@
DroneGameManager*/
/*jslint nomen: true, indent: 2, maxerr: 3, maxlen: 80 */
// game.js
var document = {
addEventListener: function () {},
createElement: function () {}
};
(function (worker) {
"use strict";
var window = {};
console.log('worker loading');
worker.onmessage = function (evt) {
//console.log('Worker: Message received from main script', evt.data);
var type = evt.data.type;
if (type === 'start') {
console.log('Worker: Message received from main script', evt.data);
importScripts('babylon.js', evt.data.logic_url);
runGame(evt.data.canvas);
return worker.postMessage({'type': 'started'});
}
if (type === 'update') {
var i;
for (i = 0; i < 100000000; i += 1) {
1+1;
importScripts('babylon.js', 'babylon.gui.js');
}(this));
var window = {
addEventListener: function (event, fn, opt) {
bindHandler('window', event, fn, opt);
},
PointerEvent: true
};
document = {
addEventListener: function (event, fn, opt) {
bindHandler('document', event, fn, opt);
},
createElement: function () {
return {onwheel: true};
},
defaultView: window
};
function mainToWorker(evt) {
switch (evt.data.type) {
case 'start':
var offscreen_canvas = prepareCanvas(evt.data);
//override createElement as it is needed by babylon to create a canvas
document.createElement = function (type) {
if (type === 'canvas') { return offscreen_canvas; }
return { onwheel: true };
}
return worker.postMessage({'type': 'updated'});
}
throw new Error('Unsupported message ' + JSON.stringify(evt.data));
//self.postMessage('nutnut', evt);
};
//TODO evt.data.logic_url should contain the list of scripts
importScripts(
'rsvp.js',
'GameManager.js',
'DroneManager.js',
'MapManager.js',
'ObstacleManager.js',
'DroneAaileFixeAPI.js',
'DroneLogAPI.js',
'DroneAPI.js',
evt.data.logic_url);
RSVP = window.RSVP;
window = undefined;
return new RSVP.Queue()
.push(function () {
return runGame(offscreen_canvas, evt.data.script,
evt.data.game_parameters_json, evt.data.log);
})
.push(function () {
return postMessage({'type': 'started'});
});
break;
case 'update':
return new RSVP.Queue()
.push(function () {
return updateGame();
})
.push(function () {
return postMessage({'type': 'updated'});
});
break;
case 'event':
handleEvent(evt.data);
break;
//case 'mousewheel':
// eventGame(evt.data.eventClone);
// break;
default:
throw new Error('Unsupported message ' + JSON.stringify(evt.data));
}
};
// Doesn't work without it
class HTMLElement {}
self.handlers = new Map();
self.canvas = null;
// getBoundingInfo()
const rect = {
top: 0,
left: 0,
right: 0,
bottom: 0,
x: 0,
y: 0,
height: 0,
width: 0,
};
function bindHandler(targetName, eventName, fn, opt) {
const handlerId = targetName + eventName;
console.log("[WEBWORKER] bindHandler. handlerId:", handlerId);
handlers.set(handlerId, fn);
postMessage({
type: 'event',
targetName: targetName,
eventName: eventName,
opt: opt,
})
}
function handleEvent(event) {
const handlerId = event.targetName + event.eventName;
console.log("[WEBWORKER] handlerId:", handlerId);
event.eventClone.preventDefault = noop;
event.eventClone.target = self.canvas;
if (!handlers.has(handlerId)) {
throw new Error('Unknown handlerId: ' + handlerId);
}
handlers.get(handlerId)(event.eventClone);
}
function prepareCanvas(data) {
const canvas = data.canvas;
self.canvas = canvas;
canvas.clientWidth = data.width;
canvas.clientHeight = data.height;
canvas.width = data.width;
canvas.height = data.height;
rect.right = rect.width = data.width;
rect.bottom = rect.height = data.height;
canvas.setAttribute = function (name, value) {
postMessage({
type: 'canvasMethod',
method: 'setAttribute',
args: [name, value],
})
};
canvas.addEventListener = function (event, fn, opt) {
bindHandler('canvas', event, fn, opt);
};
canvas.getBoundingClientRect = function () {
return rect;
};
canvas.focus = function () {
postMessage({
type: 'canvasMethod',
method: 'focus',
args: [],
})
};
// noinspection JSUnusedGlobalSymbols
const style = {
set touchAction(value) {
postMessage({
type: 'canvasStyle',
name: 'touchAction',
value: value,
})
}
};
Object.defineProperty(canvas, 'style', {get() {return style}});
return canvas;
}
function noop() { console.log("noop!"); }
(function (worker) {
worker.onmessage = mainToWorker;
worker.postMessage({
'type': 'loaded'
});
//throw new Error('argh');
}(this));
\ No newline at end of file
......@@ -244,7 +244,7 @@
</item>
<item>
<key> <string>serial</string> </key>
<value> <string>1002.51134.58025.699</string> </value>
<value> <string>1003.10284.59408.13346</string> </value>
</item>
<item>
<key> <string>state</string> </key>
......@@ -262,7 +262,7 @@
</tuple>
<state>
<tuple>
<float>1662499082.61</float>
<float>1663959195.15</float>
<string>UTC</string>
</tuple>
</state>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment