Advertisement
shubhamgoyal

VirtualWorld.py (static object flattenStrong() version)

Jul 18th, 2012
123
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 15.07 KB | None | 0 0
  1. #!/usr/bin/env python
  2. #
  3. # Copyright (c) 2011-2012 Wiktor Starzyk, Faisal Z. Qureshi
  4. #
  5. # This file is part of the Virtual Vision Simulator.
  6. #
  7. # The Virtual Vision Simulator is free software: you can
  8. # redistribute it and/or modify it under the terms
  9. # of the GNU General Public License as published by
  10. # the Free Software Foundation, either version 3 of the License,
  11. # or (at your option) any later version.
  12. #
  13. # The Virtual Vision Simulator is distributed in the hope
  14. # that it will be useful, but WITHOUT ANY WARRANTY;
  15. # without even the implied warranty of MERCHANTABILITY or
  16. # FITNESS FOR A PARTICULAR PURPOSE.  See the
  17. # GNU General Public License for more details.
  18. #
  19. # You should have received a copy of the GNU General Public License
  20. # along with the Virtual Vision Simulator.  
  21. # If not, see <http://www.gnu.org/licenses/>.
  22. #
  23.  
  24.  
  25. import sys, os
  26. import logging
  27.  
  28. from math import tan, radians
  29.  
  30. from direct.showbase.ShowBase import ShowBase
  31. from direct.gui.OnscreenText import OnscreenText as OST
  32. from direct.task import Task
  33.  
  34. from pandac.PandaModules import AntialiasAttrib, ClockObject, TextNode
  35. from pandac.PandaModules import Vec3, VBase4
  36. from pandac.PandaModules import Camera, OrthographicLens
  37. from pandac.PandaModules import loadPrcFileData
  38. from pandac.PandaModules import WindowProperties
  39. from pandac.PandaModules import FrameBufferProperties
  40. from pandac.PandaModules import GraphicsPipe
  41. from pandac.PandaModules import NodePath
  42.  
  43. from builders.object_builder import ObjectBuilder
  44. from builders.pedestrian_builder import PedestrianBuilder
  45. from builders.light_builder import LightBuilder
  46. from builders.camera_builder import PandaCameraBuilder
  47. from file_io.scene_file import *
  48. from file_io.pedestrian_file import *
  49.  
  50. from simulator.model import Model
  51. from simulator.model import DIRECTIONALLIGHT
  52. from simulator.panda3d.controller import Controller
  53.  
  54. WIDTH = 1200
  55. HEIGHT = 600
  56.  
  57. loadPrcFileData("", "win-size %s %s" % (WIDTH, HEIGHT))
  58. loadPrcFileData("", "texture-anisotropic-degree 10")
  59.  
  60. LIGHTS_PER_OBJECT = 4
  61.  
  62. PTZ_CAMERA = 1
  63. WIDE_FOV_CAMERA = 2
  64.  
  65. MANUAL_CAMERA = False
  66.  
  67.  
  68. def Length(a, b):
  69.     ax, ay, az = a
  70.     bx, by, bz = b
  71.     length = (ax-bx) ** 2 + (ay-by) ** 2
  72.     return length
  73.  
  74.  
  75. class VirtualWorld(ShowBase):
  76.  
  77.     def __init__(self, scene_file, pedestrian_file, dir, mode):
  78.         ShowBase.__init__(self)
  79.        
  80.         self.static_model = NodePath('static_models')
  81.         self.static_model.reparentTo(self.render)
  82.        
  83.         self.globalClock = ClockObject.getGlobalClock()
  84.         self.globalClock.setMode(ClockObject.MSlave)
  85.        
  86.         self.directory = dir
  87.         self.model = Model(dir)
  88.         self.loadScene(scene_file)
  89.         self.loadPedestrians(pedestrian_file)
  90.        
  91.         self.static_model.flattenStrong()
  92.        
  93.         #self.cam_label = OST("Top Down", pos=(0, 0.95), fg=(1,1,1,1),
  94.         #                     scale=0.05, mayChange=True)
  95.         #self.time_label = OST("Time: 0.0", pos=(-1.3, 0.95), fg=(1,1,1,1),
  96.         #                      scale=0.06, mayChange=True, align=TextNode.ALeft)
  97.                                        
  98.         #self.accept("arrow_right", self.changeCamera, [1])
  99.         #self.accept("arrow_left", self.changeCamera, [-1])
  100.         self.accept("escape", self.exit)
  101.         self.accept("aspectRatioChanged", self.setAspectRatio)
  102.         self.accept("window-event", self.windowChanged)
  103.        
  104.         #base.disableMouse()
  105.         lens = OrthographicLens()
  106.         lens.setFilmSize(1550, 1000)
  107.        
  108.         self.default_camera = render.attachNewNode(Camera("top down"))
  109.         self.default_camera.node().setLens(lens)
  110.         self.default_camera.setPosHpr(Vec3( -75, 0, 2200), Vec3(0, -90, 0))
  111.        
  112.         #self.new_window = base.openWindow()
  113.        
  114.         new_window_fbp = FrameBufferProperties.getDefault()
  115.         new_window_properties = WindowProperties.getDefault()
  116.         new_window = base.graphicsEngine.makeOutput(base.pipe, 'Top Down View Window', 0, new_window_fbp, new_window_properties, GraphicsPipe.BFRequireWindow)
  117.        
  118.         self.display_regions = []
  119.     self.display_regions.append(new_window.makeDisplayRegion())
  120.         self.display_regions.append(base.win.makeDisplayRegion(0, 0.32, 0.5, 1))
  121.         self.display_regions.append(base.win.makeDisplayRegion(0.34, 0.65, 0.5, 1))
  122.         self.display_regions.append(base.win.makeDisplayRegion(0.67, 1, 0.5, 1))
  123.         self.display_regions.append(base.win.makeDisplayRegion(0, 0.32, 0, 0.5))
  124.         self.display_regions.append(base.win.makeDisplayRegion(0.34, 0.65, 0, 0.5))
  125.         self.display_regions.append(base.win.makeDisplayRegion(0.67, 1, 0, 0.5))
  126.     self.display_regions[0].setCamera(self.default_camera)
  127.        
  128.         #self.setCamera(0)
  129.  
  130.         self.controller = Controller(self, mode)
  131.         self.taskMgr.add(self.updateCameraModules, "Update Camera Modules", 80)
  132.        
  133.         self.globalClock.setFrameTime(0.0)
  134.         self.width = WIDTH
  135.         self.height = HEIGHT
  136.  
  137.         props = WindowProperties( )
  138.         props.setTitle( 'Virtual Vision Simulator' )
  139.         base.win.requestProperties( props )
  140.        
  141.         render.analyze()
  142.        
  143.         """props_new_window = WindowProperties()
  144.        props_new_window.setTitle('Top Down View')
  145.        self.new_window.requestProperties(props_new_window)"""
  146.  
  147.  
  148.     def assign_display_region_to_camera(self):
  149.        
  150.         base.win.setClearColorActive(True)
  151.     base.win.setClearColor(VBase4(0, 0, 0, 1))
  152.        
  153.         for i in range(0, len(self.display_regions)):
  154.         display_region = self.display_regions[i]
  155.         display_region.setClearColor(VBase4(0, 0, 0, 1))
  156.         display_region.setClearColorActive(True)
  157.         display_region.setClearDepthActive(True)
  158.         if i == 0:
  159.         display_region.setCamera(self.default_camera)
  160.         else:
  161.         camera_list = self.model.getCameraList()
  162.         index = i - 1
  163.         if index < len(camera_list):
  164.             camera = camera_list[index]
  165.             camera_np = camera.getCameraNode()
  166.             display_region.setCamera(camera_np)
  167.        
  168.        
  169.     def getModel(self):
  170.         """
  171.        Returns the model that stores all of the cameras, pedestrians and
  172.        static objects in the scene.
  173.        """
  174.        
  175.         return self.model
  176.  
  177.  
  178.     def getController(self):
  179.         """
  180.        Returns a controller that is used to control the world time.
  181.        """
  182.         return self.controller
  183.  
  184.  
  185.     def getTime(self):
  186.         """
  187.        Returns the current time in the world.
  188.        """
  189.         return self.globalClock.getFrameTime()
  190.  
  191.  
  192.     def loadScene(self, scene_file):
  193.         """
  194.        Loads the static objects that make up the scene. Also loads the lights
  195.        that illuminate the scene and for performance implications, sets what
  196.        lights affect what objects.
  197.        """
  198.         if not os.path.exists(scene_file):
  199.             logging.error("The path '%s' does not exist" % scene_file)
  200.             sys.exit()
  201.         light_builder = LightBuilder(self)
  202.         object_builder = ObjectBuilder(self, self.directory)
  203.         parser = SceneFileParser(self.model, object_builder, light_builder)
  204.         parser.parse(scene_file)
  205.        
  206.         self.setUpLights()
  207.  
  208.  
  209.     def setUpLights(self):
  210.         # Set what lights illuminate what objects
  211.         light_list = self.model.getLightList()
  212.         static_objects = self.model.getObjectList()
  213.         for object in static_objects:
  214.             if object.hasLighting():
  215.                 model_root = object.getModel().getChildren()[0]
  216.                 children = model_root.getChildren()
  217.                 for child in children:
  218.                     light_map = {}
  219.                     for index, light in enumerate(light_list):
  220.                         distance = Length(child.getPos(render), light.getPos())
  221.                         half_fov = light.node().getLens().getFov()[0] / 2.0
  222.                         height = light.getPos()[2]
  223.                         radius = height * tan(radians(half_fov))
  224.                         if distance > radius ** 2 + 2500 + 10:
  225.                             continue
  226.                         if distance not in light_map:
  227.                             light_map[distance] = [index]
  228.                         else:
  229.                             light_map[distance].append(index)
  230.  
  231.                     sorted_lights = sorted(light_map.keys())
  232.                     light_count = 0
  233.                     for key in sorted_lights:
  234.                         for i in light_map[key]:
  235.                             child.setLight(light_list[i])
  236.                             light_count += 1
  237.                             if light_count > LIGHTS_PER_OBJECT:
  238.                                 break
  239.                         if light_count > LIGHTS_PER_OBJECT:
  240.                             break
  241.                     child.flattenStrong()
  242.        
  243.         # Apply a directional light to the static models        
  244.         light_list = self.model.getLightList(DIRECTIONALLIGHT)
  245.         if light_list:
  246.             for object in static_objects:
  247.                 if object.hasLighting():
  248.                     model_root = object.getModel().getChildren()[0]
  249.                     model_root.setLight(light_list[0])
  250.  
  251.         render.setShaderAuto()
  252.         render.setAntialias(AntialiasAttrib.MLine)
  253.  
  254.  
  255.     def loadPedestrians(self, pedestrian_file):
  256.         """Loads the pedestrians into the scene."""
  257.         if not os.path.exists(pedestrian_file):
  258.             logging.error("The path '%s' does not exist" % pedestrian_file)
  259.             sys.exit()
  260.         pedestrian_builder = PedestrianBuilder(self, "../media/characters/")
  261.         parser = PedestrianFileParser(self.model, pedestrian_builder)
  262.         parser.parse("../media/characters/pedestrians.xml")
  263.         parser.parse(pedestrian_file)
  264.  
  265.  
  266.     def addCamera(self, config):
  267.         """
  268.        This method is used to add a new panda camera to the world. The panda
  269.        camera is returned so that it can be linked with a camera module.
  270.        """
  271.         type = config.type
  272.         cam_builder = PandaCameraBuilder(self)
  273.         if type == WIDE_FOV_CAMERA:
  274.             pass
  275.         else:
  276.             camera = cam_builder.buildPandaPTZCamera(config)
  277.             self.model.addCamera(camera)
  278.         return camera
  279.  
  280.  
  281.     def setAspectRatio(self):
  282.         """
  283.        This method is called when the aspect ratio of the window changes.
  284.        It updates the aspect ratios of all the cameras.
  285.        """
  286.         width = base.win.getXSize()
  287.         height = base.win.getYSize()
  288.         ratio = self.camLens.getAspectRatio()
  289.         camera_list = self.model.getCameraList()
  290.         for camera in camera_list:
  291.             camera.setAspectRatio(ratio)
  292.             camera.setImageSize(width, height)
  293.  
  294.         self.default_camera.node().getLens().setAspectRatio(ratio)
  295.         r =  width / float(height)
  296.         #self.time_label.setPos(-r, 0.95)
  297.  
  298.  
  299.     def changeCamera(self, num):
  300.         """
  301.        This method is used to toggle the camera that is viewed in the main
  302.        window. Typically num is either 1 or -1 denoting whether to toggle up
  303.        or down the camera list.
  304.        """
  305.         number = self.cur_camera + 1 + num
  306.         num_cameras = len(self.model.getCameraList())
  307.         if number > num_cameras:
  308.             number = 0
  309.         elif number < 0:
  310.             number = num_cameras
  311.         self.setCamera(number)
  312.  
  313.  
  314.     def setCamera(self, num):
  315.         """
  316.        This method sets which cameras view is shown in the panda3d window.
  317.        """
  318.         if MANUAL_CAMERA:
  319.             self.cur_camera = num -1
  320.             return
  321.        
  322.         self.display_region.setClearColor(VBase4(0, 0, 0, 1))
  323.         self.display_region.setClearColorActive(True)
  324.         self.display_region.setClearDepthActive(True)
  325.         if num == 0:
  326.             self.cur_camera = -1
  327.             self.display_region.setCamera(self.default_camera)
  328.             self.cam_label.setText("Top Down")
  329.         else:
  330.             camera_list = self.model.getCameraList()
  331.             index = num - 1
  332.             if index < len(camera_list):
  333.                 self.cur_camera = index
  334.                 camera = camera_list[index]
  335.                 camera_np = camera.getCameraNode()
  336.                 self.display_region.setCamera(camera_np)
  337.                 name = camera.getName()
  338.                 status_label = camera.getStatusLabel()
  339.                 label = "%s: %s" %(name, status_label)
  340.                 self.cam_label.setText(label)
  341.  
  342.  
  343.     def step(self, increment):
  344.         """
  345.        This method updates the world by one time step.
  346.        """
  347.         if increment:
  348.             new_time = self.globalClock.getFrameTime() + increment
  349.         else:
  350.             new_time = self.globalClock.getRealTime()
  351.            
  352.         self.globalClock.setFrameTime(new_time)
  353.         #self.time_label.setText("Time: %.2f" % new_time)
  354.        
  355.         self.updateActors()
  356.         self.updateCameras()
  357.  
  358.  
  359.     def updateActors(self):
  360.         """
  361.        This method updates the pedestrians in the scene by calling their update
  362.        functions.
  363.        """
  364.         pedestrians = self.model.getPedestrianList()
  365.         time = self.getTime()
  366.         for pedestrian in pedestrians:
  367.             if pedestrian.isActive(time):
  368.                 pedestrian.update(time)
  369.  
  370.  
  371.     def updateCameras(self):
  372.         """
  373.        This method updates the panda cameras which are used to provide the
  374.        higher level camera modules with rendered images of the scene. There
  375.        is one panda camera for each camera module.
  376.        """
  377.         time = self.getTime()
  378.         camera_list = self.model.getCameraList()
  379.         for camera in camera_list:
  380.             camera.update(time)
  381.        
  382.         """if self.cur_camera != -1:
  383.            cur_camera = camera_list[self.cur_camera]
  384.            if cur_camera.statusChanged():
  385.                name = cur_camera.getName()
  386.                status_label = cur_camera.getStatusLabel()
  387.                label = "%s: %s" %(name, status_label)
  388.                self.cam_label.setText(label)"""
  389.  
  390.  
  391.     def updateCameraModules(self, task):
  392.         """
  393.        This method updates the camera modules by calling their update function.
  394.        This allows the camera modules to process messages and complete any
  395.        tasks that were assigned to them.
  396.        """
  397.         time = self.getTime()
  398.         for camera in self.model.getCameraModules():
  399.             camera.update(time)
  400.         return Task.cont
  401.  
  402.  
  403.     def windowChanged(self, window):
  404.         """
  405.        This function is called when the window is modified. It updates the
  406.        image size used by the cameras when getting the rendered image from the
  407.        texture.
  408.        """
  409.         wp = window.getProperties()
  410.         width = wp.getXSize()
  411.         height = wp.getYSize()
  412.         if width != self.width or height != self.height:
  413.             self.width = width
  414.             self.height = height
  415.             camera_list = self.model.getCameraList()
  416.             for camera in camera_list:
  417.                 camera.setImageSize(width, height)
  418.         self.windowEvent(window)
  419.  
  420.  
  421.     def exit(self):
  422.         sys.exit()
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement