Exemple #1
0
    def test_spawn_and_delete_one_object(self, client_type):
        """
        Ask Clerk to spawn one object.
        """
        # Get the client for this test.
        client = self.clients[client_type]

        # Constants and parameters for this test.
        objID, templateID = 1, '_templateEmpty'

        # Spawn a new object from templateID. The new object must have objID=1.
        init = {'templateID': templateID,
                'rbs': {'position': (0, 0, 0)}}
        ret = client.spawn([init])
        assert ret.ok and ret.data == [objID]

        # Attempt to spawn a non-existing template.
        assert not client.spawn([{'templateID': 'blah'}]).ok

        # Send invalid data to 'spawn'.
        assert not client.spawn([{'blah': 'blah'}]).ok

        # Exactly one object must exist at this point.
        ret = client.getAllObjectIDs()
        assert (ret.ok, ret.data) == (True, [objID])

        # Attempt to delete a non-existing object. This must silently fail.
        assert client.removeObject(100).ok
        ret = client.getAllObjectIDs()
        assert (ret.ok, ret.data) == (True, [objID])

        # Delete an existing object.
        assert client.removeObject(objID).ok
        ret = client.getAllObjectIDs()
        assert (ret.ok, ret.data) == (True, [])
Exemple #2
0
    def run(self):
        # Return immediately if no resets are required.
        if self.period == -1:
            return

        # Establish connection to Azrael.
        client = azrael.client.Client()

        # Query all objects in the scene. These are the only objects that will
        # survive the reset.
        ret = client.getAllObjectIDs()
        assert ret.ok
        ret = client.getRigidBodies(ret.data)
        assert ret.ok
        allowed_objIDs = {k: v["rbs"] for k, v in ret.data.items() if v is not None}
        print("Took simulation snapshot for reset: ({} objects)".format(len(allowed_objIDs)))

        # Periodically reset the SV values. Set them several times because it
        # is well possible that not all State Variables reach Leonard in the
        # same frame, which means some objects will be reset while other are
        # not. This in turn may cause strange artefacts in the next physics
        # update step, especially when the objects now partially overlap.
        while True:
            # Wait until the timeout expires.
            time.sleep(self.period)

            # Remove all newly added objects.
            ret = client.getAllObjectIDs()
            for objID in ret.data:
                if objID not in allowed_objIDs:
                    client.removeObject(objID)

            # Forcefully reset the position and velocity of every object. Do
            # this several times since network latency may result in some
            # objects being reset sooner than others.
            for ii in range(5):
                for objID, SV in allowed_objIDs.items():
                    tmp = {
                        "position": SV.position,
                        "velocityLin": SV.velocityLin,
                        "velocityRot": SV.velocityRot,
                        "rotation": SV.rotation,
                    }
                    assert client.setRigidBodies({objID: tmp}).ok
                time.sleep(0.1)
Exemple #3
0
    def test_getAllObjectIDs(self, client_type):
        """
        Ensure the getAllObjectIDs command reaches Clerk.
        """
        # Get the client for this test.
        client = self.clients[client_type]

        # Constants and parameters for this test.
        templateID, objID_1 = '_templateEmpty', 1

        # So far no objects have been spawned.
        ret = client.getAllObjectIDs()
        assert (ret.ok, ret.data) == (True, [])

        # Spawn a new object.
        init = {'templateID': templateID, 'rbs': {'position': (0, 0, 0)}}
        ret = client.spawn([init])
        assert ret.ok and ret.data == [objID_1]

        # The object list must now contain the ID of the just spawned object.
        ret = client.getAllObjectIDs()
        assert (ret.ok, ret.data) == (True, [objID_1])
Exemple #4
0
def resetSimulation(host, port=5555):
    """
    Delete all objects in the scene.

    Azrael does not have a command to do that (yet), which is why this function
    queries all objects and the deletes them one-by-one.

    The `host` and `port` parameters specify the location of the Azrael API.
    """
    # Connect to Azrael.
    client = azrael.client.Client(host, port=port)

    # Query IDs of all objects in the simulation.
    ret = client.getAllObjectIDs()
    assert ret.ok
    allIDs = ret.data

    # Delete all objects.
    for objID in allIDs:
        assert client.removeObject(objID).ok
    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))