class Module(Component): implements(IModule) def __init__(self, config): self.name = config['name'] self.type = type(self) self._depends = [] self._running = False event.send('MODULE_CREATED', self) ModuleManager.get().register(self) def start(self): self._running = True event.send('MODULE_START', self) def backgrounded(self): self._running def pause(self): self._running = False event.send('MODULE_PAUSE', self) def update(self, time_since_last_update): pass def shutdown(self): self.pause() event.send('MODULE_SHUTDOWN', self)
class Camera(Component): implements(ICamera) def __init__(self, name, scene, position, offset, orientation, near_clip=0.5): offset = sim.OgreVector3(offset) self._camera = scene.scene_mgr.createCamera(name) self._camera.nearClipDistance = near_clip self._camera.setFixedYawAxis(False) # Place the camera out in front at the needed distance self._camera.position = (offset.length(), 0, 0) # Make it face back toward zero self._camera.lookAt((0, 0, 0)) # Account for the odd up vector difference between our and Ogre's # default coordinate systems self._camera.roll(Ogre.Degree(90)) # Apply custom rotation if desired self._camera.rotate(orientation) # Allows easier movement of camera self._node = scene.scene_mgr.getRootSceneNode().createChildSceneNode() self._node.position = (0, 0, 0) self._node.attachObject(self._camera) # Rotate the node to place the camera in its desired offset position # Do the in plane rotation, then up rotation to keep the cameras up # facing the proper way inPlane = Ogre.Vector3(offset.x, offset.y, 0) if inPlane.length() != 0: self._node.rotate(self._camera.position.getRotationTo(inPlane)) else: # The camera is directly above or below self._camera.roll(Ogre.Degree(180)) inPlane = Ogre.Vector3.UNIT_X self._node.rotate(inPlane.getRotationTo(offset), Ogre.Node.TS_WORLD) # position camera self._node.position = position #ICamera methods class camera(cls_property): def fget(self): return self._camera class node(cls_property): def fget(self): return self._node
class Sub2Module(module.Module): core.implements(module.IModule) def __init__(self, config): self.config = config # Verify that super module is loaded assert_module_count(SuperModule, 1) module.Module.__init__(self, config)
class SuperModule(module.Module): core.implements(module.IModule) def __init__(self, config): self.config = config # Verify that sub modules are not yet loaded assert_module_count(Sub1Module, 0) assert_module_count(Sub2Module, 0) module.Module.__init__(self, config)
class SimPanelProvider(Component): implements(IPanelProvider) def getPanels(self, subsystems, parent): # This dummy window holds the rendering context to make sure the user # doesn't close the window containing it dummy = wxOgre(None, parent, -1, wx.DefaultPosition, wx.DefaultSize, 0, wx.DefaultValidator, "dummy") dummy.Show(False) # Our real window main = wxOgre(None, parent, -1, wx.DefaultPosition, wx.DefaultSize, 0, wx.DefaultValidator, "main") main_info = wx.aui.AuiPaneInfo().Name("main").Caption( "Simulation").Center() main._input_forwarder = InputForwarder(Simulation.get().input_system) main._input_forwarder.forward_window(main) return [(main_info, main)]
class StartingGate(object): core.implements(ICompetitionObjective) def __init__(self): # Gate Releated Members self._through_gate = False self._gate_entered_velocity = None def _entered_gate(self, vehicle): self._gate_entered_velicty = vehicle.velocity def _left_gate(self, vehicle): if not self._through_gate: velA = self._gate_entered_velicty velB = vehicle.velocity angle = math.acos( (velA.absDotProduct(velB)) / (velA.length() * velB.length())) if math.degrees(angle) < 10: print 'Straight Through!' self._through_gate = True
class KMLRobotLoader(core.Component, KMLLoader): """ Loads a robot from our structured KML Loader """ core.implements(IRobotLoader) iface_map = {'Thruster': IThruster} @staticmethod def can_load(robot_data): try: if robot_data.endswith('.rml') and len(robot_data) > 4: return True return False except AttributeError: return False def load(self, robot, scene, robot_data): config = yaml.load(file(robot_data)) rbt_node = config['Robot'] # Load main part robot.name = rbt_node['name'] main_part = Part() main_part.load((scene, None, rbt_node)) # We don't want the body to stop responding to forces main_part._body.setAutoFreeze(False) robot._main_part = main_part # Load child parts parts = rbt_node.get('Parts', None) if parts is not None: for part_node in parts.itervalues(): iface_name, class_name = part_node['type'] iface = self.iface_map[iface_name] part = core.Component.create(iface, class_name) part.load((scene, robot._main_part, part_node))
class Visual(Object): implements(IVisual, IKMLStorable) _plane_count = 0 @two_step_init def __init__(self): self._node = None Object.__init__(self) def init(self, parent, name, scene, mesh, material, position=Ogre.Vector3.ZERO, orientation=Ogre.Quaternion.IDENTITY, scale=Ogre.Vector3(1, 1, 1)): Object.init(parent, name) Visual._create(self, scene, mesh, material, position, orientation, scale) def _create(self, scene, mesh, material, position, orientation, scale): # Create the graphical representation of the object entity = scene.scene_mgr.createEntity(self.name, mesh) if material is not None: entity.setMaterialName(material) # Attach graphical entity to a new node in the scene graph self._node = scene.scene_mgr.getRootSceneNode().createChildSceneNode() self._node.attachObject(entity) # Apply scalling and normalized normals if object is actually scalled if scale != Ogre.Vector3(1, 1, 1): self._node.setScale(scale) self._node.position = position self._node.orientation = orientation class position(core.cls_property): def fget(self): return self._node.position class orientation(core.cls_property): def fget(self): return self._node.orientation class visible(core.cls_property): def fset(self, value): self._node.setVisible(value) def fget(self): return self._node.isVisible() # IStorable Methods def load(self, data_object): """ @type data_object: tuple @param data_object: (scene, parent, kml_node) """ scene, parent, node = data_object # Load Object based values Object.load(self, (parent, node)) gfx_node = node['Graphical'] mesh = gfx_node['mesh'] material = gfx_node.get('material', None) scale = sim.OgreVector3(gfx_node.get('scale', Ogre.Vector3(1, 1, 1))) # Handle special mesh generation if mesh.startswith('PLANE'): if ':' in mesh: mesh = mesh.split(':')[1] else: mesh = 'Plane' + str(Visual._plane_count) norm = gfx_node['normal'] width = gfx_node['width'] height = gfx_node['height'] upvec = gfx_node.get('upvec', Ogre.Vector3.UNIT_Y) utile = gfx_node.get('utile', 1) vtile = gfx_node.get('vtile', 1) plane = Ogre.Plane(norm, 0) group_name = gfx_node.get( 'group', Ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME) xsegments = int(width) ysegments = int(height) Ogre.MeshManager.getSingletonPtr().createPlane(mesh, \ group_name, plane, width, height, upVector = upvec, uTile = utile, vTile = vtile, xsegments = xsegments, ysegments = ysegments) Visual._plane_count += 1 # Orientation defaults: IDENTITY, Position: (0,0,0) position, orientation = parse_position_orientation(node) Visual._create(self, scene, mesh, material, position, orientation, scale) # Check visibility if not gfx_node.get('visible', True): self._node.setVisible(False) def save(self, data_object): raise "Not yet implemented"
class Trigger(Body, OgreNewt.ContactCallback): core.implements(ITrigger, IWorldUpdateListener) _trigger_count = 0 @two_step_init def __init__(self): self._contact_events = {} self._contactors = {} Body.__init__(self) OgreNewt.ContactCallback.__init__(self) def init(self, parent, name, scene, contact_properties, shape_type, shape_props, position = Ogre.Vector3.ZERO, orientation = Ogre.Quaternion.IDENTITY): """ @param contact_properties: tuple (string, string, string) @type contact_properties: The first item is the material to contact with the second is the enter event type, and the third item is the leave event type. """ Body.init(self, None, name, scene, 0, shape_type, shape_props, position, orietnation) Trigger._create(self, scene, contact_properties) # IWorldUpdateListener methods def pre_update(self): pass def post_update(self): new_contactors = {} for contact_info, contacting in self._contactors.iteritems(): if contacting: new_contactors[contact_info] = False else: contactor, material = contact_info leave_event = self._contact_events[material][1] if leave_event is not None: event.post(leave_event, contactor) self._contactors.clear() self._contactors.update(new_contactors) def _create(self, scene, contact_properties): """ """ # Nobody has given us a material yet, autogenerate one if self._material is None: self._material = 'Trigger' + str(Trigger._trigger_count) Trigger._trigger_count += 1 material_id = scene.world.get_material_id(self._material) self._body.setMaterialGroupID(material_id) # Setup our selves as the callback for all the material pairs # we are supposed to trigger events for for material, enter_event, leave_event in contact_properties: # Make ourselves the contact callback for this material pair pair = scene.world.get_material_pair(self.material, material) pair.setContactCallback(self) # Store what to do when bodies enter and leave the area with this # material self._contact_events[material] = (enter_event, leave_event) # Register our self to be notified before and after phyiscs updates scene.world.add_update_listener(self) def load(self, data_object): Body.load(self, data_object) scene, parent, node = data_object # Extract contact information physical_node = node['Physical'] contact_node = physical_node.get('contact_information', None) if contact_node is None: raise PhysicsError, "Trigger must a have 'contact_information' node" contact_properties = [] for contact_material, contact_events in contact_node.iteritems(): enter_event = contact_events[0] leave_event = None #print type(contact_events) if type(contact_events) is not list: raise PhysicsError, "Contact events must be a list" if len(contact_events) > 1: leave_event = contact_events[1] contact_properties.append((contact_material, enter_event, leave_event)) self._create(scene, contact_properties) def save(self, data_object): raise "Not yet implemented" # OgreNewt.ContactCallback Method def userProcess(self): """ Extract which body is which, send off """ # Determin which body is the trigger, and which is the contacting object me = self.m_body0.getUserData(); contactor = self.m_body1.getUserData(); # Our guess was wrong if ITrigger.providedBy(contactor): me, contactor = contactor, me # swap values # Store the contact information for latter event firing contact_material = contactor.material contact_info = (contactor, contact_material) # If this is the first time we are contacting post the event if not self._contactors.has_key(contact_info): enter_event = self._contact_events[contact_material][0] if enter_event is not None: event.post(enter_event, contactor) self._contactors[contact_info] = True # Ignore all contacts return 0
class Body(Object): core.implements(IBody, IKMLStorable) _tree_mesh_hack = 0 @two_step_init def __init__(self): """ If you call this, make sure to call create, before using the object """ self._force = Ogre.Vector3(0,0,0) self._omega = Ogre.Vector3(0,0,0) self._torque = Ogre.Vector3(0,0,0) self._gravity = defaults.gravity self._local_force = [] self._global_force = [] self._buoyancy_plane = None self._body = None self._material = None self._old_velocity = Ogre.Vector3.ZERO self._previous_omega = Ogre.Vector3.ZERO Object.__init__(self) def init(self, parent, name, scene, shape_type, shape_props, mass, center_of_mass = Ogre.Vector3.ZERO, inertia = None, position = Ogre.Vector3.ZERO, orientation = Ogre.Quaternion.IDENTITY): """ @type scene: ram.sim.scene.Scene @param scene: The scene to create the body in @type shape_type: str @param shape_type: Denotes, the type of shape, like 'box' or 'sphere' @type shape_props: Dict @param shape_props: Maps paramater name to value for the shapes constructor. """ Object.init(self, parent, name) Body._create(self, scene, shape_type, shape_props, mass, center_of_mass, inertia, position, orientation) def _create(self, scene, shape_type, shape_props, mass, center_of_mass, inertia, position, orientation): # Create Collision Object # TODO: Improve collision support col = None if shape_type == 'box': size = sim.OgreVector3(shape_props['size']) col = OgreNewt.Box(scene.world, size) elif shape_type == 'cylinder': col = OgreNewt.Cylinder(scene.world, shape_props['radius'], shape_props['height']) elif shape_type == 'mesh': # Fix this by later (we shouldn't need a node!!!) name = 'TREE_HACK' + str(Body._tree_mesh_hack) Body._tree_mesh_hack += 1 mesh_name = shape_props['mesh_name'] scale = sim.OgreVector3(shape_props.get('mesh_scale', Ogre.Vector3(1,1,1))) tree_ent = scene.scene_mgr.createEntity(name, mesh_name) # Need extra node, for scaling error temp_node = \ scene.scene_mgr.getRootSceneNode().createChildSceneNode() temp_node.attachObject(tree_ent) temp_node.setVisible(False) temp_node.setScale(scale) col = OgreNewt.TreeCollision(scene.world, temp_node, True) # When this works remove and destory our node temporary node!! else: raise PhysicsError, '"%s" is not a valid shape type' % shape_type self._body = scene.world.create_body(self, col, mass, center_of_mass, inertia, position, orientation) # IStorable Methods def load(self, data_object): """ @type data_object: tuple @param data_object: (scene, parent, kml_node) """ scene, parent, node = data_object # Load Object based values Object.load(self, (parent, node)) physical_node = node.get('Physical', None) if physical_node is None: msg = 'Object "%s" needs a "Phsyical" section' % node['name'] raise PhysicsError(msg) # Find shape type and its properties shape_node = physical_node.get('Shape', None) if shape_node is None: msg = 'Object "%s" needs a "Physical.Shape" section' % node['name'] raise PhysicsError(msg) shape_type = shape_node['type'].lower() shape_props = {} for param, value in shape_node.iteritems(): if param != 'type': shape_props[param] = value scale = shape_node.get('mesh_scale', None) if scale is not None: shape_props['mesh_scale'] = scale else: gfx_node = node.get('Graphical', {}) shape_props['mesh_scale'] = gfx_node.get('scale', [1,1,1]) # Grab and validate Mass mass = physical_node.get('mass', 0) if (type(mass) is not int) and (type(mass) is not float): raise SimulationError('Mass must be an interger of float') position, orientation = parse_position_orientation(node) # Inertia and COM center_of_mass = physical_node.get('center_of_mass',Ogre.Vector3.ZERO) inertia = physical_node.get('inertia', None) Body._create(self, scene, shape_type, shape_props, mass, center_of_mass, inertia, position, orientation) # Small hack, this should be integrated integrated better # I should probably reduce the number of constructor parameters as well material = physical_node.get('material', None) if material is not None: self._material = material material_id = scene.world.get_material_id(material) self._body.setMaterialGroupID(material_id) def save(self, data_object): raise "Not yet implemented" @staticmethod def _make_force_pos_pair(force, pos): return (sim.OgreVector3(force), sim.OgreVector3(pos)) # IBody Methods class material(core.cls_property): def fget(self): return self._material class gravity(core.cls_property): def fget(self): return self._gravity def fset(self, gravity): self._gravity = sim.OgreVector3(gravity) class position(core.cls_property): def fget(self): return self._body.getPositionOrientation()[0] class orientation(core.cls_property): def fget(self): return self._body.getPositionOrientation()[1] class velocity(core.cls_property): def fget(self): return self._body.getVelocity() class omega(core.cls_property): def fget(self): return self._body.getOmega() class acceleration(core.cls_property): def fget(self): return self._old_velocity - self.velocity class angular_accel(core.cls_property): def fget(self): return self._previous_omega - self.omega # Force Applying Methods class force(core.cls_property): def fget(self): return self._force def fset(self, force): self._force = sim.OgreVector3(force) def add_local_force(self, force, pos): self._local_force.append(Body._make_force_pos_pair(force, pos)) def set_local_force(self, force, pos): if (force is None) and (pos is None): self._local_force = [] else: self._local_force = [Body._make_force_pos_pair(force, pos)] def get_local_forces(self): return self._local_force def add_global_force(self, force, pos): self._global_force.append(Body._make_force_pos_pair(force, pos)) def set_global_force(self, force, pos): if (force is None) and (pos is None): self._global_force = [] else: self._global_force = [Body._make_force_pos_pair(force, pos)] def get_global_forces(self): return self._global_force # Apply Torque class torque(core.cls_property): def fget(self): return self._torque def fset(self, torque): self._torque = sim.OgreVector3(torque) def set_buoyancy(self, normal): """ @type normal: Ogre.Vector3 @param normal: The normal of the buoyancy plane. If none, the object will not be buoyanct """ if normal is not None: self._buoyancy_plane = Ogre.Plane(normal, (0,0,0)) else: self._buoyancy_plane = None def get_buoyancy_plane(self): return self._buoyancy_plane
class Object(core.Component): core.implements(IObject, IKMLStorable) @staticmethod def assert_object_implementer(obj): if not IObject.providedBy(obj): raise SimulationError('Object must implement IObject interface') @two_step_init def __init__(self): self._children = {} self.parent = None self.name = None def init(self, parent, name): Object._create(self, parent, name) def update(self, time_since_last_update): for child in self._children.itervalues(): child.update(time_since_last_update) def _create(self, parent, name): self._children = {} self.parent = parent self.name = name if self.parent is not None: self.assert_object_implementer(parent) self.parent.add_child(self) # IStorable Methods # IStorable Methods def load(self, data_object): """ @type data_object: tuple @param data_object: (parent, kml_node) """ parent, node = data_object Object._create(self, parent, node['name']) def save(self, data_object): raise "Not yet implemented" def get_child(self, name): if not self._children.has_key(name): raise SimulationError('Object does not have child %s' % name) return self._children[name] def add_child(self, child): self.assert_object_implementer(child) self._children[child.name] = child def remove_child(self, child): actual_child = child # If its not an implementer of IObject if not IObject.providedBy(child): actual_child = self.get_child(child) del self._children[actual_child.name]
class C2(core.Component): core.implements(I1) def my_func(self, arg1): pass
class C1(core.Component): core.implements(I1)
class Simulation(Singleton, Module): """ The root object of the simulation, this is a singleton object just use 'Simulation.get()' to access it. """ implements(IModule) #@log_init(defaults.simulation_log_config) def init(self, config={}): self._ogre_root = None self._scenes = {} self._config = config self._debug = config.get('debugOutput', False) self._graphics_init(config.get('Graphics', {})) self.input_system = InputSystem(config.get('Input', {})) config['name'] = 'Simulation' Module.__init__(self, config) # def __del__(self): # # Ensure proper of C++ destructors # # TODO: Ensure I have to do this, I might be able to ignore this # del self._scenes # del self._ogre_root #@log('* * * Beginning shutdown', '* * * Shutdown complete') def shutdown(self): self._debug_print('Beginning shutdown') Module.pause(self) # Close all scenes self._debug_print('Destroying Scenes') for scene in self._scenes.itervalues(): scene.destroy() # Release references then shutdown self._debug_print('Releasing scene references') del self._scenes # System seems to crash if this stuff happens #self._debug_print('Shutting down Ogre') #self._ogre_root.shutdown() #self._debug_print('Shutting down Complete') #del self._ogre_root #self._debug_print('Reference deleted') #del self._ogre_logger #self._debug_print('Logger deleted') def update(self, time_since_last_update): """ Updates all simulation components with the given timesteps @type time_since_last_update: a decimal number @param time_since_last_update: name says it all """ if self._running: Ogre.WindowEventUtilities.messagePump() for scene in self._scenes.itervalues(): scene.update(time_since_last_update) event.send('SIM_UPDATE', time_since_last_update) return self._running def iterscenes(self): """ Iterate over the scenes: (name, scene) """ for name, scene in self._scenes.iteritems(): yield (name, scene) def get_scene(self, name): """ @type name: string @param name: The name of the scene to retrieve @rtype: None or sim.Scene @return: None if scene doesn't exist """ return self._scenes.get(name, None) def create_all_scenes(self): """ This load all scenes present in the config file. """ scene_path = self._config.get('scene_path', defaults.scene_search_path) # Interpolate scene path scene_path = [os.path.normpath(environmentSub(p)) for p in scene_path] for name, scene_file in self._config.get('Scenes', {}).iteritems(): self.create_scene(name, scene_file, scene_path) def create_scene(self, name, scene_file, scene_path): """ @type name: string @param name: The name of the scene to create @type scene_file: string @param scene_file: the name of the scene file @type scene_path: list of strings @param scene_path: The path to search for the scene_file on """ # Filter out non-existant paths from search, this keeps windows paths # out of unix and unix paths out of windows search_path = [p for p in scene_path if os.path.exists(p)] if len(search_path) == 0: raise SimulationError('No valid directory found on scene path') #self.logger.info('Loading %s on path:', scene_file) #for path in search_path: # self.logger.info('\t%s' % path ) found = False for dir in search_path: scene_path = os.path.abspath(os.path.join(dir, scene_file)) if os.path.exists(scene_path): self._scenes[name] = scene.Scene(name, scene_path, self._debug) found = True if not found: raise SimulationError('Could not find scene file: %s' % scene_file) # ----------------------------------------------------------------------- # # G R A P H I C S I N I T I A L I Z A T I O N # # ----------------------------------------------------------------------- # def _graphics_init(self, config): # Create the logger to suppress output self._ogre_logger = Ogre.LogManager() self._ogre_logger.createLog(config.get('logName', 'Ogre.log'), defaultLog=True, debuggerOutput=self._debug, suppressFileOutput=False) # Create Ogre.Root singleton with no default plugins self._ogre_root = Ogre.Root("") # Start up Ogre piecewise, passing a default empty config if needed self._load_ogre_plugins(config.get('Plugins', {})) self._create_render_system(config.get('RenderSystem', {})) self._ogre_root.initialise(False) def _load_ogre_plugins(self, config): """ This loads the plugins Ogre needs to run based on the config file. An example:: Plugins: # Where to search for the plugins search_path: [ C:\Libraries\Python-Ogre-0.7\plugins, C:\Developement\Python-Ogre\Python-Ogre-0.7\plugins] # The plugins to load plugins: [ RenderSystem_GL, Plugin_ParticleFX, Plugin_OctreeSceneManager ] """ import platform plugins = config.get('plugins', defaults.ogre_plugins) if 'Darwin' == platform.system(): for plugin in plugins: self._ogre_root.loadPlugin(plugin) else: # Filter out non-existant paths from search, this keeps windows # paths out of unix and unix paths out of windows search_path = config.get('search_path', defaults.ogre_plugin_search_path) # Run Environment varialbe replacement search_path = \ [os.path.normpath(environmentSub(p)) for p in search_path] search_path = [p for p in search_path if os.path.exists(p)] if len(search_path) == 0: raise GraphicsError('All plugin directories do not exist') #self.logger.info('Loadings Ogre Plugins on path:') #for path in search_path: # self.logger.info('\t%s' % path ) extension = '.so' if 'nt' == os.name: extension = '.dll' for plugin in plugins: plugin_name = plugin + extension #self.logger.info('\tSearching for: %s' % plugin_name) found = False for dir in search_path: plugin_path = os.path.join(dir, plugin_name) # Only the plugin once if not found and os.path.exists(plugin_path): self._ogre_root.loadPlugin(plugin_path) found = True if not found: raise GraphicsError('Could not load plugin: %s' % plugin_name) def _create_render_system(self, config): """ This secion here takes over for Ogre's ogre.cfg. The type indicates which Ogre RenderSystem to create and which section to load the options from. An Example:: Ogre: RenderSystem: type: GLRenderSystem GLRenderSystem: - [Colour Depth, '32'] - [Display Frequency, 'N/A'] - [FSAA, '0'] - [Full Screen, 'No'] - [RTT Preferred Mode, 'FBO'] - [VSync, 'No'] """ # Allows looser specification of RenderSystem names typemap = { 'GL': 'OpenGL Rendering Subsystem', 'GLRenderSystem': 'OpenGL Rendering Subsystem', 'OpenGL': 'OpenGL Rendering Subsystem', 'DirectX': 'D3D9RenderSystem', 'DirectX9': 'D3D9RenderSystem', 'Direct 3D': 'D3D9RenderSystem' } # Attempt to find the selected renderer based on given input render_system = None try: type = config.get('type', defaults.render_system) type_name = typemap[type] renderers = self._ogre_root.getAvailableRenderers() for i in xrange(0, len(renderers)): renderer = renderers[i] if type_name == renderer.getName(): render_system = renderer if render_system is None: raise GraphicsError("Could not load " + type + " make sure " "the proper plugin is loaded") except AttributeError, KeyError: raise GraphicsError('"%s" is not a valid render system' % type) self._ogre_root.setRenderSystem(render_system) # Load our options from the custom config system render_system_opts = config.get(type, defaults.render_system_options) for name, value in render_system_opts: render_system.setConfigOption(name, value) # Give Ogre our new render system self._ogre_root.setRenderSystem(render_system) event.send('OGRE_RENDERER_CREATED')
class Thruster(Visual): # Inherits IBody, IVisual, IKMLStorable core.implements(IThruster) @two_step_init def __init__(self): self.direction = Ogre.Vector3.UNIT_Z self._force_pos = Ogre.Vector3.ZERO self._force = 0 self.max_force = 0 self.min_force = 0 Visual.__init__(self) def init(self, parent, name, scene, direction, min_force, max_force, material, position=Ogre.Vector3.ZERO, orientation=Ogre.Quaternion.IDENTITY, scale=Ogre.Vector3(1, 1, 1)): core.verifyClass(IPart, parent) #Visual.init(self, parent, name, scene, mesh, material, position, # orietnation, scale) # Switch me back after the scene node issue is fixed Object.init(parent, name) Thruster._create(self, scene, min_force, max_force, direction, mesh, material, position, orientation, scale) class force(core.cls_property): def fget(self): return self._force def fset(self, force): # Limit thrust to min and max values if force < self.min_force: self._force = self.min_force elif force > self.max_force: self._force = self.max_force else: self._force = force def update(self, time_since_last_frame): forceToApply = self._force # You can thrust in the water if self._node._getDerivedPosition().z > 0: forceToApply = 0 force = sim.OgreVector3(self.direction) * forceToApply self.parent.add_local_force(force, self._force_pos) # Redraw force lines self._thrust_line.estimateVertexCount(1) self._thrust_line.estimateIndexCount(1) self._thrust_line.beginUpdate(0) self._draw_thrust_line(forceToApply) self._thrust_line.end() def _draw_thrust_line(self, force): # Remove transformation by Ogre SceneNode orientation = self._node.orientation.UnitInverse() base_pt = Ogre.Vector3(0, 0, 0) # Direction must be reversed because we are showing water flow thrust_pt = (orientation * -self.direction) * force self._thrust_line.position(base_pt) self._thrust_line.position(thrust_pt) #def _create(self, direction): def _create(self, scene, direction, min_force, max_force, mesh, material, position, orientation, scale): self.direction = direction self.min_force = min_force self.max_force = max_force # Uncomment when python ogre gets updated # Reparent self to node # parent_node = self._node.getParentSceneNode() # parent_node.removeChild(self._node) # self.parent._node.addChild(self._node) # entity = scene.scene_mgr.createEntity(self.name, mesh) entity.setMaterialName(material) self._node = self.parent._node.createChildSceneNode() self._node.attachObject(entity) pscale = self.parent._node.getScale() iscale = Ogre.Vector3((1 / pscale.x), (1 / pscale.y), (1 / pscale.z)) if scale != Ogre.Vector3(1, 1, 1): self._node.setScale(scale * iscale) self._node.position = sim.OgreVector3(position) * iscale self._node.orientation = orientation self._thrust_line = scene.scene_mgr.createManualObject(self.name + "manual") self._thrust_line.dynamic = True self._thrust_line.estimateVertexCount(1) self._thrust_line.estimateIndexCount(1) self._thrust_line.begin("BaseRedNoLighting", Ogre.RenderOperation.OT_LINE_STRIP) self._draw_thrust_line(self._force) self._thrust_line.end() self._node.attachObject(self._thrust_line) def load(self, data_object): #Visual.load(self, data_object) # Remove me when scene node parenting issue is fixed scene, parent, kml_node = data_object Object.load(self, (parent, kml_node)) gfx_node = kml_node['Graphical'] mesh = gfx_node['mesh'] material = gfx_node['material'] scale = sim.OgreVector3(gfx_node['scale']) position, orientation = parse_position_orientation(kml_node) self._force_pos = sim.OgreVector3(position) direction = sim.OgreVector3(kml_node['direction']) min_force = kml_node['min_force'] max_force = kml_node['max_force'] Thruster._create(self, scene, direction, min_force, max_force, mesh, material, position, orientation, scale)
class MasterVisionPanel(BasePanel): core.implements(view.IPanelProvider) def __init__(self, parent, eventHub, vision, ai, machine, *args, **kwargs): BasePanel.__init__(self, parent, *args, **kwargs) # Make sure we shut down all events on close self.Bind(wx.EVT_CLOSE, self._onClose) self._sizer = wx.BoxSizer(wx.VERTICAL) buoyPanel = BuoyPanel(self, self._childChangedSize, eventHub, vision, machine) self._sizer.Add(buoyPanel) pipePanel = OrangePipePanel(self, self._childChangedSize, eventHub, vision) self._sizer.Add(pipePanel) binPanel = BinPanel(self, self._childChangedSize, eventHub, vision, ai = ai) self._sizer.Add(binPanel) targetPanel = TargetPanel(self, self._childChangedSize, eventHub, vision) self._sizer.Add(targetPanel) windowPanel = WindowPanel(self, self._childChangedSize, eventHub, vision, machine = machine) self._sizer.Add(windowPanel) #barbedWirePanel = BarbedWirePanel(self, self._childChangedSize, eventHub, vision) #self._sizer.Add(barbedWirePanel) lanePanel = LanePanel(self, self._childChangedSize, eventHub, vision) self._sizer.Add(lanePanel) cupidPanel = CupidPanel(self, self._childChangedSize, eventHub, vision) self._sizer.Add(cupidPanel) self.SetSizerAndFit(self._sizer) def _childChangedSize(self): self.SetSizerAndFit(self._sizer) @staticmethod def getPanels(subsystems, parent): eventHub = ext.core.Subsystem.getSubsystemOfType(ext.core.QueuedEventHub, subsystems, nonNone = True) vision = ext.core.Subsystem.getSubsystemOfType(ext.vision.VisionSystem, subsystems) ai = ext.core.Subsystem.getSubsystemOfType( ram.ai.subsystem.AI, subsystems) machine = ext.core.Subsystem.getSubsystemOfType( ram.ai.state.Machine, subsystems) paneInfo = wx.aui.AuiPaneInfo().Name("Vision") paneInfo = paneInfo.Caption("Vision").Right() panel = MasterVisionPanel(parent, eventHub, vision, ai, machine) return [(paneInfo, panel, [vision])]