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)
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)
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()
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()
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)
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
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()