def test_setFragments_dae(self, client_type): """ Spawn a new object and modify its geometry at runtime. """ # Get the client for this test. client = self.clients[client_type] # Get a Collada fragment. f_dae = {'f_dae': getFragDae()} # Add a new template and spawn it. temp = getTemplate('t1', fragments=f_dae) assert client.addTemplates([temp]).ok new_obj = {'templateID': temp.aid, 'rbs': {'position': (1, 1, 1), 'velocityLin': (-1, -1, -1)}} ret = client.spawn([new_obj]) objID = ret.data[0] assert ret.ok and ret.data == [objID] del temp, new_obj, ret # Query the body states to obtain the 'version' value. ret = client.getRigidBodies(objID) assert ret.ok version = ret.data[objID]['rbs'].version # Fetch-, modify-, update- and verify the geometry. ret = client.getFragments([objID]) assert ret.ok assert ret.data[objID]['f_dae']['fragtype'] == 'DAE' # Change the geometry for fragment 'f_dae' to a RAW type. assert client.setFragments({objID: {'f_dae': getFragRaw()._asdict()}}).ok # Ensure the fragment is now indeed of type 'RAW'. ret = client.getFragments([objID]) assert ret.ok assert ret.data[objID]['f_dae']['fragtype'] == 'RAW' # Ensure 'version' is different as well. ret = client.getRigidBodies(objID) assert ret.ok and (ret.data[objID]['rbs'].version != version) # Change the fragment geometry once more. version = ret.data[objID]['rbs'].version assert client.setFragments({objID: {'f_dae': getFragDae()._asdict()}}).ok # Ensure it now has type 'DAE' again. ret = client.getFragments([objID]) assert ret.ok assert ret.data[objID]['f_dae']['fragtype'] == 'DAE' # Ensure 'version' is different as well. ret = client.getRigidBodies(objID) assert ret.ok and (ret.data[objID]['rbs'].version != version)
def test_collada_model(self, client_type): """ Add a template based on a Collada model, spawn it, and query its geometry. """ # Get the client for this test. client = self.clients[client_type] # Add a valid template with Collada data and verify the upload worked. temp = getTemplate('foo', fragments={'f_dae': getFragDae()}) assert client.addTemplates([temp]).ok # Spawn the template. ret = client.spawn([{'templateID': temp.aid}]) assert ret.ok objID = ret.data[0] # Query and the geometry. ret = client.getFragments([objID]) assert ret.ok # Verify it has the correct type ('DAE') and address. ret = ret.data[objID] assert ret['f_dae']['fragtype'] == 'DAE' assert ret['f_dae']['url_frag'] == ( config.url_instances + '/' + str(objID) + '/f_dae')
def test_remove_fragments(self, client_type): """ Remove a fragment. This test is basically the integration test for 'test_dibbler.test_updateFragments_partial'. """ # Get the client for this test. client = self.clients[client_type] # Convenience. objID = 1 # The original template has the following three fragments: frags_orig = { 'fname_1': getFragRaw(), 'fname_2': getFragDae(), 'fname_3': getFragRaw(), } t1 = getTemplate('t1', fragments=frags_orig) # Add a new template and spawn it. assert client.addTemplates([t1]).ok new_obj = {'templateID': t1.aid, 'rbs': {'position': (1, 1, 1), 'velocityLin': (-1, -1, -1)}} assert client.spawn([new_obj]) == (True, None, [objID]) # Query the fragment geometries and Body State to verify that both # report three fragments. ret = client.getFragments([objID]) assert ret.ok and len(ret.data[objID]) == 3 ret = client.getObjectStates(objID) assert ret.ok and len(ret.data[objID]['frag']) == 3 # Update the fragments as follows: keep the first intact, remove the # second, and modify the third one. frags_new = { 'fname_2': getFragNone()._asdict(), 'fname_3': getFragDae()._asdict() } assert client.setFragments({objID: frags_new}).ok # After the last update there must now only be two fragments. ret = client.getFragments([objID]) assert ret.ok and len(ret.data[objID]) == 2 ret = client.getObjectStates(objID) assert ret.ok and len(ret.data[objID]['frag']) == 2
def test_setFragments_raw(self, client_type): """ Spawn a new object and modify its geometry at runtime. """ # Get the client for this test. client = self.clients[client_type] # Convenience. objID = 1 # Add a new template and spawn it. frag = {'bar': getFragRaw()} temp = getTemplate('t1', fragments=frag) assert client.addTemplates([temp]).ok new_obj = {'templateID': temp.aid, 'rbs': {'position': (1, 1, 1), 'velocityLin': (-1, -1, -1)}} ret = client.spawn([new_obj]) assert ret.ok and ret.data == [objID] del temp, new_obj, ret # Query the SV to obtain the 'version' value. ret = client.getRigidBodies(objID) assert ret.ok version = ret.data[objID]['rbs'].version # Fetch-, modify-, update- and verify the geometry. ret = client.getFragments([objID]) assert ret.ok assert ret.data[objID]['bar']['fragtype'] == 'RAW' # Download the fragment. base_url = 'http://{ip}:{port}'.format( ip=config.addr_webserver, port=config.port_webserver) url = base_url + ret.data[objID]['bar']['url_frag'] + '/model.json' for ii in range(10): assert ii < 8 try: tmp = urllib.request.urlopen(url).readall() break except urllib.request.URLError: time.sleep(0.2) tmp = json.loads(tmp.decode('utf8')) assert FragRaw(**tmp) == frag['bar'].fragdata # Change the fragment geometries. cmd = {objID: {k: v._asdict() for (k, v) in frag.items()}} assert client.setFragments(cmd).ok ret = client.getFragments([objID]) assert ret.ok assert ret.data[objID]['bar']['fragtype'] == 'RAW' # Download the fragment. url = base_url + ret.data[objID]['bar']['url_frag'] + '/model.json' tmp = urllib.request.urlopen(url).readall() tmp = json.loads(tmp.decode('utf8')) assert FragRaw(**tmp) == frag['bar'].fragdata # Ensure 'version' is different as well. ret = client.getRigidBodies(objID) assert ret.ok and (ret.data[objID]['rbs'].version != version)
def test_create_fetch_template(self, client_type): """ Add a new object to the templateID DB and query it again. """ # Get the client for this test. client = self.clients[client_type] # Request an invalid ID. assert not client.getTemplates(['blah']).ok # Clerk has default objects. This one has an empty collision shape... name_1 = '_templateEmpty' ret = client.getTemplates([name_1]) assert ret.ok and (len(ret.data) == 1) assert ret.data[name_1]['template'].rbs.cshapes == {'csempty': getCSEmpty()} # ... this one is a sphere... name_2 = '_templateSphere' ret = client.getTemplates([name_2]) assert ret.ok and (len(ret.data) == 1) assert ret.data[name_2]['template'].rbs.cshapes == {'cssphere': getCSSphere()} # ... and this one is a box. name_3 = '_templateBox' ret = client.getTemplates([name_3]) assert ret.ok and (len(ret.data) == 1) assert ret.data[name_3]['template'].rbs.cshapes == {'csbox': getCSBox()} # Retrieve all three again but with a single call. ret = client.getTemplates([name_1, name_2, name_3]) assert ret.ok assert set(ret.data.keys()) == set((name_1, name_2, name_3)) assert ret.data[name_2]['template'].rbs.cshapes == {'cssphere': getCSSphere()} assert ret.data[name_3]['template'].rbs.cshapes == {'csbox': getCSBox()} assert ret.data[name_1]['template'].rbs.cshapes == {'csempty': getCSEmpty()} # Add a new object template. frag = {'bar': getFragRaw()} body = getRigidBody() temp_name = 't1' temp_orig = getTemplate(temp_name, rbs=body, fragments=frag) assert client.addTemplates([temp_orig]).ok # Fetch the just added template again and verify its content (skip the # geometry because it contains only meta information and will be # checked afterwards). ret = client.getTemplates([temp_name]) assert ret.ok and (len(ret.data) == 1) temp_out = ret.data[temp_name]['template'] assert temp_out.boosters == temp_orig.boosters assert temp_out.factories == temp_orig.factories assert temp_out.rbs == temp_orig.rbs # Fetch the geometry from the web server and verify it. ret = client.getTemplateGeometry(ret.data[temp_name]) assert ret.ok assert ret.data['bar'] == frag['bar'].fragdata del ret, temp_out, temp_orig # Define a new object with two boosters and one factory unit. # The 'boosters' and 'factories' arguments are a list of named # tuples. Their first argument is the unit ID (Azrael does not # automatically assign any). boosters = { '0': types.Booster(pos=(0, 0, 0), direction=(0, 0, 1), minval=0, maxval=0.5, force=0), '1': types.Booster(pos=(0, 0, 0), direction=(0, 0, 1), minval=0, maxval=0.5, force=0), } factories = { '0': types.Factory(pos=(0, 0, 0), direction=(0, 0, 1), templateID='_templateBox', exit_speed=(0.1, 0.5)) } # Attempt to query the geometry of a non-existing object. assert client.getFragments([1]) == (True, None, {1: None}) # Define a new template, add it to Azrael, spawn it, and record its # object ID. body = getRigidBody(cshapes={'csbox': getCSBox()}) temp = getTemplate('t2', rbs=body, fragments=frag, boosters=boosters, factories=factories) assert client.addTemplates([temp]).ok init = {'templateID': temp.aid, 'rbs': {'position': (0, 0, 0)}} ret = client.spawn([init]) assert ret.ok and len(ret.data) == 1 objID = ret.data[0] # Retrieve- and verify the geometry of the just spawned object. ret = client.getFragments([objID]) assert ret.ok assert ret.data[objID]['bar']['fragtype'] == 'RAW' # Retrieve the entire template and verify the CS and geometry, and # number of boosters/factories. ret = client.getTemplates([temp.aid]) assert ret.ok and (len(ret.data) == 1) t_data = ret.data[temp.aid]['template'] assert t_data.rbs == body assert t_data.boosters == temp.boosters assert t_data.factories == temp.factories # Fetch the geometry from the Web server and verify it is correct. ret = client.getTemplateGeometry(ret.data[temp.aid]) assert ret.ok assert ret.data['bar'] == frag['bar'].fragdata
def run(self): """ """ # Return immediately if no resets are required. if self.period == -1: return # Instantiate Client. client = azrael.client.Client() # Query all object IDs. This happens only once which means the geometry # swap does not affect newly generated objects. time.sleep(1) ret = client.getAllObjectIDs() objIDs = ret.data print('\n-- {} objects --\n'.format(len(objIDs))) # Query and backup all models currently in the scene. geo_meta = client.getFragments(objIDs).data base_url = 'http://{}:{}'.format( azrael.config.addr_webserver, azrael.config.port_webserver) geo_orig = {} for objID in objIDs: frags = {} for frag_name in geo_meta[objID]: url = base_url + geo_meta[objID][frag_name]['url_frag'] url += '/model.json' tmp = urllib.request.urlopen(url).readall() tmp = json.loads(tmp.decode('utf8')) tmp = FragRaw(**tmp) frags[frag_name] = FragMeta(frag_name, 'raw', tmp) del url, tmp geo_orig[objID] = frags del frags, objID del geo_meta, base_url # Compile a set of sphere models for all objects. These will be # periodically swapped out for the original models. sphere_vert, sphere_uv, sphere_rgb = loadSphere() sphere = FragRaw(sphere_vert, sphere_uv, sphere_rgb) geo_spheres = {} for objID in objIDs: tmp = {_: FragMeta(_, 'raw', sphere) for _ in geo_orig[objID]} geo_spheres[objID] = tmp del tmp del sphere_vert, sphere_uv, sphere_rgb, sphere cnt = 0 while True: # Update the counter and pause for the specified time. cnt = (cnt + 1) % 20 time.sleep(self.period) # Swap out the geometry. if (cnt % 2) == 1: geo = geo_spheres else: geo = geo_orig # Apply the new geometry to each fragment. for objID, val in geo.items(): ret = client.updateFragments(objID, list(val.values())) if not ret.ok: print('--> Terminating geometry updates') sys.exit(1) # Modify the global scale and a fragment position. scale = (cnt + 1) / 10 for objID in objIDs: # Change the scale of the overall object. new_sv = RigidBodyDataOverride(scale=scale) client.setRigidBody(objID, new_sv) # Move the second fragment. x = -10 + cnt newStates = { objID: [FragState('frag_2', 1, [x, 0, 0], [0, 0, 0, 1])] } client.setFragmentStates(newStates) # Print status for user. print('Scale={:.1f}'.format(scale))