コード例 #1
0
ファイル: test_client.py プロジェクト: daviddeng/azrael
    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)
コード例 #2
0
ファイル: test_client.py プロジェクト: daviddeng/azrael
    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
コード例 #3
0
ファイル: test_client.py プロジェクト: daviddeng/azrael
    def test_update_FragmentStates(self, client_type):
        """
        Query and modify fragment states.
        Note that fragment states are updated via 'setFragments'.
        """
        # Get the client for this test.
        client = self.clients[client_type]

        # Convenience.
        objID = 1

        # Add a new template and spawn it.
        temp = getTemplate('t1', fragments={'bar': getFragRaw()})
        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 Body State to get the Fragment States. Then verify the
        # Fragment State named 'bar'.
        ret = client.getObjectStates(objID)
        ref = {'bar': {'scale': 1, 'position': [0, 0, 0], 'rotation': [0, 0, 0, 1]}}
        assert ret.ok
        assert ret.data[objID]['frag'] == ref

        # Modify and update the fragment states in Azrael, then query and
        # verify it worked.
        newStates = {objID: {'bar': {'scale': 2.2, 'position': [1, 2, 3],
                                     'rotation': [1, 0, 0, 0]}}}
        assert client.setFragments(newStates).ok
        ret = client.getObjectStates(objID)
        assert ret.ok
        ret = ret.data[objID]['frag']['bar']
        assert ret == newStates[objID]['bar']
コード例 #4
0
ファイル: demo_pcb.py プロジェクト: daviddeng/azrael
def placeTarget(host, numTargets=1):
    """
    Spawn ``numTargets`` in the scene.

    The targets visually oscillate in size. They also have no collision
    shapes and are thus unaffected by physics (ie they cannot collide
    with anything).
    """
    # Connect to Azrael.
    client = azrael.client.Client(ip=host)

    # Spawn the target object from the 'BoosterCube_1' template (defined in
    # 'demo_boostercube' that must already be running at this point).
    init = []
    for ii in range(numTargets):
        tmp = {
            'templateID': 'BoosterCube_1',
            'rbs': {'imass': 0, 'position': (0, 0, 3 * ii)}
        }
        init.append(tmp)
    ret = client.spawn(init)

    # Check for errors and abort if there are any.
    if not ret.ok:
        print(ret)
        sys.exit(1)

    # Extract the IDs of the spawned target objects.
    targetIDs = ret.data
    print('Spawned {} targets'.format(len(targetIDs)))
    del init, ret

    # Replace the collision shape with an empty one to disable the physics for
    # those targets.
    cs = types.CollShapeEmpty()
    cs = types.CollShapeMeta('empty', (0, 0, 0), (0, 0, 0, 1), cs)
    cmd = {targetID: {'cshapes': {'cssphere': cs}} for targetID in targetIDs}
    assert client.setRigidBodies(cmd).ok
    del cs

    # Tag the object with target. This is necessary because the
    # `PyConBrisbaneClient.selectNewTarget` method will use to distinguish
    # targets from other objects.
    cmd = {targetID: 'Target' for targetID in targetIDs}
    assert client.setCustomData(cmd)

    # Create a random phase offset in the oscillation pattern (pure eye candy
    # to avoid all targets scale synchronously).
    phi = 2 * np.pi * np.random.rand(len(targetIDs))

    # Modify the scale of the target every 100ms.
    cnt = 0
    while True:
        time.sleep(0.1)

        # Compile the payload for the update command, then send it to Azrael.
        # The fragment names (eg 'frag_1') are hard coded in the Template
        # (don't worry about them, just accept that they exist).
        cmd = {}
        for idx, targetID in enumerate(targetIDs):
            # Compute the new scale value.
            scale = 1 + np.sin(2 * np.pi * 0.1 * cnt + phi[idx])
            scale *= 0.1

            tmp = {
                'frag_1': {'scale': scale},
                'frag_2': {'scale': scale},
            }
            cmd[targetID] = tmp
        assert client.setFragments(cmd).ok

        # Randomly update the target's position every 10s.
        if (cnt % 100) == 0:
            cmd = {}
            for targetID in targetIDs:
                pos = 15 * np.random.rand(3) - 10
                cmd[targetID] = {'position': pos.tolist()}
            assert client.setRigidBodies(cmd).ok
        cnt += 1
コード例 #5
0
ファイル: test_client.py プロジェクト: daviddeng/azrael
    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)
