Skip to content

Breaking Down Player Objects

Brian Erikson edited this page Jul 22, 2014 · 5 revisions

TL;DR Version

Adding Objects

  1. ws.send(message('playerObject', "{'cmd': 'pObjCreate', 'objectId': 'None', 'type': TYPE_AS_STRING, 'model': MODEL_AS_STRING, 'data': EPHEMERIS_AS_STRING +'}'));
  2. Ensure that the ephemeris that you send to the server DOES NOT have a full_name or name assigned to it; the server will do so.
  3. ensure the model in MODEL_AS_STRING is also located in js/objectDB.js with associated paths and Blender .dae files added to the /models folder.
  4. Sample ephemeris: ephemeris = { ma: -2.47311027, epoch: 2451545.0, a:1.00000261, e: 0.01671123, i: 0.00001531, w_bar: 102.93768193, w: 102.93768193, L: 100.46457166, om: 0, P: 365.256 }

Removing Objects

  1. ws.send(message('playerObject',"{'data': {'cmd': 'destroy', 'uuid': '" + OBJECT_ID + "'}}"));
  2. The server WILL NOT remove an object that the player is not an owner of.
  • Ensure that the OBJECT_ID is the ID you want to remove, because after you send this, it is out of your hands.

Typical Complete Workflow

New object request via js/main.js

  1. Data format of request is {cmd: 'playerObject', data: {cmd: 'pObjCreate', objectId: 'None', type: MODEL_TYPE_AS_STR, model: MODEL_AS_STR, data: EPHEMERIS}
  2. The EPHEMERIS consists of the following object: {ma: 0, epoch: 0, a: 0, e: 0, i: 0, w_bar: 0, w: 0, L: 0, om: 0, P: 0}
  • NOTE: Server will assign an ephemeris name according to type, model, and logged in user

Receive request at py/webSocketParser.py

  1. The first step in the parsing process is at the parse function, which hands off the parsing of the message to the playerObjectResponder function, located in the same module.
  2. The playerObjectResponder figures out which game instance the player is a part of, parses the data, and checks to see what action it needs to take.
  • Available actions right now are: 'create', 'query', and 'destroy', with query currently being unimplemented.
  1. The action we are concerned with right now is 'create'. The create command carries a heavier payload than the other two, as it needs to parse an entire object, and the other two commands only need to carry a UUID as data.
  2. The create command parses and passes the type of the object, model, orbit, and the user's name to the addPlayerObject function.

addPlayerObject function at py/game_logic/Game.py

  1. This function parses the requested object itself, and adds the full_name of the orbit.
  • The parsing substitutes whitespace as an underline, _, and apostrophes ' (to show possession), as a double-dash --, and finally adds a unique identifier so multiples of the same object don't conflict.
  • example: "TestUser--s_Magellan_Probe_5"
  1. The function then appends this new object to the playerObjects list for the game instance, and returns the object to the webSocketParser for submission. The websocket then sends the content contained in the following message: {cmd: pObjCreate, data: OBJECT}

Receive Object at /js/wsMessageParser.js

  1. the message from the server is received here, via the 'pObjCreate' command, parses the object, and then gets the model path from js/objectDB.js. this path is handed off to addBlenderPlayerObjectMesh at js/main.js.

Adding a blender player object mesh at js/main.js

  1. This function parses the .DAE blender file into something THREE.js can use and incorporate into the rSimulate.scene via a THREE.ColladaLoader().
  • The ColladaLoader takes a fraction of a second to parse, so we use a callback here to push the mesh to the addPlayerObject function and the playerObjects list once it's parsed.
  • You can also use this callback to scale, rotate, and introduce animations before loading to the scene.
  1. The addPlayerObject function adds the body to the scene via addBody function with the 'playerObject' indexLabel, then parses the orbit name to show up as a clean button label, and finally adds a button listener with a callback to the orientToObject function, which simply moves the camera to the object that was clicked.

Remove object request via js/main.js

  1. This action is initiated through the Remove this object button listener (which calls removePlayerBody function), which is added to the HTML doc through the initUI function.
  2. The removePlayerBody function checks to see which body is selected, and then sends a message to the server: {cmd: 'playerObject', data: {cmd: 'destroy', uuid: OBJECT_UUID}

Receive remove object request at py/webSocketParser.py

  1. Message is passed to the playerObjectResponder function via the playerObject command.
  2. The playerObjectResponder function parses the message, passes it to the 'destroy' command, gets the UUID of the object and passes this information to the removePlayerObject function, which is located in the Game.py module.

Removal of the server object via py/game_logic/Game.py

  1. The removePlayerObject function checks to see if the object exists in the playerObject list and if the requesting player owns the object, then removes it from the object and returns True. If the player doesn't own the object or the object doesn't match up with any existing UUIDs, the function returns False.
  2. The webSocketParser.py then passes this info onto the client an object: {cmd: 'playerObject', data: {cmd: 'pObjDestroyRequest', 'result': str(result), 'objectId': uuid, 'reason': str(result)}
  • The reason is currently statically configured as 'unknown'. This will later change to be more verbose. The server log is more verbose than the client's currently.

Confirm and remove player object from js/main.js

  1. The wsMessageParser.js module calls for removal of the body through the removeBody function, located in main.js. If the request to the server was denied, the error will log in the browser console.
  2. The removeBody function removes the object from the following: mesh and ellipse from the scene, the orbits array, meshes array, ellipses array, indexes array, and the playerObjects array, then removes the button from the UI, and deselects the object if it is still selected.