Пример #1
0
    def testAgent(self):

        physics = None
        viewer = None

        try:
            scene = Scene()

            physics = Panda3dBulletPhysics(scene, debug=True)

            agent = scene.agents[0].find('**/+BulletRigidBodyNode')
            agent.setPos(LVector3f(0, 0, 1.0))
            agent.node().setLinearVelocity(LVector3f(1, 0, 0))
            agent.node().setAngularVelocity(LVector3f(0, 0, 1))
            agent.node().setActive(True)

            viewer = Viewer(scene, interactive=False)
            viewer.disableMouse()

            mat = np.array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, -10, 0, 1])
            mat = LMatrix4f(*mat.ravel())
            viewer.cam.setMat(mat)
            for _ in range(50):
                viewer.step()
            time.sleep(1.0)

        finally:
            self.hulkSmash(None, physics, viewer)
Пример #2
0
    def testInit(self):
        scene = Scene()

        # Load object to scene
        modelId = '126'
        modelFilename = os.path.join(TEST_SUNCG_DATA_DIR, "object",
                                     str(modelId),
                                     str(modelId) + ".egg")
        assert os.path.exists(modelFilename)
        model = loadModel(modelFilename)
        model.setName('object-' + str(modelId))
        model.reparentTo(scene.scene)

        self.assertTrue(scene.getTotalNbHouses() == 0)
        self.assertTrue(scene.getTotalNbRooms() == 0)
        self.assertTrue(scene.getTotalNbObjects() == 1)
Пример #3
0
    def testRenderWithModelLights(self):

        filename = os.path.join(TEST_SUNCG_DATA_DIR, 'metadata',
                                'suncgModelLights.json')
        info = SunCgModelLights(filename)

        scene = Scene()

        modelId = 's__1296'
        modelFilename = os.path.join(TEST_SUNCG_DATA_DIR, "object",
                                     str(modelId),
                                     str(modelId) + ".egg")
        assert os.path.exists(modelFilename)
        model = loadModel(modelFilename)
        model.setName('model-' + str(modelId))
        model.show(BitMask32.allOn())

        objectsNp = scene.scene.attachNewNode('objects')
        objNp = objectsNp.attachNewNode('object-' + str(modelId))
        model.reparentTo(objNp)

        # Calculate the center of this object
        minBounds, maxBounds = model.getTightBounds()
        centerPos = minBounds + (maxBounds - minBounds) / 2.0

        # Add offset transform to make position relative to the center
        model.setTransform(TransformState.makePos(-centerPos))

        # Add lights to model
        for lightNp in info.getLightsForModel(modelId):
            lightNp.node().setShadowCaster(True, 512, 512)
            lightNp.reparentTo(model)
            scene.scene.setLight(lightNp)

        viewer = None

        try:
            viewer = Viewer(scene, interactive=False, shadowing=True)

            viewer.cam.setTransform(
                TransformState.makePos(LVector3f(0.5, 0.5, 3.0)))
            viewer.cam.lookAt(lightNp)

            for _ in range(20):
                viewer.step()
            time.sleep(1.0)

        finally:
            if viewer is not None:
                viewer.destroy()
                viewer.graphicsEngine.removeAllWindows()
Пример #4
0
    def testObjectWithViewer(self):

        scene = Scene()

        modelId = '83'
        modelFilename = os.path.join(TEST_SUNCG_DATA_DIR, "object",
                                     str(modelId),
                                     str(modelId) + ".egg")
        assert os.path.exists(modelFilename)
        model = loadModel(modelFilename)
        model.setName('model-' + str(modelId))
        model.show(BitMask32.allOn())

        objectsNp = scene.scene.attachNewNode('objects')
        objNp = objectsNp.attachNewNode('object-' + str(modelId))
        model.reparentTo(objNp)

        # Calculate the center of this object
        minBounds, maxBounds = model.getTightBounds()
        centerPos = minBounds + (maxBounds - minBounds) / 2.0

        # Add offset transform to make position relative to the center
        model.setTransform(TransformState.makePos(-centerPos))

        renderer = None
        viewer = None

        try:
            renderer = Panda3dRenderer(scene, shadowing=False)

            viewer = Viewer(scene, interactive=False)
            viewer.disableMouse()

            viewer.cam.setTransform(
                TransformState.makePos(LVecBase3(5.0, 0.0, 0.0)))
            viewer.cam.lookAt(model)

            for _ in range(20):
                viewer.step()
            time.sleep(1.0)

        finally:
            if renderer is not None:
                renderer.destroy()
            if viewer is not None:
                viewer.destroy()
                viewer.graphicsEngine.removeAllWindows()