コード例 #6
0
ファイル: demo_default.py プロジェクト: daviddeng/azrael
def spawnCubes(numCols, numRows, numLayers, center=(0, 0, 0)):
    """
    Spawn multiple cubes in a regular grid.

    The number of cubes equals ``numCols`` * ``numRows`` * ``numLayers``. The
    center of this "prism" is at ``center``.

    Every cube has two boosters and two factories. The factories can themselves
    spawn more (purely passive) cubes.
    """
    tID_cube = addTexturedCubeTemplates(numCols, numRows, numLayers)

    # Get a Client instance.
    client = azrael.client.Client()

    # ----------------------------------------------------------------------
    # Spawn the differently textured cubes in a regular grid.
    # ----------------------------------------------------------------------
    allObjs = []
    cube_idx = 0
    cube_spacing = 0.1

    # Determine the template and position for every cube. The cubes are *not*
    # spawned in this loop, but afterwards.
    print("Compiling scene: ", end="", flush=True)
    t0 = time.time()
    for row in range(numRows):
        for col in range(numCols):
            for lay in range(numLayers):
                # Base position of cube.
                pos = np.array([col, row, lay], np.float64)

                # Add space in between cubes.
                pos *= -(2 + cube_spacing)

                # Correct the cube's position to ensure the center of the
                # grid coincides with the origin.
                pos[0] += (numCols // 2) * (1 + cube_spacing)
                pos[1] += (numRows // 2) * (1 + cube_spacing)
                pos[2] += (numLayers // 2) * (1 + cube_spacing)

                # Move the grid to position ``center``.
                pos += np.array(center)

                # Store the position and template for this cube.
                allObjs.append({"templateID": tID_cube[cube_idx], "rbs": {"position": pos.tolist()}})
                cube_idx += 1
                del pos
    print("{:,} objects ({:.1f}s)".format(len(allObjs), time.time() - t0))
    del cube_idx, cube_spacing, row, col, lay

    # Spawn the cubes from the templates at the just determined positions.
    print("Spawning {} objects: ".format(len(allObjs)), end="", flush=True)
    t0 = time.time()
    ret = client.spawn(allObjs)
    if not ret.ok:
        print("** Error:")
        print(ret)
        assert False
    print(" {:.1f}s".format(time.time() - t0))

    # Make 'frag_2' invisible by setting its scale to zero.
    for objID in ret.data:
        assert client.setFragments({objID: {"frag_2": {"scale": 0}}}).ok
        assert client.setCustomData({objID: "asteroid"}).ok
コード例 #7
0
ファイル: demo_default.py プロジェクト: daviddeng/azrael
def addBoosterCubeTemplate(scale, vert, uv, rgb):
    # Get a Client instance.
    client = azrael.client.Client()

    # Ensure the data has the correct format.
    vert = scale * np.array(vert)
    uv = np.array(uv, np.float32)
    rgb = np.array(rgb, np.uint8)
    print("done")

    # Attach four boosters: left (points down), front (points back), right
    # (points up), and back (point forward).
    dir_up = np.array([0, +1, 0])
    dir_forward = np.array([0, 0, -1])
    pos_left = np.array([-1.5, 0, 0])
    pos_center = np.zeros(3)

    boosters = {
        "0": types.Booster(pos=pos_left, direction=-dir_up, minval=0, maxval=10.0, force=0),
        "1": types.Booster(pos=pos_center, direction=dir_forward, minval=0, maxval=1000.0, force=0),
        "2": types.Booster(pos=-pos_left, direction=dir_up, minval=0, maxval=10.0, force=0),
        "3": types.Booster(pos=pos_center, direction=-dir_forward, minval=0, maxval=1000.0, force=0),
    }
    del dir_up, dir_forward, pos_left, pos_center

    # Construct a Tetrahedron (triangular Pyramid). This is going to be the
    # (super simple) "flame" that comes out of the (still invisible) boosters.
    y = 0.5 * np.arctan(np.pi / 6)
    a = (-0.5, -y, 1)
    b = (0.5, -y, 1)
    c = (0, 3 / 4 - y, 1)
    d = (0, 0, 0)
    vert_b = [(a + b + c) + (a + b + d) + (a + c + d) + (b + c + d)]
    vert_b = np.array(vert_b[0], np.float64)
    del a, b, c, d, y

    # Add the template to Azrael.
    print("  Adding template to Azrael... ", end="", flush=True)
    tID = "ground"
    cs = CollShapeBox(1, 1, 1)
    cs = CollShapeMeta("box", (0, 0, 0), (0, 0, 0, 1), cs)
    z = np.array([])
    frags = {
        "frag_1": getFragMeta("raw", FragRaw(vert, uv, rgb)),
        "b_left": getFragMeta("raw", FragRaw(vert_b, z, z)),
        "b_right": getFragMeta("raw", FragRaw(vert_b, z, z)),
    }

    body = getRigidBody()
    temp = Template(tID, body, frags, boosters, {})
    assert client.addTemplates([temp]).ok
    del cs, frags, temp, z
    print("done")

    # Spawn the template near the center.
    print("  Spawning object... ", end="", flush=True)
    pos, orient = [0, 0, -10], [0, 1, 0, 0]
    new_obj = {
        "templateID": tID,
        "rbs": {
            "scale": scale,
            "imass": 0.1,
            "position": pos,
            "rotation": orient,
            "axesLockLin": [1, 1, 1],
            "axesLockRot": [1, 1, 1],
        },
    }
    ret = client.spawn([new_obj])
    objID = ret.data[0]
    print("done (ID=<{}>)".format(objID))

    # Disable the booster fragments by settings their scale to Zero.
    newStates = {objID: {"b_left": {"scale": 0}, "b_right": {"scale": 0}}}
    assert client.setFragments(newStates).ok