Пример #5
0
    def testDebugObjectWithRender(self):

        scene = Scene()

        modelId = '83'
        modelFilename = os.path.join(TEST_SUNCG_DATA_DIR, "object",
                                     str(modelId),
                                     str(modelId) + ".egg")
        assert os.path.exists(modelFilename)
        model = loadModel(modelFilename)
        model.setName('model-' + str(modelId))
        model.hide()

        objectsNp = scene.scene.attachNewNode('objects')
        objNp = objectsNp.attachNewNode('object-' + str(modelId))
        model.reparentTo(objNp)

        # Calculate the center of this object
        minBounds, maxBounds = model.getTightBounds()
        centerPos = minBounds + (maxBounds - minBounds) / 2.0

        # Add offset transform to make position relative to the center
        model.setTransform(TransformState.makePos(-centerPos))

        renderer = None
        physics = None
        viewer = None

        try:
            renderer = Panda3dRenderer(scene, shadowing=False)
            physics = Panda3dBulletPhysics(scene, debug=True)

            viewer = Viewer(scene, interactive=False)
            viewer.disableMouse()

            viewer.cam.setTransform(
                TransformState.makePos(LVecBase3(5.0, 0.0, 0.0)))
            viewer.cam.lookAt(model)

            for _ in range(20):
                viewer.step()
            time.sleep(1.0)

        finally:
            self.hulkSmash(renderer, physics, viewer)
Пример #6
0
    def loadHouseFromJson(houseId, datasetRoot):

        filename = SunCgSceneLoader.getHouseJsonPath(datasetRoot, houseId)
        with open(filename) as f:
            data = json.load(f)
        assert houseId == data['id']
        houseId = str(data['id'])

        # Create new node for house instance
        houseNp = NodePath('house-' + str(houseId))

        objectIds = {}
        for levelId, level in enumerate(data['levels']):
            logger.debug('Loading Level %s to scene' % (str(levelId)))

            # Create new node for level instance
            levelNp = houseNp.attachNewNode('level-' + str(levelId))

            roomNpByNodeIndex = {}
            for nodeIndex, node in enumerate(level['nodes']):
                if not node['valid'] == 1: continue

                modelId = str(node['modelId'])

                if node['type'] == 'Room':
                    logger.debug('Loading Room %s to scene' % (modelId))

                    # Create new nodes for room instance
                    roomNp = levelNp.attachNewNode('room-' + str(modelId))
                    roomLayoutsNp = roomNp.attachNewNode('layouts')
                    roomObjectsNp = roomNp.attachNewNode('objects')

                    # Load models defined for this room
                    for roomObjFilename in reglob(
                            os.path.join(datasetRoot, 'room', houseId),
                            modelId + '[a-z].obj'):

                        # Convert extension from OBJ + MTL to EGG format
                        f, _ = os.path.splitext(roomObjFilename)
                        modelFilename = f + ".egg"
                        if not os.path.exists(modelFilename):
                            raise Exception(
                                'The SUNCG dataset object models need to be convert to Panda3D EGG format!'
                            )

                        # Create new node for object instance
                        objectNp = NodePath('object-' + str(modelId) + '-0')
                        objectNp.reparentTo(roomLayoutsNp)

                        model = loadModel(modelFilename)
                        model.setName('model-' + os.path.basename(f))
                        model.reparentTo(objectNp)
                        model.hide()

                    if 'nodeIndices' in node:
                        for childNodeIndex in node['nodeIndices']:
                            roomNpByNodeIndex[childNodeIndex] = roomObjectsNp

                elif node['type'] == 'Object':

                    logger.debug('Loading Object %s to scene' % (modelId))

                    # Instance identification
                    if modelId in objectIds:
                        objectIds[modelId] = objectIds[modelId] + 1
                    else:
                        objectIds[modelId] = 0

                    # Create new node for object instance
                    objectNp = NodePath('object-' + str(modelId) + '-' +
                                        str(objectIds[modelId]))

                    #TODO: loading the BAM format would be much more efficient
                    # Convert extension from OBJ + MTL to EGG format
                    objFilename = os.path.join(datasetRoot, 'object',
                                               node['modelId'],
                                               node['modelId'] + '.obj')
                    assert os.path.exists(objFilename)
                    f, _ = os.path.splitext(objFilename)
                    modelFilename = f + ".egg"
                    if not os.path.exists(modelFilename):
                        raise Exception(
                            'The SUNCG dataset object models need to be convert to Panda3D EGG format!'
                        )

                    model = loadModel(modelFilename)
                    model.setName('model-' + os.path.basename(f))
                    model.reparentTo(objectNp)
                    model.hide()

                    # 4x4 column-major transformation matrix from object coordinates to scene coordinates
                    transform = np.array(node['transform']).reshape((4, 4))

                    # Transform from Y-UP to Z-UP coordinate systems
                    #TODO: use Mat4.convertMat(CS_zup_right, CS_yup_right)
                    yupTransform = np.array([[1, 0, 0, 0], [0, 0, -1, 0],
                                             [0, 1, 0, 0], [0, 0, 0, 1]])

                    zupTransform = np.array([[1, 0, 0, 0], [0, 0, 1, 0],
                                             [0, -1, 0, 0], [0, 0, 0, 1]])

                    transform = np.dot(np.dot(yupTransform, transform),
                                       zupTransform)
                    transform = TransformState.makeMat(
                        LMatrix4f(*transform.ravel()))

                    # Calculate the center of this object
                    minBounds, maxBounds = model.getTightBounds()
                    centerPos = minBounds + (maxBounds - minBounds) / 2.0

                    # Add offset transform to make position relative to the center
                    objectNp.setTransform(
                        transform.compose(TransformState.makePos(centerPos)))
                    model.setTransform(TransformState.makePos(-centerPos))

                    # Get the parent nodepath for the object (room or level)
                    if nodeIndex in roomNpByNodeIndex:
                        objectNp.reparentTo(roomNpByNodeIndex[nodeIndex])
                    else:
                        objectNp.reparentTo(levelNp)

                    # Validation
                    assert np.allclose(mat4ToNumpyArray(
                        model.getNetTransform().getMat()),
                                       mat4ToNumpyArray(transform.getMat()),
                                       atol=1e-6)

                    objectNp.setTag('model-id', str(modelId))
                    objectNp.setTag('level-id', str(levelId))
                    objectNp.setTag('house-id', str(houseId))

                elif node['type'] == 'Ground':

                    logger.debug('Loading Ground %s to scene' % (modelId))

                    # Create new nodes for ground instance
                    groundNp = levelNp.attachNewNode('ground-' + str(modelId))
                    groundLayoutsNp = groundNp.attachNewNode('layouts')

                    # Load model defined for this ground
                    for groundObjFilename in reglob(
                            os.path.join(datasetRoot, 'room', houseId),
                            modelId + '[a-z].obj'):

                        # Convert extension from OBJ + MTL to EGG format
                        f, _ = os.path.splitext(groundObjFilename)
                        modelFilename = f + ".egg"
                        if not os.path.exists(modelFilename):
                            raise Exception(
                                'The SUNCG dataset object models need to be convert to Panda3D EGG format!'
                            )

                        objectNp = NodePath('object-' + str(modelId) + '-0')
                        objectNp.reparentTo(groundLayoutsNp)

                        model = loadModel(modelFilename)
                        model.setName('model-' + os.path.basename(f))
                        model.reparentTo(objectNp)
                        model.hide()

                else:
                    raise Exception('Unsupported node type: %s' %
                                    (node['type']))

        scene = Scene()
        houseNp.reparentTo(scene.scene)

        # Recenter objects in rooms
        for room in scene.scene.findAllMatches('**/room*'):

            # Calculate the center of this room
            minBounds, maxBounds = room.getTightBounds()
            centerPos = minBounds + (maxBounds - minBounds) / 2.0

            # Add offset transform to room node
            room.setTransform(TransformState.makePos(centerPos))

            # Add recentering transform to all children nodes
            for childNp in room.getChildren():
                childNp.setTransform(TransformState.makePos(-centerPos))

        # Recenter objects in grounds
        for ground in scene.scene.findAllMatches('**/ground*'):

            # Calculate the center of this ground
            minBounds, maxBounds = ground.getTightBounds()
            centerPos = minBounds + (maxBounds - minBounds) / 2.0

            # Add offset transform to ground node
            ground.setTransform(TransformState.makePos(centerPos))

            # Add recentering transform to all children nodes
            for childNp in ground.getChildren():
                childNp.setTransform(TransformState.makePos(-centerPos))

        return scene
Пример #7
0
    def testRenderSimpleCubeRoom(self):

        samplingRate = 16000.0
        scene = Scene()
        hrtf = CipicHRTF(os.path.join(TEST_DATA_DIR, 'hrtf', 'cipic_hrir.mat'),
                         samplingRate)

        viewer = Viewer(scene, interactive=False)

        # Define a simple cube (10 x 10 x 10 m) as room geometry
        roomSize = 10.0
        modelId = 'room-0'
        modelFilename = os.path.join(TEST_DATA_DIR, 'models', 'cube.egg')
        layoutNp = scene.scene.attachNewNode('layouts')
        objectNp = layoutNp.attachNewNode('object-' + modelId)
        objectNp.setTag('acoustics-mode', 'obstacle')
        model = loadModel(modelFilename)
        model.setName('model-' + modelId)
        model.setTransform(TransformState.makeScale(roomSize))
        model.setRenderModeWireframe()
        model.reparentTo(objectNp)
        objectNp.setPos(LVecBase3f(0.0, 0.0, 0.0))

        # Define a sound source
        sourceSize = 0.25
        modelId = 'source-0'
        modelFilename = os.path.join(TEST_DATA_DIR, 'models', 'sphere.egg')
        objectsNp = scene.scene.attachNewNode('objects')
        objectNp = objectsNp.attachNewNode('object-' + modelId)
        objectNp.setTag('acoustics-mode', 'source')
        model = loadModel(modelFilename)
        model.setName('model-' + modelId)
        model.setTransform(TransformState.makeScale(sourceSize))
        model.reparentTo(objectNp)
        objectNp.setPos(LVecBase3f(0.0, 0.0, 0.0))

        acoustics = EvertAcoustics(scene,
                                   hrtf,
                                   samplingRate,
                                   maximumOrder=3,
                                   materialAbsorption=False,
                                   frequencyDependent=False,
                                   debug=True)

        # Attach sound to object
        filename = os.path.join(TEST_DATA_DIR, 'audio', 'toilet.ogg')
        sound = EvertAudioSound(filename)
        acoustics.attachSoundToObject(sound, objectNp)

        acoustics.step(0.1)
        center = acoustics.world.getCenter()
        self.assertTrue(
            np.allclose(acoustics.world.getMaxLength() / 1000.0, roomSize))
        self.assertTrue(
            np.allclose([center.x, center.y, center.z], [0.0, 0.0, 0.0]))
        self.assertTrue(acoustics.world.numElements() == 12)
        self.assertTrue(acoustics.world.numConvexElements() == 12)

        # Configure the camera
        # NOTE: in Panda3D, the X axis points to the right, the Y axis is forward, and Z is up
        mat = np.array([
            0.999992, 0.00394238, 0, 0, -0.00295702, 0.750104, -0.661314, 0,
            -0.00260737, 0.661308, 0.75011, 0, 0.0, -25.0, 22, 1
        ])
        mat = LMatrix4f(*mat.ravel())
        viewer.cam.setMat(mat)

        agentNp = scene.agents[0]
        agentNp.setPos(
            LVecBase3f(0.25 * roomSize, -0.25 * roomSize, 0.3 * roomSize))
        for _ in range(10):
            viewer.step()
        time.sleep(1.0)

        agentNp.setPos(
            LVecBase3f(0.35 * roomSize, -0.35 * roomSize, 0.4 * roomSize))
        for _ in range(10):
            viewer.step()
        time.sleep(1.0)

        agentNp.setPos(
            LVecBase3f(-0.25 * roomSize, 0.25 * roomSize, -0.3 * roomSize))
        for _ in range(10):
            viewer.step()
        time.sleep(1.0)

        # Calculate and show impulse responses
        impulse = acoustics.calculateImpulseResponse(objectNp.getName(),
                                                     agentNp.getName())

        fig = plt.figure()
        plt.plot(impulse.impulse[0], color='b', label='Left channel')
        plt.plot(impulse.impulse[1], color='g', label='Right channel')
        plt.legend()
        plt.show(block=False)
        time.sleep(1.0)
        plt.close(fig)

        acoustics.destroy()
        viewer.destroy()
        viewer.graphicsEngine.removeAllWindows()