From: <ror...@us...> - 2007-09-20 08:48:20
|
Revision: 182 http://roreditor.svn.sourceforge.net/roreditor/?rev=182&view=rev Author: rorthomas Date: 2007-09-20 01:48:08 -0700 (Thu, 20 Sep 2007) Log Message: ----------- * fixed some cross platform TODOs * PLEASE USE TABS instead of spaces! Modified Paths: -------------- trunk/lib_common/ror/starter.py trunk/lib_common/roreditor/RoRObjectPreviewOgreWindow.py trunk/lib_common/roreditor/RoROdefEditorOgreWindow.py trunk/lib_common/roreditor/RoRTerrainOgreWindow.py trunk/lib_common/roreditor/RoRTruckOgreWindow.py trunk/lib_common/roreditor/RoRTruckUVOgreWindow.py Modified: trunk/lib_common/ror/starter.py =================================================================== --- trunk/lib_common/ror/starter.py 2007-09-20 08:15:43 UTC (rev 181) +++ trunk/lib_common/ror/starter.py 2007-09-20 08:48:08 UTC (rev 182) @@ -220,9 +220,9 @@ # dlg.Destroy() # return False - #TODO check for actual binary name since RoR.exe is windows only + #this function is already cross platform if not checkRoRDirectory(): - dlg = wx.MessageDialog(self, "RoR.exe not found in the selected directory!\nPlease select a new directory!", "Error", wx.OK | wx.ICON_INFORMATION) + dlg = wx.MessageDialog(self, "RoR binary executable not found in the selected directory!\nPlease select a new directory!", "Error", wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() self.rordir = "" Modified: trunk/lib_common/roreditor/RoRObjectPreviewOgreWindow.py =================================================================== --- trunk/lib_common/roreditor/RoRObjectPreviewOgreWindow.py 2007-09-20 08:15:43 UTC (rev 181) +++ trunk/lib_common/roreditor/RoRObjectPreviewOgreWindow.py 2007-09-20 08:48:08 UTC (rev 182) @@ -1,6 +1,6 @@ #Thomas Fischer 31/05/2007, th...@th... import wx, math -import ogre.renderer.OGRE as ogre +import ogre.renderer.OGRE as ogre from wxogre.OgreManager import * from wxogre.wxOgreWindow import * from ror.SimpleTruckRepresentation import * @@ -9,271 +9,272 @@ class TreeDropTarget(wx.PyDropTarget): - def __init__(self, window): - wx.PyDropTarget.__init__(self) - self.do = wx.FileDataObject() - self.SetDataObject(self.do) + def __init__(self, window): + wx.PyDropTarget.__init__(self) + self.do = wx.FileDataObject() + self.SetDataObject(self.do) - def OnEnter(self, x, y, d): - print "OnEnter: %d, %d, %d\n" % (x, y, d) - return wx.DragCopy + def OnEnter(self, x, y, d): + print "OnEnter: %d, %d, %d\n" % (x, y, d) + return wx.DragCopy - def OnDragOver(self, x, y, d): - print "OnDragOver: %d, %d, %d\n" % (x, y, d) - return wx.DragCopy + def OnDragOver(self, x, y, d): + print "OnDragOver: %d, %d, %d\n" % (x, y, d) + return wx.DragCopy - def OnLeave(self): - print "OnLeave\n" + def OnLeave(self): + print "OnLeave\n" - def OnDrop(self, x, y): - print "OnDrop: %d %d\n" % (x, y) - return True + def OnDrop(self, x, y): + print "OnDrop: %d %d\n" % (x, y) + return True - def OnData(self, x, y, d): - print "OnData: %d, %d, %d\n" % (x, y, d) - self.GetData() - print "%s\n" % self.do.GetFilenames() - return d - -class ObjectPreviewOgreWindow(wxOgreWindow): - def __init__(self, parent, ID, size = wx.Size(200,200), rordir = "", **kwargs): - self.rordir = rordir - self.parent = parent - self.objnode = None - self.objentity = None - self.camalpha = 0 - self.radius = 40 - self.dragging = False - self.mode = None - self.logovisible = True - wxOgreWindow.__init__(self, parent, ID, size = size, **kwargs) - droptarget = TreeDropTarget(self) - self.SetDropTarget(droptarget) - + def OnData(self, x, y, d): + print "OnData: %d, %d, %d\n" % (x, y, d) + self.GetData() + print "%s\n" % self.do.GetFilenames() + return d - def SceneInitialisation(self): - #TODO This section is not platform independent, needs to be fixed. - addresources = [self.rordir+"\\data\\terrains",self.rordir+"\\data\\trucks",self.rordir+"\\data\\objects"] - # only init things in the main window, not in shared ones! - # setup resources - for r in addresources: - ogre.ResourceGroupManager.getSingleton().addResourceLocation(r, "FileSystem", "General", False) +class ObjectPreviewOgreWindow(wxOgreWindow): + def __init__(self, parent, ID, size = wx.Size(200,200), rordir = "", **kwargs): + self.rordir = rordir + self.parent = parent + self.objnode = None + self.objentity = None + self.camalpha = 0 + self.radius = 40 + self.dragging = False + self.mode = None + self.logovisible = True + wxOgreWindow.__init__(self, parent, ID, size = size, **kwargs) + droptarget = TreeDropTarget(self) + self.SetDropTarget(droptarget) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/packs/OgreCore.zip", "Zip", "Bootstrap", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media", "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/materials", "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/models", "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups() - self.createSceneManager() - def createSceneManager(self, type="object"): - #get the scenemanager - self.mode = type - uuid = randomID() - if type == "object": - self.sceneManager = getOgreManager().createSceneManager(ogre.ST_GENERIC) - elif type == "terrain": - self.sceneManager = getOgreManager().createSceneManager(ogre.ST_EXTERIOR_CLOSE) + def SceneInitialisation(self): + addresources = [os.path.join(self.rordir,'data', 'terrains'), + os.path.join(self.rordir,'data', 'trucks'), + os.path.join(self.rordir,'data', 'objects')] + # only init things in the main window, not in shared ones! + # setup resources + for r in addresources: + ogre.ResourceGroupManager.getSingleton().addResourceLocation(r, "FileSystem", "General", False) - # create a camera - self.camera = self.sceneManager.createCamera(str(randomID())+'Camera') - self.camera.lookAt(ogre.Vector3(0, 0, 0)) - self.camera.setPosition(ogre.Vector3(0, 0, 100)) - self.camera.nearClipDistance = 1 - self.camera.setAutoAspectRatio(True) + ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/packs/OgreCore.zip", "Zip", "Bootstrap", False) + ogre.ResourceGroupManager.getSingleton().addResourceLocation("media", "FileSystem", "General", False) + ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/materials", "FileSystem", "General", False) + ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/models", "FileSystem", "General", False) + ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups() + self.createSceneManager() - # create the Viewport" - self.viewport = self.renderWindow.addViewport(self.camera, 0, 0.0, 0.0, 1.0, 1.0) - self.viewport.backgroundColour = ogre.ColourValue(0, 0, 0) + def createSceneManager(self, type="object"): + #get the scenemanager + self.mode = type + uuid = randomID() + if type == "object": + self.sceneManager = getOgreManager().createSceneManager(ogre.ST_GENERIC) + elif type == "terrain": + self.sceneManager = getOgreManager().createSceneManager(ogre.ST_EXTERIOR_CLOSE) - # bind mouse and keyboard - self.Bind(wx.EVT_MOUSE_EVENTS, self.onMouseEvent) - - #create objects - self.populateScene() - - def loadFile(self, filename): - self.filename = filename - filenameonly, extension = os.path.splitext(filename) - uuid = randomID() - - #hide logo - self.logovisible = False - - if extension.lower() in [".truck", ".load"]: - self.mode="object" - self.free() - self.createSceneManager() - uuid = randomID() - self.objnode, self.objentity, manualobject = createTruckMesh(self.sceneManager, filename, uuid) - #print "aaa", self.objnode.getPosition() - elif extension.lower() in [".odef"]: - self.mode="object" - self.free() - self.createSceneManager() - self.loadodef(filename, uuid) - elif extension.lower() in [".terrn"]: - self.mode="terrain" - self.free() - self.createSceneManager("terrain") - terrain = RoRTerrain(filename) - cfgfile = os.path.join(os.path.dirname(filename), terrain.TerrainConfig) - self.objnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"objnode") - self.objnode.setPosition(1500, 0, 1500) - self.sceneManager.setWorldGeometry(cfgfile) - - def loadodef(self, filename, uuid): - try: - meshname, sx, sy, sz, ismovable, boxes = loadOdef(filename) - except Exception, err: - log().error("error while processing odef file %s" % filename) - log().error(str(err)) - return - # create mesh - print meshname, sx, sy, sz - self.objnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"objnode") - self.objentity = self.sceneManager.createEntity(uuid+'objentity', meshname) - self.objnode.attachObject(self.objentity) - self.objnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(-90),relativeTo=ogre.Node.TransformSpace.TS_WORLD) - #self.objnode.setPosition(0,0,0) - if not sx is None: - self.objnode.setScale(sx, sy, sz) + # create a camera + self.camera = self.sceneManager.createCamera(str(randomID())+'Camera') + self.camera.lookAt(ogre.Vector3(0, 0, 0)) + self.camera.setPosition(ogre.Vector3(0, 0, 100)) + self.camera.nearClipDistance = 1 + self.camera.setAutoAspectRatio(True) - - def free(self): - try: - self.sceneManager.destroyAllManualObjects() - except Exception, e: - log().exception(str(e)) - - try: - self.logotextnode.detachAllObjects() - self.logowheelnode.detachAllObjects() - self.sceneManager.destroySceneNode(self.logotextnode.getName()) - self.sceneManager.destroySceneNode(self.logowheelnode.getName()) - self.sceneManager.destroyEntity(self.logotextentity) - self.sceneManager.destroyEntity(self.logowheelentity) - except Exception, e: - log().exception(str(e)) - try: - #BUG: next line fails and goes to except - self.objnode.detachAllObjects() - self.sceneManager.destroySceneNode(self.objnode.getName()) - except Exception, e: - log().exception(str(e)) + # create the Viewport" + self.viewport = self.renderWindow.addViewport(self.camera, 0, 0.0, 0.0, 1.0, 1.0) + self.viewport.backgroundColour = ogre.ColourValue(0, 0, 0) - #try: - #BUG Entering this function alone seams to kill the application. - #self.sceneManager.destroyEntity(self.objentity) - #except Exception, e: - #log().exception(str(e)) - - self.renderWindow.removeAllViewports() - getOgreManager().destroySceneManager(self.sceneManager) - - def populateScene(self): - self.sceneManager.AmbientLight = ogre.ColourValue(0.7, 0.7, 0.7 ) - self.sceneManager.setShadowTechnique(ogre.ShadowTechnique.SHADOWTYPE_STENCIL_ADDITIVE); - self.sceneManager.setSkyDome(True, 'mysimple/terraineditor/previewwindowsky', 4.0, 8.0) + # bind mouse and keyboard + self.Bind(wx.EVT_MOUSE_EVENTS, self.onMouseEvent) - #self.MainLight = self.sceneManager.createLight('MainLight') - #self.MainLight.setPosition (ogre.Vector3(20, 80, 130)) + #create objects + self.populateScene() - # add some fog - self.sceneManager.setFog(ogre.FOG_EXP, ogre.ColourValue.White, 0.00002) + def loadFile(self, filename): + self.filename = filename + filenameonly, extension = os.path.splitext(filename) + uuid = randomID() - # create a floor Mesh - plane = ogre.Plane() - plane.normal = ogre.Vector3(0, 1, 0) - plane.d = 200 - uuid = str(randomID()) - ogre.MeshManager.getSingleton().createPlane(uuid + 'FloorPlane', "General", plane, 200000.0, 200000.0, - 20, 20, True, 1, 50.0, 50.0,ogre.Vector3(0, 0, 1), - ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, - ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, - True, True) + #hide logo + self.logovisible = False - # create floor entity - entity = self.sceneManager.createEntity(uuid+'floor', uuid + 'FloorPlane') - entity.setMaterialName('mysimple/terraineditor/previewwindowfloor') - self.sceneManager.getRootSceneNode().createChildSceneNode().attachObject(entity) - - if self.logovisible: - uuid = str(randomID()) - self.logowheelnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"logonode") - self.logowheelentity = self.sceneManager.createEntity(uuid+'logoentity', "logowheel.mesh") - self.logowheelentity.setMaterialName('mysimple/terrainselect') - self.logowheelnode.attachObject(self.logowheelentity) - self.logowheelnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(-90),relativeTo=ogre.Node.TransformSpace.TS_WORLD) - self.logowheelnode.setScale(0.025, 0.025, 0.025) + if extension.lower() in [".truck", ".load"]: + self.mode="object" + self.free() + self.createSceneManager() + uuid = randomID() + self.objnode, self.objentity, manualobject = createTruckMesh(self.sceneManager, filename, uuid) + #print "aaa", self.objnode.getPosition() + elif extension.lower() in [".odef"]: + self.mode="object" + self.free() + self.createSceneManager() + self.loadodef(filename, uuid) + elif extension.lower() in [".terrn"]: + self.mode="terrain" + self.free() + self.createSceneManager("terrain") + terrain = RoRTerrain(filename) + cfgfile = os.path.join(os.path.dirname(filename), terrain.TerrainConfig) + self.objnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"objnode") + self.objnode.setPosition(1500, 0, 1500) + self.sceneManager.setWorldGeometry(cfgfile) - uuid = str(randomID()) - self.logotextnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"logonode") - self.logotextentity = self.sceneManager.createEntity(uuid+'logoentity', "logotext.mesh") - self.logotextentity.setMaterialName('mysimple/transblue') - self.logotextnode.attachObject(self.logotextentity) - self.logotextnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(-90),relativeTo=ogre.Node.TransformSpace.TS_WORLD) - self.logotextnode.setScale(0.025, 0.025, 0.025) - - else: - pass - #self.logotextnode.setVisible(False) - #self.logowheelnode.setVisible(False) + def loadodef(self, filename, uuid): + try: + meshname, sx, sy, sz, ismovable, boxes = loadOdef(filename) + except Exception, err: + log().error("error while processing odef file %s" % filename) + log().error(str(err)) + return + # create mesh + print meshname, sx, sy, sz + self.objnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"objnode") + self.objentity = self.sceneManager.createEntity(uuid+'objentity', meshname) + self.objnode.attachObject(self.objentity) + self.objnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(-90),relativeTo=ogre.Node.TransformSpace.TS_WORLD) + #self.objnode.setPosition(0,0,0) + if not sx is None: + self.objnode.setScale(sx, sy, sz) - def updateCamera(self): - if not self.mode is None: - if self.logovisible: - self.radius = 100 - pos = self.logotextnode.getPosition() - lookheight = ogre.Vector3(0,0,0) - self.logowheelnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(1),relativeTo=ogre.Node.TransformSpace.TS_LOCAL) - else: - if self.mode == "object": - self.radius = self.objentity.getBoundingRadius() * 2 - if self.objentity is None: - height = 20 - else: - height = self.objentity.getBoundingBox().getMaximum().z - rotateheight = ogre.Vector3(0, height * 0.2, 0) - pos = self.objnode.getPosition() + rotateheight + (self.objentity.getBoundingBox().getMinimum() + self.objentity.getBoundingBox().getMaximum() ) / 2 - lookheight = ogre.Vector3(0, height / 2, 0) - elif self.mode == "terrain": - self.radius = 3000 - rotateheight = ogre.Vector3(0, 1600, 0) - pos = self.objnode.getPosition() + rotateheight - lookheight = -rotateheight + def free(self): + try: + self.sceneManager.destroyAllManualObjects() + except Exception, e: + log().exception(str(e)) - dx = math.cos(self.camalpha) * self.radius - dy = math.sin(self.camalpha) * self.radius - self.camera.setPosition(pos - ogre.Vector3(dx, -5, dy)) - self.camera.lookAt(pos + lookheight) - if self.dragging == False: - self.camalpha += math.pi / 720 - if self.camalpha >= 360: - self.camalpha -= 360 + try: + self.logotextnode.detachAllObjects() + self.logowheelnode.detachAllObjects() + self.sceneManager.destroySceneNode(self.logotextnode.getName()) + self.sceneManager.destroySceneNode(self.logowheelnode.getName()) + self.sceneManager.destroyEntity(self.logotextentity) + self.sceneManager.destroyEntity(self.logowheelentity) + except Exception, e: + log().exception(str(e)) + try: + #BUG: next line fails and goes to except + self.objnode.detachAllObjects() + self.sceneManager.destroySceneNode(self.objnode.getName()) + except Exception, e: + log().exception(str(e)) + #try: + #BUG Entering this function alone seams to kill the application. + #self.sceneManager.destroyEntity(self.objentity) + #except Exception, e: + #log().exception(str(e)) - def OnFrameStarted(self): - if self.logovisible: - self.logowheelnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(1),relativeTo=ogre.Node.TransformSpace.TS_LOCAL) - self.updateCamera() - wxOgreWindow.OnFrameStarted(self) - - def onMouseEvent(self, event): - #self.SetFocus() #Gives Keyboard focus to the window - - if event.RightDown(): #Precedes dragging - self.StartDragX, self.StartDragY = event.GetPosition() #saves position of initial click - elif event.Dragging() and event.RightIsDown(): #Dragging with RMB - x,y = event.GetPosition() - dx = self.StartDragX - x - dy = self.StartDragY - y - self.StartDragX, self.StartDragY = x, y - self.camalpha -= float(dx) * (math.pi / 720) * 2 - self.updateCamera() - self.dragging = True - else: - self.dragging = False - event.Skip() - \ No newline at end of file + self.renderWindow.removeAllViewports() + getOgreManager().destroySceneManager(self.sceneManager) + + def populateScene(self): + self.sceneManager.AmbientLight = ogre.ColourValue(0.7, 0.7, 0.7 ) + self.sceneManager.setShadowTechnique(ogre.ShadowTechnique.SHADOWTYPE_STENCIL_ADDITIVE); + self.sceneManager.setSkyDome(True, 'mysimple/terraineditor/previewwindowsky', 4.0, 8.0) + + #self.MainLight = self.sceneManager.createLight('MainLight') + #self.MainLight.setPosition (ogre.Vector3(20, 80, 130)) + + # add some fog + self.sceneManager.setFog(ogre.FOG_EXP, ogre.ColourValue.White, 0.00002) + + # create a floor Mesh + plane = ogre.Plane() + plane.normal = ogre.Vector3(0, 1, 0) + plane.d = 200 + uuid = str(randomID()) + ogre.MeshManager.getSingleton().createPlane(uuid + 'FloorPlane', "General", plane, 200000.0, 200000.0, + 20, 20, True, 1, 50.0, 50.0,ogre.Vector3(0, 0, 1), + ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, + ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, + True, True) + + # create floor entity + entity = self.sceneManager.createEntity(uuid+'floor', uuid + 'FloorPlane') + entity.setMaterialName('mysimple/terraineditor/previewwindowfloor') + self.sceneManager.getRootSceneNode().createChildSceneNode().attachObject(entity) + + if self.logovisible: + uuid = str(randomID()) + self.logowheelnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"logonode") + self.logowheelentity = self.sceneManager.createEntity(uuid+'logoentity', "logowheel.mesh") + self.logowheelentity.setMaterialName('mysimple/terrainselect') + self.logowheelnode.attachObject(self.logowheelentity) + self.logowheelnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(-90),relativeTo=ogre.Node.TransformSpace.TS_WORLD) + self.logowheelnode.setScale(0.025, 0.025, 0.025) + + uuid = str(randomID()) + self.logotextnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"logonode") + self.logotextentity = self.sceneManager.createEntity(uuid+'logoentity', "logotext.mesh") + self.logotextentity.setMaterialName('mysimple/transblue') + self.logotextnode.attachObject(self.logotextentity) + self.logotextnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(-90),relativeTo=ogre.Node.TransformSpace.TS_WORLD) + self.logotextnode.setScale(0.025, 0.025, 0.025) + + else: + pass + #self.logotextnode.setVisible(False) + #self.logowheelnode.setVisible(False) + + + def updateCamera(self): + if not self.mode is None: + if self.logovisible: + self.radius = 100 + pos = self.logotextnode.getPosition() + lookheight = ogre.Vector3(0,0,0) + self.logowheelnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(1),relativeTo=ogre.Node.TransformSpace.TS_LOCAL) + else: + if self.mode == "object": + self.radius = self.objentity.getBoundingRadius() * 2 + if self.objentity is None: + height = 20 + else: + height = self.objentity.getBoundingBox().getMaximum().z + rotateheight = ogre.Vector3(0, height * 0.2, 0) + pos = self.objnode.getPosition() + rotateheight + (self.objentity.getBoundingBox().getMinimum() + self.objentity.getBoundingBox().getMaximum() ) / 2 + lookheight = ogre.Vector3(0, height / 2, 0) + elif self.mode == "terrain": + self.radius = 3000 + rotateheight = ogre.Vector3(0, 1600, 0) + pos = self.objnode.getPosition() + rotateheight + lookheight = -rotateheight + + dx = math.cos(self.camalpha) * self.radius + dy = math.sin(self.camalpha) * self.radius + self.camera.setPosition(pos - ogre.Vector3(dx, -5, dy)) + self.camera.lookAt(pos + lookheight) + if self.dragging == False: + self.camalpha += math.pi / 720 + if self.camalpha >= 360: + self.camalpha -= 360 + + + def OnFrameStarted(self): + if self.logovisible: + self.logowheelnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(1),relativeTo=ogre.Node.TransformSpace.TS_LOCAL) + self.updateCamera() + wxOgreWindow.OnFrameStarted(self) + + def onMouseEvent(self, event): + #self.SetFocus() #Gives Keyboard focus to the window + + if event.RightDown(): #Precedes dragging + self.StartDragX, self.StartDragY = event.GetPosition() #saves position of initial click + elif event.Dragging() and event.RightIsDown(): #Dragging with RMB + x,y = event.GetPosition() + dx = self.StartDragX - x + dy = self.StartDragY - y + self.StartDragX, self.StartDragY = x, y + self.camalpha -= float(dx) * (math.pi / 720) * 2 + self.updateCamera() + self.dragging = True + else: + self.dragging = False + event.Skip() + \ No newline at end of file Modified: trunk/lib_common/roreditor/RoROdefEditorOgreWindow.py =================================================================== --- trunk/lib_common/roreditor/RoROdefEditorOgreWindow.py 2007-09-20 08:15:43 UTC (rev 181) +++ trunk/lib_common/roreditor/RoROdefEditorOgreWindow.py 2007-09-20 08:48:08 UTC (rev 182) @@ -1,6 +1,6 @@ #Thomas Fischer 31/05/2007, th...@th... import wx, math -import ogre.renderer.OGRE as ogre +import ogre.renderer.OGRE as ogre from wxogre.OgreManager import * from wxogre.wxOgreWindow import * from ror.SimpleTruckRepresentation import * @@ -9,355 +9,356 @@ class TreeDropTarget(wx.PyDropTarget): - def __init__(self, window): - wx.PyDropTarget.__init__(self) - self.do = wx.FileDataObject() - self.SetDataObject(self.do) + def __init__(self, window): + wx.PyDropTarget.__init__(self) + self.do = wx.FileDataObject() + self.SetDataObject(self.do) - def OnEnter(self, x, y, d): - print "OnEnter: %d, %d, %d\n" % (x, y, d) - return wx.DragCopy + def OnEnter(self, x, y, d): + print "OnEnter: %d, %d, %d\n" % (x, y, d) + return wx.DragCopy - def OnDragOver(self, x, y, d): - print "OnDragOver: %d, %d, %d\n" % (x, y, d) - return wx.DragCopy + def OnDragOver(self, x, y, d): + print "OnDragOver: %d, %d, %d\n" % (x, y, d) + return wx.DragCopy - def OnLeave(self): - print "OnLeave\n" + def OnLeave(self): + print "OnLeave\n" - def OnDrop(self, x, y): - print "OnDrop: %d %d\n" % (x, y) - return True + def OnDrop(self, x, y): + print "OnDrop: %d %d\n" % (x, y) + return True - def OnData(self, x, y, d): - print "OnData: %d, %d, %d\n" % (x, y, d) - self.GetData() - print "%s\n" % self.do.GetFilenames() - return d - + def OnData(self, x, y, d): + print "OnData: %d, %d, %d\n" % (x, y, d) + self.GetData() + print "%s\n" % self.do.GetFilenames() + return d -NEWMATNAME = "mysimple/odefeditor/objplaceholder" -class ODefEditorOgreWindow(wxOgreWindow): - def __init__(self, parent, ID, size = wx.Size(200,200), rordir = "", **kwargs): - self.rordir = rordir - self.parent = parent - self.objnode = None - self.objentity = None - self.camalpha = 0 - self.radius = 40 - self.dragging = False - self.boxes = [] - self.objmat = None - self.randcolors = [0,0.2,0.4] - wxOgreWindow.__init__(self, parent, ID, size = size, **kwargs) - droptarget = TreeDropTarget(self) - self.SetDropTarget(droptarget) - +NEWMATNAME = "mysimple/odefeditor/objplaceholder" - def SceneInitialisation(self): - #TODO This section is not platform independent, needs to be fixed. - addresources = [self.rordir+"\\data\\terrains",self.rordir+"\\data\\trucks",self.rordir+"\\data\\objects"] - # only init things in the main window, not in shared ones! - # setup resources - for r in addresources: - ogre.ResourceGroupManager.getSingleton().addResourceLocation(r, "FileSystem", "General", False) +class ODefEditorOgreWindow(wxOgreWindow): + def __init__(self, parent, ID, size = wx.Size(200,200), rordir = "", **kwargs): + self.rordir = rordir + self.parent = parent + self.objnode = None + self.objentity = None + self.camalpha = 0 + self.radius = 40 + self.dragging = False + self.boxes = [] + self.objmat = None + self.randcolors = [0,0.2,0.4] + wxOgreWindow.__init__(self, parent, ID, size = size, **kwargs) + droptarget = TreeDropTarget(self) + self.SetDropTarget(droptarget) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/packs/OgreCore.zip", "Zip", "Bootstrap", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media", "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/materials", "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/models", "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups() - #get the scenemanager - self.sceneManager = getOgreManager().createSceneManager(ogre.ST_GENERIC) + def SceneInitialisation(self): + addresources = [os.path.join(self.rordir,'data', 'terrains'), + os.path.join(self.rordir,'data', 'trucks'), + os.path.join(self.rordir,'data', 'objects')] + # only init things in the main window, not in shared ones! + # setup resources + for r in addresources: + ogre.ResourceGroupManager.getSingleton().addResourceLocation(r, "FileSystem", "General", False) - # create a camera - self.camera = self.sceneManager.createCamera(str(randomID())+'Camera') - self.camera.lookAt(ogre.Vector3(0, 0, 0)) - self.camera.setPosition(ogre.Vector3(0, 0, 100)) - self.camera.nearClipDistance = 1 - self.camera.setAutoAspectRatio(True) + ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/packs/OgreCore.zip", "Zip", "Bootstrap", False) + ogre.ResourceGroupManager.getSingleton().addResourceLocation("media", "FileSystem", "General", False) + ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/materials", "FileSystem", "General", False) + ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/models", "FileSystem", "General", False) + ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups() - # create the Viewport" - self.viewport = self.renderWindow.addViewport(self.camera, 0, 0.0, 0.0, 1.0, 1.0) - self.viewport.backgroundColour = ogre.ColourValue(0, 0, 0) + #get the scenemanager + self.sceneManager = getOgreManager().createSceneManager(ogre.ST_GENERIC) - # bind mouse and keyboard - d=10.0 #displacement for key strokes - self.ControlKeyDict={wx.WXK_LEFT:ogre.Vector3(-d,0.0,0.0), - wx.WXK_RIGHT:ogre.Vector3(d,0.0,0.0), - wx.WXK_UP:ogre.Vector3(0.0,0.0,-d), - wx.WXK_DOWN:ogre.Vector3(0.0,0.0,d), - wx.WXK_PAGEUP:ogre.Vector3(0.0,d,0.0), - wx.WXK_PAGEDOWN:ogre.Vector3(0.0,-d,0.0)} - self.Bind(wx.EVT_KEY_DOWN, self.onKeyDown) - #self.Bind(wx.EVT_KEY_UP, self.onKeyUp) - self.Bind(wx.EVT_MOUSE_EVENTS, self.onMouseEvent) - #create objects - self.populateScene() - - def loadFile(self, filename): - self.filename = filename - filenameonly, extension = os.path.splitext(filename) - if extension.lower() in [".truck", ".load"]: - self.free() - uuid = randomID() - self.objnode, self.objentity, manualobject = createTruckMesh(self.sceneManager, filename, uuid) - elif extension.lower() in [".odef"]: - self.free() - uuid = randomID() - self.loadodef(filename, uuid) + # create a camera + self.camera = self.sceneManager.createCamera(str(randomID())+'Camera') + self.camera.lookAt(ogre.Vector3(0, 0, 0)) + self.camera.setPosition(ogre.Vector3(0, 0, 100)) + self.camera.nearClipDistance = 1 + self.camera.setAutoAspectRatio(True) - def loadodef(self, filename, uuid): - try: - meshname, sx, sy, sz, ismovable, boxes = loadOdef(filename) - except Exception, err: - log().error("error while processing odef file %s" % filename) - log().error(str(err)) - return - # create mesh - self.objnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"objnode") - self.objentity = self.sceneManager.createEntity(uuid+'objentity', meshname) - self.objnode.attachObject(self.objentity) - self.objnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(-90),relativeTo=ogre.Node.TransformSpace.TS_WORLD) - - try: - self.objOriginalMat = ogre.MaterialManager.getSingleton().getByName(self.objentity.getSubEntity(0).getMaterialName()) - if self.objmat is None: - self.objmat = ogre.MaterialManager.getSingleton().getByName(NEWMATNAME) - self.objOriginalMat.copyDetailsTo(self.objmat) - # self.objmat = ogre.MaterialManager.getSingleton().getByName(NEWMATNAME) - self.objmat.setSceneBlending(ogre.SceneBlendFactor.SBF_SOURCE_ALPHA, ogre.SceneBlendFactor.SBF_DEST_ALPHA ) - self.objentity.setMaterialName(NEWMATNAME) - self.setMainMeshTrans(60) - except: - pass - - self.objnode.setPosition(0,0,0) - if not sx is None: - self.objnode.setScale(sx, sy, sz) - for box in boxes: - - matname = "mysimple/odefeditor/transred" - if box.virtual: - matname = "mysimple/odefeditor/transgreen" - matname = self.getNewMat(matname) - box.uuid = randomID() - box.node = self.sceneManager.getRootSceneNode().createChildSceneNode(box.uuid+"boxnode") - box.entity = self.sceneManager.createEntity(box.uuid+'boxentity', "beam.mesh") - box.entity.setMaterialName(matname) - box.node.attachObject(box.entity) + # create the Viewport" + self.viewport = self.renderWindow.addViewport(self.camera, 0, 0.0, 0.0, 1.0, 1.0) + self.viewport.backgroundColour = ogre.ColourValue(0, 0, 0) - if box.rotating: - rotx = float(box.rotation[0]) - roty = float(box.rotation[1]) - rotz = float(box.rotation[2]) - box.node.rotate(ogre.Vector3.UNIT_Z, ogre.Degree(rotz),relativeTo=ogre.Node.TransformSpace.TS_WORLD) - box.node.rotate(ogre.Vector3.UNIT_Y, ogre.Degree(roty),relativeTo=ogre.Node.TransformSpace.TS_WORLD) - box.node.rotate(ogre.Vector3.UNIT_X, ogre.Degree(rotx),relativeTo=ogre.Node.TransformSpace.TS_WORLD) + # bind mouse and keyboard + d=10.0 #displacement for key strokes + self.ControlKeyDict={wx.WXK_LEFT:ogre.Vector3(-d,0.0,0.0), + wx.WXK_RIGHT:ogre.Vector3(d,0.0,0.0), + wx.WXK_UP:ogre.Vector3(0.0,0.0,-d), + wx.WXK_DOWN:ogre.Vector3(0.0,0.0,d), + wx.WXK_PAGEUP:ogre.Vector3(0.0,d,0.0), + wx.WXK_PAGEDOWN:ogre.Vector3(0.0,-d,0.0)} + self.Bind(wx.EVT_KEY_DOWN, self.onKeyDown) + #self.Bind(wx.EVT_KEY_UP, self.onKeyUp) + self.Bind(wx.EVT_MOUSE_EVENTS, self.onMouseEvent) + #create objects + self.populateScene() - x = float(box.coords[0]) - x1 = float(box.coords[1]) - y = float(box.coords[2]) - y1 = float(box.coords[3]) - z = float(box.coords[4]) - z1 = float(box.coords[5]) - xdiff = x1-x - ydiff = y1-y - zdiff = z1-z - box.node.setPosition(x+xdiff/2, y+ydiff/2, z+zdiff/2) - box.node.setScale(xdiff, ydiff, zdiff) - self.boxes.append(box) + def loadFile(self, filename): + self.filename = filename + filenameonly, extension = os.path.splitext(filename) + if extension.lower() in [".truck", ".load"]: + self.free() + uuid = randomID() + self.objnode, self.objentity, manualobject = createTruckMesh(self.sceneManager, filename, uuid) + elif extension.lower() in [".odef"]: + self.free() + uuid = randomID() + self.loadodef(filename, uuid) - def getNewMat(self, basematname): - uuid = randomID() - matname = uuid+"mat" - basemat = ogre.MaterialManager.getSingleton().getByName(basematname) - mat = ogre.MaterialManager.getSingleton().create(matname, basemat.getGroup()) - basemat.copyDetailsTo(mat) - #mat = ogre.MaterialManager.getSingleton().getByName(matname) - for i in range(0,2): - self.randcolors[i] += 0.1 - if self.randcolors[i] >= 1: - self.randcolors[i] -= 1 - mat.setDiffuse(self.randcolors[0], self.randcolors[1], self.randcolors[2], 0.8) - mat.setSpecular(self.randcolors[0], self.randcolors[1], self.randcolors[2], 0.8) - mat.setSelfIllumination(self.randcolors[0], self.randcolors[1], self.randcolors[2]) - mat.setAmbient(self.randcolors[0], self.randcolors[1], self.randcolors[2]) - print "new material:", matname - return matname - - def setMainMeshTrans(self, alpha): - alpha = float(alpha) / float(100) - self.objmat.setDiffuse(0.5, 1, 0.5, alpha) - self.objmat.setSpecular(0.5, 1, 0.5, alpha) + def loadodef(self, filename, uuid): + try: + meshname, sx, sy, sz, ismovable, boxes = loadOdef(filename) + except Exception, err: + log().error("error while processing odef file %s" % filename) + log().error(str(err)) + return + # create mesh + self.objnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"objnode") + self.objentity = self.sceneManager.createEntity(uuid+'objentity', meshname) + self.objnode.attachObject(self.objentity) + self.objnode.rotate(ogre.Vector3.UNIT_X, ogre.Degree(-90),relativeTo=ogre.Node.TransformSpace.TS_WORLD) - def setMainMeshVisible(self, visible): - self.objentity.setVisible(visible) - - def setBoxesVisibility(self, type, visible): - for box in self.boxes: - if type == "normal" and box.virtual == False: - box.entity.setVisible(visible) - elif type == "virtual" and box.virtual == True: - box.entity.setVisible(visible) - - def free(self): - for box in self.boxes: - try: - box.node.detachAllObjects() - self.sceneManager.destroySceneNode(box.node.getName()) - except: - pass - try: - self.sceneManager.destroyEntity(box.entity) - except: - pass - self.boxes = [] - - try: - self.sceneManager.destroyAllManualObjects() - except: - pass - try: - self.objnode.detachAllObjects() - self.sceneManager.destroySceneNode(self.objnode.getName()) - except: - pass - try: - self.sceneManager.destroyEntity(self.objentity) - except: - pass - - def populateScene(self): - self.sceneManager.AmbientLight = ogre.ColourValue(0.7, 0.7, 0.7 ) - self.sceneManager.setShadowTechnique(ogre.ShadowTechnique.SHADOWTYPE_STENCIL_ADDITIVE); - self.sceneManager.setSkyDome(True, 'mysimple/terraineditor/previewwindowsky', 4.0, 8.0) + try: + self.objOriginalMat = ogre.MaterialManager.getSingleton().getByName(self.objentity.getSubEntity(0).getMaterialName()) + if self.objmat is None: + self.objmat = ogre.MaterialManager.getSingleton().getByName(NEWMATNAME) + self.objOriginalMat.copyDetailsTo(self.objmat) + # self.objmat = ogre.MaterialManager.getSingleton().getByName(NEWMATNAME) + self.objmat.setSceneBlending(ogre.SceneBlendFactor.SBF_SOURCE_ALPHA, ogre.SceneBlendFactor.SBF_DEST_ALPHA ) + self.objentity.setMaterialName(NEWMATNAME) + self.setMainMeshTrans(60) + except: + pass - #self.MainLight = self.sceneManager.createLight('MainLight') - #self.MainLight.setPosition (ogre.Vector3(20, 80, 130)) + self.objnode.setPosition(0,0,0) + if not sx is None: + self.objnode.setScale(sx, sy, sz) + for box in boxes: - # add some fog - self.sceneManager.setFog(ogre.FOG_EXP, ogre.ColourValue.White, 0.0002) + matname = "mysimple/odefeditor/transred" + if box.virtual: + matname = "mysimple/odefeditor/transgreen" + matname = self.getNewMat(matname) + box.uuid = randomID() + box.node = self.sceneManager.getRootSceneNode().createChildSceneNode(box.uuid+"boxnode") + box.entity = self.sceneManager.createEntity(box.uuid+'boxentity', "beam.mesh") + box.entity.setMaterialName(matname) + box.node.attachObject(box.entity) - # create a floor Mesh - plane = ogre.Plane() - plane.normal = ogre.Vector3(0, 1, 0) - plane.d = 200 - uuid = str(randomID()) - ogre.MeshManager.getSingleton().createPlane(uuid + 'FloorPlane', "General", plane, 200000.0, 200000.0, - 20, 20, True, 1, 50.0, 50.0,ogre.Vector3(0, 0, 1), - ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, - ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, - True, True) + if box.rotating: + rotx = float(box.rotation[0]) + roty = float(box.rotation[1]) + rotz = float(box.rotation[2]) + box.node.rotate(ogre.Vector3.UNIT_Z, ogre.Degree(rotz),relativeTo=ogre.Node.TransformSpace.TS_WORLD) + box.node.rotate(ogre.Vector3.UNIT_Y, ogre.Degree(roty),relativeTo=ogre.Node.TransformSpace.TS_WORLD) + box.node.rotate(ogre.Vector3.UNIT_X, ogre.Degree(rotx),relativeTo=ogre.Node.TransformSpace.TS_WORLD) - # create floor entity - entity = self.sceneManager.createEntity(uuid+'floor', uuid + 'FloorPlane') - entity.setMaterialName('mysimple/terraineditor/previewwindowfloor') - self.sceneManager.getRootSceneNode().createChildSceneNode().attachObject(entity) + x = float(box.coords[0]) + x1 = float(box.coords[1]) + y = float(box.coords[2]) + y1 = float(box.coords[3]) + z = float(box.coords[4]) + z1 = float(box.coords[5]) + xdiff = x1-x + ydiff = y1-y + zdiff = z1-z + box.node.setPosition(x+xdiff/2, y+ydiff/2, z+zdiff/2) + box.node.setScale(xdiff, ydiff, zdiff) + self.boxes.append(box) - def updateCamera(self): - return - if not self.objnode is None: - self.radius = self.objentity.getBoundingRadius() * 2 - height = self.objentity.getBoundingBox().getMaximum().z - #pos = self.objnode.getPosition() + ogre.Vector3(0, height*0.4, 0) - # always look to the center! - pos = self.objnode.getPosition() + ogre.Vector3(0, height*0.4, 0) + (self.objentity.getBoundingBox().getMinimum() + self.objentity.getBoundingBox().getMaximum() ) / 2 - dx = math.cos(self.camalpha) * self.radius - dy = math.sin(self.camalpha) * self.radius - self.camera.setPosition(pos - ogre.Vector3(dx, -5, dy)) - self.camera.lookAt(pos + ogre.Vector3(0, height / 2, 0)) - - # disable auto rotation - #if self.dragging == False: - # self.camalpha += math.pi / 720 - if self.camalpha >= 360: - self.camalpha -= 360 + def getNewMat(self, basematname): + uuid = randomID() + matname = uuid+"mat" + basemat = ogre.MaterialManager.getSingleton().getByName(basematname) + mat = ogre.MaterialManager.getSingleton().create(matname, basemat.getGroup()) + basemat.copyDetailsTo(mat) + #mat = ogre.MaterialManager.getSingleton().getByName(matname) + for i in range(0,2): + self.randcolors[i] += 0.1 + if self.randcolors[i] >= 1: + self.randcolors[i] -= 1 + mat.setDiffuse(self.randcolors[0], self.randcolors[1], self.randcolors[2], 0.8) + mat.setSpecular(self.randcolors[0], self.randcolors[1], self.randcolors[2], 0.8) + mat.setSelfIllumination(self.randcolors[0], self.randcolors[1], self.randcolors[2]) + mat.setAmbient(self.randcolors[0], self.randcolors[1], self.randcolors[2]) + print "new material:", matname + return matname + def setMainMeshTrans(self, alpha): + alpha = float(alpha) / float(100) + self.objmat.setDiffuse(0.5, 1, 0.5, alpha) + self.objmat.setSpecular(0.5, 1, 0.5, alpha) - def OnFrameStarted(self): - self.updateCamera() - wxOgreWindow.OnFrameStarted(self) - - def onMouseEvent(self,event): - self.SetFocus() - width, height, a, b, c = self.renderWindow.getMetrics() + def setMainMeshVisible(self, visible): + self.objentity.setVisible(visible) - if event.RightDown(): #Precedes dragging - self.StartDragX, self.StartDragY = event.GetPosition() #saves position of initial click - if event.GetWheelRotation() != 0: - zfactor = 0.001 - if event.ShiftDown(): - zfactor = 0.01 - zoom = zfactor * -event.GetWheelRotation() - self.camera.moveRelative(ogre.Vector3(0,0, zoom)) + def setBoxesVisibility(self, type, visible): + for box in self.boxes: + if type == "normal" and box.virtual == False: + box.entity.setVisible(visible) + elif type == "virtual" and box.virtual == True: + box.entity.setVisible(visible) - if event.Dragging() and event.RightIsDown() and event.ControlDown(): - x,y = event.GetPosition() - dx = self.StartDragX - x - dy = self.StartDragY - y - self.StartDragX, self.StartDragY = x, y - if event.ShiftDown(): - dx = float(dx) / 10 - dy = float(dy) / 10 - else: - dx = float(dx) / 50 - dy = float(dy) / 50 - self.camera.moveRelative(ogre.Vector3(dx,-dy,0)) - - elif event.Dragging() and event.RightIsDown(): #Dragging with RMB - x,y = event.GetPosition() - dx = self.StartDragX - x - dy = self.StartDragY - y - self.StartDragX, self.StartDragY = x, y - - self.camera.yaw(ogre.Degree(dx/3.0)) - self.camera.pitch(ogre.Degree(dy/3.0)) - if event.LeftDown(): - #self.selectnew(event) - self.StartDragLeftX, self.StartDragLeftY = event.GetPosition() #saves position of initial click - zfactor = 0.1 - if event.ShiftDown(): - zfactor = 5 - zoom = zfactor * -event.GetWheelRotation() - self.camera.moveRelative(ogre.Vector3(0,0, zoom)) - - def onKeyDown(self,event): - #print event.m_keyCode - d = 3 - if event.ShiftDown(): - d = 10 - if event.m_keyCode == 65: # A, wx.WXK_LEFT: - self.camera.moveRelative(ogre.Vector3(-d,0,0)) - elif event.m_keyCode == 68: # D, wx.WXK_RIGHT: - self.camera.moveRelative(ogre.Vector3(d,0,0)) - elif event.m_keyCode == 87: # W ,wx.WXK_UP: - self.camera.moveRelative(ogre.Vector3(0,0,-d)) - elif event.m_keyCode == 83: # S, wx.WXK_DOWN: - self.camera.moveRelative(ogre.Vector3(0,0,d)) - elif event.m_keyCode == wx.WXK_PAGEUP: - self.camera.moveRelative(ogre.Vector3(0,d,0)) - elif event.m_keyCode == wx.WXK_PAGEDOWN: - self.camera.moveRelative(ogre.Vector3(0,-d,0)) - elif event.m_keyCode == 84: # 84 = T - if self.filtering == ogre.TFO_BILINEAR: - self.filtering = ogre.TFO_TRILINEAR - self.Aniso = 1 - elif self.filtering == ogre.TFO_TRILINEAR: - self.filtering = ogre.TFO_ANISOTROPIC - self.Aniso = 8 - else: - self.filtering = ogre.TFO_BILINEAR - self.Aniso = 1 - ogre.MaterialManager.getSingleton().setDefaultTextureFiltering(self.filtering) - ogre.MaterialManager.getSingleton().setDefaultAnisotropy(self.Aniso) - elif event.m_keyCode == 82: # 82 = R - detailsLevel = [ ogre.PM_SOLID, - ogre.PM_WIREFRAME, - ogre.PM_POINTS ] - self.sceneDetailIndex = (self.sceneDetailIndex + 1) % len(detailsLevel) - self.camera.polygonMode=detailsLevel[self.sceneDetailIndex] - elif event.m_keyCode == 81: # Q, wx.WXK_LEFT: - self.enablephysics = not self.enablephysics \ No newline at end of file + def free(self): + for box in self.boxes: + try: + box.node.detachAllObjects() + self.sceneManager.destroySceneNode(box.node.getName()) + except: + pass + try: + self.sceneManager.destroyEntity(box.entity) + except: + pass + self.boxes = [] + + try: + self.sceneManager.destroyAllManualObjects() + except: + pass + try: + self.objnode.detachAllObjects() + self.sceneManager.destroySceneNode(self.objnode.getName()) + except: + pass + try: + self.sceneManager.destroyEntity(self.objentity) + except: + pass + + def populateScene(self): + self.sceneManager.AmbientLight = ogre.ColourValue(0.7, 0.7, 0.7 ) + self.sceneManager.setShadowTechnique(ogre.ShadowTechnique.SHADOWTYPE_STENCIL_ADDITIVE); + self.sceneManager.setSkyDome(True, 'mysimple/terraineditor/previewwindowsky', 4.0, 8.0) + + #self.MainLight = self.sceneManager.createLight('MainLight') + #self.MainLight.setPosition (ogre.Vector3(20, 80, 130)) + + # add some fog + self.sceneManager.setFog(ogre.FOG_EXP, ogre.ColourValue.White, 0.0002) + + # create a floor Mesh + plane = ogre.Plane() + plane.normal = ogre.Vector3(0, 1, 0) + plane.d = 200 + uuid = str(randomID()) + ogre.MeshManager.getSingleton().createPlane(uuid + 'FloorPlane', "General", plane, 200000.0, 200000.0, + 20, 20, True, 1, 50.0, 50.0,ogre.Vector3(0, 0, 1), + ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, + ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, + True, True) + + # create floor entity + entity = self.sceneManager.createEntity(uuid+'floor', uuid + 'FloorPlane') + entity.setMaterialName('mysimple/terraineditor/previewwindowfloor') + self.sceneManager.getRootSceneNode().createChildSceneNode().attachObject(entity) + + def updateCamera(self): + return + if not self.objnode is None: + self.radius = self.objentity.getBoundingRadius() * 2 + height = self.objentity.getBoundingBox().getMaximum().z + #pos = self.objnode.getPosition() + ogre.Vector3(0, height*0.4, 0) + # always look to the center! + pos = self.objnode.getPosition() + ogre.Vector3(0, height*0.4, 0) + (self.objentity.getBoundingBox().getMinimum() + self.objentity.getBoundingBox().getMaximum() ) / 2 + dx = math.cos(self.camalpha) * self.radius + dy = math.sin(self.camalpha) * self.radius + self.camera.setPosition(pos - ogre.Vector3(dx, -5, dy)) + self.camera.lookAt(pos + ogre.Vector3(0, height / 2, 0)) + + # disable auto rotation + #if self.dragging == False: + # self.camalpha += math.pi / 720 + if self.camalpha >= 360: + self.camalpha -= 360 + + + def OnFrameStarted(self): + self.updateCamera() + wxOgreWindow.OnFrameStarted(self) + + def onMouseEvent(self,event): + self.SetFocus() + width, height, a, b, c = self.renderWindow.getMetrics() + + if event.RightDown(): #Precedes dragging + self.StartDragX, self.StartDragY = event.GetPosition() #saves position of initial click + if event.GetWheelRotation() != 0: + zfactor = 0.001 + if event.ShiftDown(): + zfactor = 0.01 + zoom = zfactor * -event.GetWheelRotation() + self.camera.moveRelative(ogre.Vector3(0,0, zoom)) + + if event.Dragging() and event.RightIsDown() and event.ControlDown(): + x,y = event.GetPosition() + dx = self.StartDragX - x + dy = self.StartDragY - y + self.StartDragX, self.StartDragY = x, y + if event.ShiftDown(): + dx = float(dx) / 10 + dy = float(dy) / 10 + else: + dx = float(dx) / 50 + dy = float(dy) / 50 + self.camera.moveRelative(ogre.Vector3(dx,-dy,0)) + + elif event.Dragging() and event.RightIsDown(): #Dragging with RMB + x,y = event.GetPosition() + dx = self.StartDragX - x + dy = self.StartDragY - y + self.StartDragX, self.StartDragY = x, y + + self.camera.yaw(ogre.Degree(dx/3.0)) + self.camera.pitch(ogre.Degree(dy/3.0)) + if event.LeftDown(): + #self.selectnew(event) + self.StartDragLeftX, self.StartDragLeftY = event.GetPosition() #saves position of initial click + zfactor = 0.1 + if event.ShiftDown(): + zfactor = 5 + zoom = zfactor * -event.GetWheelRotation() + self.camera.moveRelative(ogre.Vector3(0,0, zoom)) + + def onKeyDown(self,event): + #print event.m_keyCode + d = 3 + if event.ShiftDown(): + d = 10 + if event.m_keyCode == 65: # A, wx.WXK_LEFT: + self.camera.moveRelative(ogre.Vector3(-d,0,0)) + elif event.m_keyCode == 68: # D, wx.WXK_RIGHT: + self.camera.moveRelative(ogre.Vector3(d,0,0)) + elif event.m_keyCode == 87: # W ,wx.WXK_UP: + self.camera.moveRelative(ogre.Vector3(0,0,-d)) + elif event.m_keyCode == 83: # S, wx.WXK_DOWN: + self.camera.moveRelative(ogre.Vector3(0,0,d)) + elif event.m_keyCode == wx.WXK_PAGEUP: + self.camera.moveRelative(ogre.Vector3(0,d,0)) + elif event.m_keyCode == wx.WXK_PAGEDOWN: + self.camera.moveRelative(ogre.Vector3(0,-d,0)) + elif event.m_keyCode == 84: # 84 = T + if self.filtering == ogre.TFO_BILINEAR: + self.filtering = ogre.TFO_TRILINEAR + self.Aniso = 1 + elif self.filtering == ogre.TFO_TRILINEAR: + self.filtering = ogre.TFO_ANISOTROPIC + self.Aniso = 8 + else: + self.filtering = ogre.TFO_BILINEAR + self.Aniso = 1 + ogre.MaterialManager.getSingleton().setDefaultTextureFiltering(self.filtering) + ogre.MaterialManager.getSingleton().setDefaultAnisotropy(self.Aniso) + elif event.m_keyCode == 82: # 82 = R + detailsLevel = [ ogre.PM_SOLID, + ogre.PM_WIREFRAME, + ogre.PM_POINTS ] + self.sceneDetailIndex = (self.sceneDetailIndex + 1) % len(detailsLevel) + self.camera.polygonMode=detailsLevel[self.sceneDetailIndex] + elif event.m_keyCode == 81: # Q, wx.WXK_LEFT: + self.enablephysics = not self.enablephysics \ No newline at end of file Modified: trunk/lib_common/roreditor/RoRTerrainOgreWindow.py =================================================================== --- trunk/lib_common/roreditor/RoRTerrainOgreWindow.py 2007-09-20 08:15:43 UTC (rev 181) +++ trunk/lib_common/roreditor/RoRTerrainOgreWindow.py 2007-09-20 08:48:08 UTC (rev 182) @@ -176,8 +176,9 @@ def SceneInitialisation(self): hasparent = (not self.sceneManager is None) if not hasparent: - #TODO This section is not platform independent, needs to be fixed. - addresources = [self.rordir+"\\data\\terrains",self.rordir+"\\data\\trucks",self.rordir+"\\data\\objects"] + addresources = [os.path.join(self.rordir,'data', 'terrains'), + os.path.join(self.rordir,'data', 'trucks'), + os.path.join(self.rordir,'data', 'objects')] # only init things in the main window, not in shared ones! # setup resources for r in addresources: Modified: trunk/lib_common/roreditor/RoRTruckOgreWindow.py =================================================================== --- trunk/lib_common/roreditor/RoRTruckOgreWindow.py 2007-09-20 08:15:43 UTC (rev 181) +++ trunk/lib_common/roreditor/RoRTruckOgreWindow.py 2007-09-20 08:48:08 UTC (rev 182) @@ -84,9 +84,8 @@ pass def SceneInitialisation(self): - - #TODO This section is not platform independent, needs to be fixed. - addresources = [self.rordir+"\\data\\trucks",self.rordir+"\\data\\objects"] + addresources = [os.path.join(self.rordir,'data', 'trucks'), + os.path.join(self.rordir,'data', 'objects')] # only init things in the main window, not in shared ones! # setup resources for r in addresources: Modified: trunk/lib_common/roreditor/RoRTruckUVOgreWindow.py =================================================================== --- trunk/lib_common/roreditor/RoRTruckUVOgreWindow.py 2007-09-20 08:15:43 UTC (rev 181) +++ trunk/lib_common/roreditor/RoRTruckUVOgreWindow.py 2007-09-20 08:48:08 UTC (rev 182) @@ -1,6 +1,6 @@ #Thomas Fischer 31/05/2007, th...@th... import wx, os, os.path -import ogre.renderer.OGRE as ogre +import ogre.renderer.OGRE as ogre from ror.truckparser import * from ror.logger import log @@ -17,280 +17,279 @@ IMGSCALE = 20 class RoRTruckUVOgreWindow(wxOgreWindow): - def __init__(self, parent, ID, size = wx.Size(200,200), **kwargs): - self.parent = parent - self.rordir = getSettingsManager().getSetting("RigsOfRods", "BasePath") - self.sceneManager = None - self.trucktree = None - self.clearlist = {'entity':[]} - self.initScene() - wxOgreWindow.__init__(self, parent, ID, size = size, **kwargs) + def __init__(self, parent, ID, size = wx.Size(200,200), **kwargs): + self.parent = parent + self.rordir = getSettingsManager().getSetting("RigsOfRods", "BasePath") + self.sceneManager = None + self.trucktree = None + self.clearlist = {'entity':[]} + self.initScene() + wxOgreWindow.__init__(self, parent, ID, size = size, **kwargs) - def initScene(self): - if not self.sceneManager is None: - self.sceneManager.destroyAllManualObjects() - self.EntityCount = 0 - self.bodies=[] - - # try to clear things up - try: - if self.nodes != {}: - for n in self.nodes: - n[0].detachAllObjects() - self.sceneManager.destroySceneNode(n[0].getName()) - except: - pass - try: - for e in self.clearlist['entity']: - print e - self.sceneManager.destroyEntity(e) - except: - pass - - self.nodes = {} - self.beams = {} - self.shocks = {} - self.submeshs = {} - self.selection = None - self.enablephysics = False + def initScene(self): + if not self.sceneManager is None: + self.sceneManager.destroyAllManualObjects() + self.EntityCount = 0 + self.bodies=[] - - def __del__ (self): - # delete the world when we're done. - self.sceneManager.destroyEntity('groundent') - #ogre.ResourceGroupManager.getSingleton().undeclareResource("UVGroundPlane", "General") - - del self.bodies + # try to clear things up + try: + if self.nodes != {}: + for n in self.nodes: + n[0].detachAllObjects() + self.sceneManager.destroySceneNode(n[0].getName()) + except: + pass + try: + for e in self.clearlist['entity']: + print e + self.sceneManager.destroyEntity(e) + except: + pass - - def OnFrameStarted(self): - pass - - def OnFrameEnded(self): - pass + self.nodes = {} + self.beams = {} + self.shocks = {} + self.submeshs = {} + self.selection = None + self.enablephysics = False - def SceneInitialisation(self): - - #TODO This section is not platform independent, needs to be fixed. - addresources = [self.rordir+"\\data\\trucks",self.rordir+"\\data\\objects"] - # only init things in the main window, not in shared ones! - # setup resources - for r in addresources: - ogre.ResourceGroupManager.getSingleton().addResourceLocation(r, "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/packs/OgreCore.zip", "Zip", "Bootstrap", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media", "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/materials", "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().addResourceLocation("media/models", "FileSystem", "General", False) - ogre.ResourceGroupManager.getSingleton().initialiseAllResourceGroups() + def __del__ (self): + # delete the world when we're done. + self.sceneManager.destroyEntity('groundent') + #ogre.ResourceGroupManager.getSingleton().undeclareResource("UVGroundPlane", "General") - #get the scenemanager - self.sceneManager = getOgreManager().createSceneManager(ogre.ST_GENERIC) + del self.bodies - # create a camera - self.camera = self.sceneManager.createCamera('Camera') - self.camera.setAutoAspectRatio(True) - self.camera.setProjectionType(Ogre.ProjectionType.PT_ORTHOGRAPHIC) - self.camera.setFarClipDistance(9999) - self.camera.setNearClipDistance(30) - self.camera.setPosition(Ogre.Vector3(0,100,-0.1)) - self.camera.lookAt(Ogre.Vector3(0,0,0)) - # create the Viewport"... [truncated message content] |
From: <ror...@us...> - 2008-03-13 00:13:00
|
Revision: 194 http://roreditor.svn.sourceforge.net/roreditor/?rev=194&view=rev Author: rorthomas Date: 2008-03-12 17:12:58 -0700 (Wed, 12 Mar 2008) Log Message: ----------- some parts working again. added section'ed Object Tree Modified Paths: -------------- trunk/lib_common/ror/SimpleTruckRepresentation.py trunk/lib_common/ror/rorcommon.py trunk/lib_common/ror/truckparser.py trunk/lib_common/roreditor/GUIObjectTree.py trunk/lib_common/roreditor/RoRObjectPreviewOgreWindow.py Modified: trunk/lib_common/ror/SimpleTruckRepresentation.py =================================================================== --- trunk/lib_common/ror/SimpleTruckRepresentation.py 2008-03-12 23:28:56 UTC (rev 193) +++ trunk/lib_common/ror/SimpleTruckRepresentation.py 2008-03-13 00:12:58 UTC (rev 194) @@ -8,10 +8,10 @@ from ror.rorcommon import * def createTruckMesh(sceneManager, fn, uuid): - if not os.path.isfile(fn): - #print "truck file not found: " + fn - log().error("truck file not found: %s" % fn) - return + #if not os.path.isfile(fn): + # #print "truck file not found: " + fn + # log().error("truck file not found: %s" % fn) + # return p = rorparser() p.parse(fn) if not 'nodes' in p.tree.keys() or not 'beams' in p.tree.keys(): Modified: trunk/lib_common/ror/rorcommon.py =================================================================== --- trunk/lib_common/ror/rorcommon.py 2008-03-12 23:28:56 UTC (rev 193) +++ trunk/lib_common/ror/rorcommon.py 2008-03-13 00:12:58 UTC (rev 194) @@ -1,4 +1,4 @@ -import sys, os, os.path, glob +import sys, os, os.path, glob, copy import wx from random import Random from logger import log Modified: trunk/lib_common/ror/truckparser.py =================================================================== --- trunk/lib_common/ror/truckparser.py 2008-03-12 23:28:56 UTC (rev 193) +++ trunk/lib_common/ror/truckparser.py 2008-03-13 00:12:58 UTC (rev 194) @@ -3,932 +3,926 @@ import sys, os, os.path, tempfile, pickle from ror.logger import log from ror.settingsManager import getSettingsManager +from ror.rorcommon import * - # default values: required:True - # please note: unkown args are marked with 'WHAT IS THIS' + # default values: required:True + # please note: unkown args are marked with 'WHAT IS THIS' class rorparser: - # This specifies all valid commands - commands = { - # set_beam_defaults changes the beams (but also the hydros and ropes) default characteristics that will be used for the beams declared after the line. You can use this line many times to make different groups of beams that have different characteristics (e.g. stronger chassis, softer cab, etc.). This method is better than the globeams command that is now deprecated. The parameters comes on the same line, after set_beam_defaults. You can use the first parameters (most usefull) and safely ignore the last parameters. - 'set_beam_defaults':[ - # Spring constant (use -1 for the default, which is 9000000) - {'name':'spring constant','type':'float'}, - # Damping constant (use -1 for the default, which is 12000) - {'name':'damping constant','type':'float'}, - # Deformation threshold constant (use -1 for the default, which is 400000) - {'name':'deformation threshold','type':'float'}, - # Breaking thresold constant (use -1 for the default, which is 1000000) - {'name':'breaking thresold','type':'float'}, - # Beam diameter (use -1 for the default, which is 0.05) - {'name':'beam diameter','type':'float', 'required':False}, - # Beam material (default: tracks/beam) - {'name':'beam material','type':'string', 'required':False}, - ], + # This specifies all valid commands + commands = { + # set_beam_defaults changes the beams (but also the hydros and ropes) default characteristics that will be used for the beams declared after the line. You can use this line many times to make different groups of beams that have different characteristics (e.g. stronger chassis, softer cab, etc.). This method is better than the globeams command that is now deprecated. The parameters comes on the same line, after set_beam_defaults. You can use the first parameters (most usefull) and safely ignore the last parameters. + 'set_beam_defaults':[ + # Spring constant (use -1 for the default, which is 9000000) + {'name':'spring constant','type':'float'}, + # Damping constant (use -1 for the default, which is 12000) + {'name':'damping constant','type':'float'}, + # Deformation threshold constant (use -1 for the default, which is 400000) + {'name':'deformation threshold','type':'float'}, + # Breaking thresold constant (use -1 for the default, which is 1000000) + {'name':'breaking thresold','type':'float'}, + # Beam diameter (use -1 for the default, which is 0.05) + {'name':'beam diameter','type':'float', 'required':False}, + # Beam material (default: tracks/beam) + {'name':'beam material','type':'string', 'required':False}, + ], - # Enables collision between wheels and the textured surfaces of a truck. - 'rollon':[], + # Enables collision between wheels and the textured surfaces of a truck. + 'rollon':[], - # Forwards the commandkeys pressed while riding a truck to loads in close proximity. It is used to remote control the commands of a load. The load must have the "importcommands" tag. - 'forwardcommands':[], + # Forwards the commandkeys pressed while riding a truck to loads in close proximity. It is used to remote control the commands of a load. The load must have the "importcommands" tag. + 'forwardcommands':[], - # Enables a load to receive commandkeys from a manned vehicle in close proximity. The controlling vehicle must have the "forwardcommands" tag. The load only receives the keys that are pressed by the player, it must contain a commands section. Commands section for loads is defined in the same manner as in manned trucks. - 'importcommands':[], + # Enables a load to receive commandkeys from a manned vehicle in close proximity. The controlling vehicle must have the "forwardcommands" tag. The load only receives the keys that are pressed by the player, it must contain a commands section. Commands section for loads is defined in the same manner as in manned trucks. + 'importcommands':[], - # the triangles backsides of the submesh will be black instead of see-through. - 'backmesh':[], + # the triangles backsides of the submesh will be black instead of see-through. + 'backmesh':[], - # rescue-truck? - 'rescuer':[], + # rescue-truck? + 'rescuer':[], - # end of file - 'end':[], + # end of file + 'end':[], - } - - ### This specifies all valid sections und subsections - sections = { - # This section is the only that is not introduced by a keyword. It is the name of the truck, and it must absolutely be the first line of the file. e.g. - 'title':[ - {'name':'title','type':'string'}, - ], + } + + ### This specifies all valid sections und subsections + sections = { + # This section is the only that is not introduced by a keyword. It is the name of the truck, and it must absolutely be the first line of the file. e.g. + 'title':[ + {'name':'title','type':'string'}, + ], - # This section is very special and should not be used for most designs. It was created to make the bridge. It allows you to alter the default mechanical and visual beam properties. The parameters are: default stress at which beams deforms (in Newtons), default stress at which beams break, default beams diameter (in meter), default beams material. This section is deprecated and should not be used for truck designs. Use the more powerfull set_beam_defaults instead. - 'globals':[ - {'name':'dry mass', 'type':'float'}, - {'name':'cargo mass', 'type':'float'}, - {'name':'material', 'type':'string'}, - ], + # This section is very special and should not be used for most designs. It was created to make the bridge. It allows you to alter the default mechanical and visual beam properties. The parameters are: default stress at which beams deforms (in Newtons), default stress at which beams break, default beams diameter (in meter), default beams material. This section is deprecated and should not be used for truck designs. Use the more powerfull set_beam_defaults instead. + 'globals':[ + {'name':'dry mass', 'type':'float'}, + {'name':'cargo mass', 'type':'float'}, + {'name':'material', 'type':'string'}, + ], - # This section is very special and should not be used for most designs. It was created to make the bridge. It allows you to alter the default mechanical and visual beam properties. The parameters are: default stress at which beams deforms (in Newtons), default stress at which beams break, default beams diameter (in meter), default beams material. This section is deprecated and should not be used for truck designs. Use the more powerfull set_beam_defaults instead. - 'globeams':[ - #default stress at which beams deforms (in Newtons) - {'name':'deform', 'type':'float'}, - #default stress at which beams break - {'name':'break', 'type':'float'}, - #default beams diameter (in meter) - {'name':'diameter', 'type':'float'}, - #default beams material - {'name':'material', 'type':'string'}, - ], + # This section is very special and should not be used for most designs. It was created to make the bridge. It allows you to alter the default mechanical and visual beam properties. The parameters are: default stress at which beams deforms (in Newtons), default stress at which beams break, default beams diameter (in meter), default beams material. This section is deprecated and should not be used for truck designs. Use the more powerfull set_beam_defaults instead. + 'globeams':[ + #default stress at which beams deforms (in Newtons) + {'name':'deform', 'type':'float'}, + #default stress at which beams break + {'name':'break', 'type':'float'}, + #default beams diameter (in meter) + {'name':'diameter', 'type':'float'}, + #default beams material + {'name':'material', 'type':'string'}, + ], - # The engine section contains the engine parameters. - 'engine':[ - {'name':'min rpm', 'type':'float'}, - {'name':'max rpm', 'type':'float'}, - #torque (flat torque model, usually correct for large intercooled turbo diesels). This defines the engine power! - {'name':'torque', 'type':'float'}, - #differential ratio (a global gear conversion ratio) - {'name':'differential ratio', 'type':'float'}, - {'name':'rear gear', 'type':'float'}, - {'name':'first gear', 'type':'float'}, - {'name':'second gear', 'type':'float'}, - {'name':'third gear', 'type':'float','required':False}, - {'name':'fourth gear', 'type':'float','required':False}, - {'name':'fifth gear', 'type':'float','required':False}, - {'name':'sixth gear', 'type':'float','required':False}, - {'name':'seventh gear', 'type':'float','required':False}, - {'name':'eighth gear', 'type':'float','required':False}, - {'name':'nineth gear', 'type':'float','required':False}, - {'name':'tenth rpm', 'type':'float','required':False}, - {'name':'eleventh rpm', 'type':'float','required':False}, - {'name':'twelveth rpm', 'type':'float','required':False}, - {'name':'thirteenth rpm', 'type':'float','required':False}, - {'name':'fourteenth rpm', 'type':'float','required':False}, - {'name':'fifteenth rpm', 'type':'float','required':False}, - {'name':'sixteenth rpm', 'type':'float','required':False}, - #The last gear must be followed by a -1 value. - {'name':'ending argument', 'type':'float','required':False}, - ], + # The engine section contains the engine parameters. + 'engine':[ + {'name':'min rpm', 'type':'float'}, + {'name':'max rpm', 'type':'float'}, + #torque (flat torque model, usually correct for large intercooled turbo diesels). This defines the engine power! + {'name':'torque', 'type':'float'}, + #differential ratio (a global gear conversion ratio) + {'name':'differential ratio', 'type':'float'}, + {'name':'rear gear', 'type':'float'}, + {'name':'first gear', 'type':'float'}, + {'name':'second gear', 'type':'float'}, + {'name':'third gear', 'type':'float','required':False}, + {'name':'fourth gear', 'type':'float','required':False}, + {'name':'fifth gear', 'type':'float','required':False}, + {'name':'sixth gear', 'type':'float','required':False}, + {'name':'seventh gear', 'type':'float','required':False}, + {'name':'eighth gear', 'type':'float','required':False}, + {'name':'nineth gear', 'type':'float','required':False}, + {'name':'tenth rpm', 'type':'float','required':False}, + {'name':'eleventh rpm', 'type':'float','required':False}, + {'name':'twelveth rpm', 'type':'float','required':False}, + {'name':'thirteenth rpm', 'type':'float','required':False}, + {'name':'fourteenth rpm', 'type':'float','required':False}, + {'name':'fifteenth rpm', 'type':'float','required':False}, + {'name':'sixteenth rpm', 'type':'float','required':False}, + #The last gear must be followed by a -1 value. + {'name':'ending argument', 'type':'float','required':False}, + ], - # Engoption sets optional parameters to the engine, mainly for car engines. Parameters are: - 'engoption':[ - # Engine inertia: the default game value is 10.0, which is correct for a large diesel engine, but for smaller engines you might want smaller values, like 1.0 or 0.5 for small athmospheric engines. - {'name':'Engine inertia', 'type':'float'}, + # Engoption sets optional parameters to the engine, mainly for car engines. Parameters are: + 'engoption':[ + # Engine inertia: the default game value is 10.0, which is correct for a large diesel engine, but for smaller engines you might want smaller values, like 1.0 or 0.5 for small athmospheric engines. + {'name':'Engine inertia', 'type':'float'}, - # Engine type: valid types are t for truck engine and c for car engine. This changes engine sound and other engine characteristics. - {'name':'Engine type', 'type':'string', - 'validvalues':[ - 'c', # truck engine - 't', # car engine - ]}, - ], + # Engine type: valid types are t for truck engine and c for car engine. This changes engine sound and other engine characteristics. + {'name':'Engine type', 'type':'string', + 'validvalues':[ + 'c', # truck engine + 't', # car engine + ]}, + ], - # This allows you to change the default braking force value (the default is 30000), generally to a lower value for smaller trucks and cars. - 'brakes':[ - # braking force - {'name':'braking force', 'type':'float'}, - ], + # This allows you to change the default braking force value (the default is 30000), generally to a lower value for smaller trucks and cars. + 'brakes':[ + # braking force + {'name':'braking force', 'type':'float'}, + ], - # This section is important. It helps to position the truck in space, by defining a local direction reference. For example this is used to measure the pitch and the roll of the truck. The three parameters are node numbers (defined in the next section). The first if the reference and may be anywhere, the second must be behind the first (if you look at the front of the truck, it is hidden behind the first), and the third must be at the left of the first (if you look to the right of the truck, it is hidden by the first) - 'cameras':[ - # The first if the reference and may be anywhere - {'name':'center node', 'type':'node'}, - # The second must be behind the first - {'name':'back node', 'type':'node'}, - # The third must be at the left of the first - {'name':'left node', 'type':'node'}, - ], + # This section is important. It helps to position the truck in space, by defining a local direction reference. For example this is used to measure the pitch and the roll of the truck. The three parameters are node numbers (defined in the next section). The first if the reference and may be anywhere, the second must be behind the first (if you look at the front of the truck, it is hidden behind the first), and the third must be at the left of the first (if you look to the right of the truck, it is hidden by the first) + 'cameras':[ + # The first if the reference and may be anywhere + {'name':'center node', 'type':'node'}, + # The second must be behind the first + {'name':'back node', 'type':'node'}, + # The third must be at the left of the first + {'name':'left node', 'type':'node'}, + ], - # With this section begins the structural description. Each line defines a node. The first parameter is the node number, and must absolutely be consecutive. The three following parameters are the x,y,z coordinates, in meter. You can attach an optional option to a node by adding a single character. Recognized options are: - 'nodes':[ - {'name':'id', 'type':'int'}, - {'name':'x', 'type':'float'}, - {'name':'y', 'type':'float'}, - {'name':'z', 'type':'float'}, - {'name':'options', 'type':'string', - 'required':False, - 'default':'n', - 'validvalues':[ - 'n', # normal node, nothing special - 'l', # this node bears a part of the cargo load - 'f', # this node has extra friction with the ground (usefull for feets) - 'x', # this node is the exhaust point (requires a "y" node) - 'y', # exhaust reference point, this point is at the opposite of the direction of the exhaust - 'c', # this node will not detect contact with ground (can be used for optimization, on inner chassis parts) - 'h', # this node is a hook point (e.g. the extremity of a crane) - 'e', # this node is a terrain editing point (used in the terrain editor truck) - 'b', # this node is assigned an extra buoyancy force (experimental) - ]}, - ], + # With this section begins the structural description. Each line defines a node. The first parameter is the node number, and must absolutely be consecutive. The three following parameters are the x,y,z coordinates, in meter. You can attach an optional option to a node by adding a single character. Recognized options are: + 'nodes':[ + {'name':'id', 'type':'int'}, + {'name':'x', 'type':'float'}, + {'name':'y', 'type':'float'}, + {'name':'z', 'type':'float'}, + {'name':'options', 'type':'string', + 'required':False, + 'default':'n', + 'validvalues':[ + 'n', # normal node, nothing special + 'l', # this node bears a part of the cargo load + 'f', # this node has extra friction with the ground (usefull for feets) + 'x', # this node is the exhaust point (requires a "y" node) + 'y', # exhaust reference point, this point is at the opposite of the direction of the exhaust + 'c', # this node will not detect contact with ground (can be used for optimization, on inner chassis parts) + 'h', # this node is a hook point (e.g. the extremity of a crane) + 'e', # this node is a terrain editing point (used in the terrain editor truck) + 'b', # this node is assigned an extra buoyancy force (experimental) + ]}, + ], - # Fixes are nodes that are fixed in place. That means that once put in place in the terrain, they will never move, whatever happens. This is usefull to make fixed scenery elements from beams, like bridges. Just add the node number that you want to fix. - 'fixes':[ - # node number that you want to fix. - {'name':'node', 'type':'node'}, - ], + # Fixes are nodes that are fixed in place. That means that once put in place in the terrain, they will never move, whatever happens. This is usefull to make fixed scenery elements from beams, like bridges. Just add the node number that you want to fix. + 'fixes':[ + # node number that you want to fix. + {'name':'node', 'type':'node'}, + ], - # This section defines all the beams connecting nodes. Each line describes a beam. The two first parameters are the node number of the two connected nodes. Order has no importance. There is an optional 3rd parameter, composed of a single character. - 'beams':[ - {'name':'first node', 'type':'node'}, - {'name':'second node', 'type':'node'}, - {'name':'options', 'type':'string', - 'required':False, - 'default':'n', - 'validvalues':[ - 'n', # visible, default - 'v', # visible, default - 'i', # this beam is invisible. Very usefull to hide "cheating" structural beam, or to improve performances once the truck is textured. - 'r', # this beam is a rope (opposes no force to compression) - ]} - ], + # This section defines all the beams connecting nodes. Each line describes a beam. The two first parameters are the node number of the two connected nodes. Order has no importance. There is an optional 3rd parameter, composed of a single character. + 'beams':[ + {'name':'first node', 'type':'node'}, + {'name':'second node', 'type':'node'}, + {'name':'options', 'type':'string', + 'required':False, + 'default':'n', + 'validvalues':[ + 'n', # visible, default + 'v', # visible, default + 'i', # this beam is invisible. Very usefull to hide "cheating" structural beam, or to improve performances once the truck is textured. + 'r', # this beam is a rope (opposes no force to compression) + ]} + ], - # Shocks can be seen as tunable beams, useful for suspensions. - 'shocks':[ - # the two nodes connected by the shock - {'name':'first node', 'type':'node'}, - {'name':'second node', 'type':'node'}, - # spring rate: the stiffness - {'name':'spring rate', 'type':'float'}, - # to adjust the amount of rebound: the best value is given by 2*sqrt(suspended mass*spring) - {'name':'dampening', 'type':'float'}, - # shortbound, longbound: defines the amount of deformation the shock can support (beyond, it becomes rigid as a standard beam) when shortened and lengthened - {'name':'shortbound', 'type':'float'}, - {'name':'longbound', 'type':'float'}, - # allows to compress or depress the suspension (leave it to 1.0 for most cases). - {'name':'precomp', 'type':'float'}, - # You can make the shocks stability-active with optional parameters: - {'name':'options', 'type':'string', - 'required':False, - 'default':None, - 'validvalues':[ - 'n', # normal - 'l', # to make a left-hand active shock - 'r', # to make a right-hand active shock - 'i', # to make the shock invisible (AVAILABLE FROM VERSION 0.29). - ]} - ], + # Shocks can be seen as tunable beams, useful for suspensions. + 'shocks':[ + # the two nodes connected by the shock + {'name':'first node', 'type':'node'}, + {'name':'second node', 'type':'node'}, + # spring rate: the stiffness + {'name':'spring rate', 'type':'float'}, + # to adjust the amount of rebound: the best value is given by 2*sqrt(suspended mass*spring) + {'name':'dampening', 'type':'float'}, + # shortbound, longbound: defines the amount of deformation the shock can support (beyond, it becomes rigid as a standard beam) when shortened and lengthened + {'name':'shortbound', 'type':'float'}, + {'name':'longbound', 'type':'float'}, + # allows to compress or depress the suspension (leave it to 1.0 for most cases). + {'name':'precomp', 'type':'float'}, + # You can make the shocks stability-active with optional parameters: + {'name':'options', 'type':'string', + 'required':False, + 'default':None, + 'validvalues':[ + 'n', # normal + 'l', # to make a left-hand active shock + 'r', # to make a right-hand active shock + 'i', # to make the shock invisible (AVAILABLE FROM VERSION 0.29). + ]} + ], - # The hydros section concerns only the direction actuactors! They are beams that changes of length depending on the direction command. - 'hydros':[ - # two node numbers - {'name':'first node', 'type':'node'}, - {'name':'second node', 'type':'node'}, - # lenghtening factor (negative or positive depending on wether you want to lenghten or shorten when turning left or the contrary) - {'name':'lenghtening factor', 'type':'float'}, - # optional flags - {'name':'options', 'type':'string', - 'required':False, - 'default':None, - 'validvalues':[ - 's', # WHAT IS THIS? - 'n', # normal - 'i', # make the hydro invisible. - ]} - ], + # The hydros section concerns only the direction actuactors! They are beams that changes of length depending on the direction command. + 'hydros':[ + # two node numbers + {'name':'first node', 'type':'node'}, + {'name':'second node', 'type':'node'}, + # lenghtening factor (negative or positive depending on wether you want to lenghten or shorten when turning left or the contrary) + {'name':'lenghtening factor', 'type':'float'}, + # optional flags + {'name':'options', 'type':'string', + 'required':False, + 'default':None, + 'validvalues':[ + 's', # WHAT IS THIS? + 'n', # normal + 'i', # make the hydro invisible. + ]} + ], - # The commands section describes the "real" hydros, those you command with the function keys. They are like beams, but their length varies depending with the function keys you press. - 'commands':[ - # two node numbers - {'name':'first node', 'type':'node'}, - {'name':'second node', 'type':'node'}, - # speed rate (how fast the hydro will change length) - {'name':'speed rate', 'type':'float'}, - # the shortest length (1.0 is the startup length) - {'name':'shortest length', 'type':'float'}, - # the longest length (1.0 is the startup length) - {'name':'longest length', 'type':'float'}, - # the number of the shortening function key (between 1 and 12) - {'name':'shortening key', 'type':'int'}, - # the number of the lengthtening function key (between 1 and 12) - {'name':'lengthtening key', 'type':'int'}, - # optional flags - {'name':'options', 'type':'string', - 'required':False, - 'default':None, - 'validvalues':[ - 'i', # make the hydro invisible. - 'r', # WHAT IS THIS - 'n', # WHAT IS THIS - 'v', # WHAT IS THIS - ]} - ], + # The commands section describes the "real" hydros, those you command with the function keys. They are like beams, but their length varies depending with the function keys you press. + 'commands':[ + # two node numbers + {'name':'first node', 'type':'node'}, + {'name':'second node', 'type':'node'}, + # speed rate (how fast the hydro will change length) + {'name':'speed rate', 'type':'float'}, + # the shortest length (1.0 is the startup length) + {'name':'shortest length', 'type':'float'}, + # the longest length (1.0 is the startup length) + {'name':'longest length', 'type':'float'}, + # the number of the shortening function key (between 1 and 12) + {'name':'shortening key', 'type':'int'}, + # the number of the lengthtening function key (between 1 and 12) + {'name':'lengthtening key', 'type':'int'}, + # optional flags + {'name':'options', 'type':'string', + 'required':False, + 'default':None, + 'validvalues':[ + 'i', # make the hydro invisible. + 'r', # WHAT IS THIS + 'n', # WHAT IS THIS + 'v', # WHAT IS THIS + ]} + ], - # Rotators are alternate commands(hydros) that allows you to do turntables, like in the base of a rotating crane. They use 10 reference nodes: and Then, in a similar way to commands, comes the , and the numbers of the left and right function keys. - 'rotators':[ - # 2 nodes to define the axis of rotation - {'name':'axis1 node', 'type':'node'}, - {'name':'axis2 node', 'type':'node'}, - # 4 nodes (must be a square, centered with the axis), to define the baseplate - {'name':'base1 node', 'type':'node'}, - {'name':'base2 node', 'type':'node'}, - {'name':'base3 node', 'type':'node'}, - {'name':'base4 node', 'type':'node'}, - # 4 nodes (again, a square, centered with the axis) to define the rotating plate. - {'name':'rotbase1 node', 'type':'node'}, - {'name':'rotbase2 node', 'type':'node'}, - {'name':'rotbase3 node', 'type':'node'}, - {'name':'rotbase4 node', 'type':'node'}, - # speed rate (how fast the hydro will change length) - {'name':'speed rate', 'type':'float'}, - # the number of the left key (between 1 and 12) - {'name':'left key', 'type':'int'}, - # the number of the right key (between 1 and 12) - {'name':'right key', 'type':'int'}, - ], + # Rotators are alternate commands(hydros) that allows you to do turntables, like in the base of a rotating crane. They use 10 reference nodes: and Then, in a similar way to commands, comes the , and the numbers of the left and right function keys. + 'rotators':[ + # 2 nodes to define the axis of rotation + {'name':'axis1 node', 'type':'node'}, + {'name':'axis2 node', 'type':'node'}, + # 4 nodes (must be a square, centered with the axis), to define the baseplate + {'name':'base1 node', 'type':'node'}, + {'name':'base2 node', 'type':'node'}, + {'name':'base3 node', 'type':'node'}, + {'name':'base4 node', 'type':'node'}, + # 4 nodes (again, a square, centered with the axis) to define the rotating plate. + {'name':'rotbase1 node', 'type':'node'}, + {'name':'rotbase2 node', 'type':'node'}, + {'name':'rotbase3 node', 'type':'node'}, + {'name':'rotbase4 node', 'type':'node'}, + # speed rate (how fast the hydro will change length) + {'name':'speed rate', 'type':'float'}, + # the number of the left key (between 1 and 12) + {'name':'left key', 'type':'int'}, + # the number of the right key (between 1 and 12) + {'name':'right key', 'type':'int'}, + ], - # The contacters section lists the nodes that may contact with cab triangle. This concerns only contacts with other trucks or loads. You can easily omit this section at first. - 'contacters':[ - #node that may contact with cab triangle - {'name':'node', 'type':'node'}, - ], + # The contacters section lists the nodes that may contact with cab triangle. This concerns only contacts with other trucks or loads. You can easily omit this section at first. + 'contacters':[ + #node that may contact with cab triangle + {'name':'node', 'type':'node'}, + ], - # The help section gives the name material used for the help panel on the dashboard. This material must be defined elsewhere in the MaterialFile. This is optional. - 'help':[ - {'name':'dashboard material', 'type':'string'}, - ], + # The help section gives the name material used for the help panel on the dashboard. This material must be defined elsewhere in the MaterialFile. This is optional. + 'help':[ + {'name':'dashboard material', 'type':'string'}, + ], - # Ropes are special beams that have no compression strength (they can shorten easily) but have standard extension strength, like a cable or a chain. They have also another particularity: the second node can "grab" the nearest reachable ropable node with the 'O' key. Standard use is to use a chassis node as the first node, and a "free" node as the second node (free as in not attached by any other beam). The best example of this are the chains of the multibennes truck. - 'ropes':[ - {'name':'first node', 'type':'node'}, - {'name':'second node', 'type':'node'}, - ], + # Ropes are special beams that have no compression strength (they can shorten easily) but have standard extension strength, like a cable or a chain. They have also another particularity: the second node can "grab" the nearest reachable ropable node with the 'O' key. Standard use is to use a chassis node as the first node, and a "free" node as the second node (free as in not attached by any other beam). The best example of this are the chains of the multibennes truck. + 'ropes':[ + {'name':'first node', 'type':'node'}, + {'name':'second node', 'type':'node'}, + ], - # Ties are also special beams that have no compression strength (they can shorten easily) but have standard extension strength, like a cable or a chain. As the Ropes, they grab the nearest reachable ropable node with the 'O' key. But there is a twist: unlike the ropes, they disappear when not attached (because they have no extremity node at rest) and they automatically shorten until the extension forces reaches a thresold. They are very usefull to solidly strap a load to a chassis. The parameters are the number of the root node (the starting point of the beam), the maximum reach length, the rate of auto-shortening, the shortest length possible, and the last parameter... well... is probably not very usefull and should be kept as 1.0... You can make a tie invisible with the "i" option. - 'ties':[ - {'name':'root node', 'type':'node'}, - {'name':'max len', 'type':'float'}, - {'name':'rate', 'type':'float'}, - {'name':'short', 'type':'float'}, - {'name':'long', 'type':'float'}, - {'name':'options', 'type':'string', - 'required':False, - 'default':None, - 'validvalues':[ - 'i', # make the hydro invisible. - ]}, - ], + # Ties are also special beams that have no compression strength (they can shorten easily) but have standard extension strength, like a cable or a chain. As the Ropes, they grab the nearest reachable ropable node with the 'O' key. But there is a twist: unlike the ropes, they disappear when not attached (because they have no extremity node at rest) and they automatically shorten until the extension forces reaches a thresold. They are very usefull to solidly strap a load to a chassis. The parameters are the number of the root node (the starting point of the beam), the maximum reach length, the rate of auto-shortening, the shortest length possible, and the last parameter... well... is probably not very usefull and should be kept as 1.0... You can make a tie invisible with the "i" option. + 'ties':[ + {'name':'root node', 'type':'node'}, + {'name':'max len', 'type':'float'}, + {'name':'rate', 'type':'float'}, + {'name':'short', 'type':'float'}, + {'name':'long', 'type':'float'}, + {'name':'options', 'type':'string', + 'required':False, + 'default':None, + 'validvalues':[ + 'i', # make the hydro invisible. + ]}, + ], - # This section lists the nodes that can be catched by ropes or ties. Good use is to define some ropable nodes at the front and back of the truck to allow towing the truck. - 'ropables':[ - {'name':'node', 'type':'node'}, - ], + # This section lists the nodes that can be catched by ropes or ties. Good use is to define some ropable nodes at the front and back of the truck to allow towing the truck. + 'ropables':[ + {'name':'node', 'type':'node'}, + ], - # This section is important, it defines the wheels! The order in which the wheel are declared is important: each consecutive pair of wheel is grouped into an axle. - 'wheels':[ - # radius (in meter) - {'name':'radius', 'type':'float'}, - # width (in meter) - {'name':'width', 'type':'float'}, - # number of rays - {'name':'raycount', 'type':'int'}, - # the numbers of two existing nodes that defines the wheel axis (the second node must have a larger Z coordinate than the first) - {'name':'node1', 'type':'node'}, - {'name':'node2', 'type':'node'}, - # the number of a special rigidity node (see explanation about Axle Rigidity) or 9999 if it is not used - {'name':'rigidity node', 'type':'node'}, - # is the wheel braked (1) or not (0) (for directional braking, as found in planes, use 2 for left wheel and 3 for right wheel) - {'name':'braked', 'type':'int'}, - # is the wheel propulsed (1) or not (0) - {'name':'propulsed', 'type':'int'}, - # the number of a reference arm node for this wheel. This is where reaction torque is applied to the chassis. Should be on the rotation axis of the suspension arm. - {'name':'arm node', 'type':'node'}, - # mass of the wheel (in kg) - {'name':'mass', 'type':'float'}, - # spring factor of the wheel : the stiffiness of the wheel - {'name':'spring', 'type':'float'}, - # damp factor : the reboundiness of the wheel - {'name':'damp', 'type':'float'}, - # face material and band material (and no quote between them) if you don't know, use "tracks/wheelface" for the face and "tracks/wheelband1" for single wheel or "tracks/wheelband2" for dual mounted wheels. - {'name':'material', 'type':'string'}, - ], + # This section is important, it defines the wheels! The order in which the wheel are declared is important: each consecutive pair of wheel is grouped into an axle. + 'wheels':[ + # radius (in meter) + {'name':'radius', 'type':'float'}, + # width (in meter) + {'name':'width', 'type':'float'}, + # number of rays + {'name':'raycount', 'type':'int'}, + # the numbers of two existing nodes that defines the wheel axis (the second node must have a larger Z coordinate than the first) + {'name':'node1', 'type':'node'}, + {'name':'node2', 'type':'node'}, + # the number of a special rigidity node (see explanation about Axle Rigidity) or 9999 if it is not used + {'name':'rigidity node', 'type':'node'}, + # is the wheel braked (1) or not (0) (for directional braking, as found in planes, use 2 for left wheel and 3 for right wheel) + {'name':'braked', 'type':'int'}, + # is the wheel propulsed (1) or not (0) + {'name':'propulsed', 'type':'int'}, + # the number of a reference arm node for this wheel. This is where reaction torque is applied to the chassis. Should be on the rotation axis of the suspension arm. + {'name':'arm node', 'type':'node'}, + # mass of the wheel (in kg) + {'name':'mass', 'type':'float'}, + # spring factor of the wheel : the stiffiness of the wheel + {'name':'spring', 'type':'float'}, + # damp factor : the reboundiness of the wheel + {'name':'damp', 'type':'float'}, + # face material and band material (and no quote between them) if you don't know, use "tracks/wheelface" for the face and "tracks/wheelband1" for single wheel or "tracks/wheelband2" for dual mounted wheels. + {'name':'material', 'type':'string'}, + ], - # This define the position of the in-truck cam. It is a special node suspended to eight chassis nodes. The parameters are the 3 coordinates of the point and the 8 nodes numbers to which it is binded. - 'cinecam':[ - {'name':'x', 'type':'float'}, - {'name':'y', 'type':'float'}, - {'name':'z', 'type':'float'}, - {'name':'node1', 'type':'node'}, - {'name':'node2', 'type':'node'}, - {'name':'node3', 'type':'node'}, - {'name':'node4', 'type':'node'}, - {'name':'node5', 'type':'node'}, - {'name':'node6', 'type':'node'}, - {'name':'node7', 'type':'node'}, - {'name':'node8', 'type':'node'}, - ], + # This define the position of the in-truck cam. It is a special node suspended to eight chassis nodes. The parameters are the 3 coordinates of the point and the 8 nodes numbers to which it is binded. + 'cinecam':[ + {'name':'x', 'type':'float'}, + {'name':'y', 'type':'float'}, + {'name':'z', 'type':'float'}, + {'name':'node1', 'type':'node'}, + {'name':'node2', 'type':'node'}, + {'name':'node3', 'type':'node'}, + {'name':'node4', 'type':'node'}, + {'name':'node5', 'type':'node'}, + {'name':'node6', 'type':'node'}, + {'name':'node7', 'type':'node'}, + {'name':'node8', 'type':'node'}, + ], - # This defines where the light flares will be. It is positionned relative to 3 nodes of the chassis. One node is the reference node, and the two others define a base (x,y). So the flare is in the plane defined by the 3 nodes, and is placed relative to the reference node by adding a fraction of the vectors ref->x and ref->y. The three first parameters are the 3 nodes numbers (rex,x,y) and the two next gives what amount of ref->x and ref->y to add to displace the flare point (these two should be logically between 0 and 1, or else that means you use the wrong base triangle and if the body flexes too much the flare will not stick to the body correctly). - 'flares':[ - {'name':'ref node', 'type':'node'}, - {'name':'x node', 'type':'node'}, - {'name':'y node', 'type':'node'}, - {'name':'offsetx', 'type':'float'}, - {'name':'offsety', 'type':'float'}, - ], + # This defines where the light flares will be. It is positionned relative to 3 nodes of the chassis. One node is the reference node, and the two others define a base (x,y). So the flare is in the plane defined by the 3 nodes, and is placed relative to the reference node by adding a fraction of the vectors ref->x and ref->y. The three first parameters are the 3 nodes numbers (rex,x,y) and the two next gives what amount of ref->x and ref->y to add to displace the flare point (these two should be logically between 0 and 1, or else that means you use the wrong base triangle and if the body flexes too much the flare will not stick to the body correctly). + 'flares':[ + {'name':'ref node', 'type':'node'}, + {'name':'x node', 'type':'node'}, + {'name':'y node', 'type':'node'}, + {'name':'offsetx', 'type':'float'}, + {'name':'offsety', 'type':'float'}, + ], - #This allows you to "stick" any 3D mesh to a triangle of points of a truck. You can use it to stick air intakes, horns, seats, dashboard, bumbers, whatever to the truck (note that there will be no collision detection of these objects). They work the same way as the flares. It is positionned relative to 3 nodes of the chassis. One node is the reference node, and the two others define a base (x,y). So the prop is positionned relative to the plane defined by the 3 nodes, and is placed relative to the reference node by adding a fraction of the vectors ref->x and ref->y. Additionnally, you can displace the prop along the normal to the plane. The three first parameters are the 3 nodes numbers (rex,x,y) and the three next gives what amount of ref->x, ref->y and normal to add to displace the prop (the first two should be logically between 0 and 1, or else that means you use the wrong base triangle and if the body flexes too much the flare will not stick to the body correctly, the third is normalized, in meter). The next 3 parameters are rotation angles to apply to the mesh (in each 3 axis), and the last is the name of an Ogre3D mesh object. Note that meshes with the name beginning with "dashboard", "leftmirror", "rightmirror", "seat", "beacon", "pale" and "spinprop" are reserved as they employ some magic to work. The first "seat" mesh is made translucent, so it should be the driver's seat. - 'props':[ - {'name':'ref node', 'type':'node'}, - {'name':'x node', 'type':'node'}, - {'name':'y node', 'type':'node'}, - {'name':'offsetx', 'type':'float'}, - {'name':'offsety', 'type':'float'}, - {'name':'offsetz', 'type':'float'}, - {'name':'rotx', 'type':'float'}, - {'name':'roty', 'type':'float'}, - {'name':'rotz', 'type':'float'}, - {'name':'mesh', 'type':'string'}, - ], + #This allows you to "stick" any 3D mesh to a triangle of points of a truck. You can use it to stick air intakes, horns, seats, dashboard, bumbers, whatever to the truck (note that there will be no collision detection of these objects). They work the same way as the flares. It is positionned relative to 3 nodes of the chassis. One node is the reference node, and the two others define a base (x,y). So the prop is positionned relative to the plane defined by the 3 nodes, and is placed relative to the reference node by adding a fraction of the vectors ref->x and ref->y. Additionnally, you can displace the prop along the normal to the plane. The three first parameters are the 3 nodes numbers (rex,x,y) and the three next gives what amount of ref->x, ref->y and normal to add to displace the prop (the first two should be logically between 0 and 1, or else that means you use the wrong base triangle and if the body flexes too much the flare will not stick to the body correctly, the third is normalized, in meter). The next 3 parameters are rotation angles to apply to the mesh (in each 3 axis), and the last is the name of an Ogre3D mesh object. Note that meshes with the name beginning with "dashboard", "leftmirror", "rightmirror", "seat", "beacon", "pale" and "spinprop" are reserved as they employ some magic to work. The first "seat" mesh is made translucent, so it should be the driver's seat. + 'props':[ + {'name':'ref node', 'type':'node'}, + {'name':'x node', 'type':'node'}, + {'name':'y node', 'type':'node'}, + {'name':'offsetx', 'type':'float'}, + {'name':'offsety', 'type':'float'}, + {'name':'offsetz', 'type':'float'}, + {'name':'rotx', 'type':'float'}, + {'name':'roty', 'type':'float'}, + {'name':'rotz', 'type':'float'}, + {'name':'mesh', 'type':'string'}, + ], - #This last part defines the most visible part of the truck: the body. It will dress the chassis with solid triangles. You must define each body panel (a continuous almost-flat section) in a different submesh section, in order to have sharp body angles, and to simplify texturing. A submesh has two subsection: the texcoords, that places nodes of the submesh on the texture image (coordinates between 0.0 and 1.0) , and then the cab subsection, that draws the triangles, with triplets of node numbers. The nodes used in the cab subsection must be present in the texcoord subsection. The order in which the three points forming the triangles is given is important, as its winding defines in which direction it will be visible. The winding must be counterclockwise to be visible (IIRC). There is an optional flag to the cab subsection: if you add "c" to the triangle, this triangle will be a contact triangle, that can contact with contacters nodes. mcreed has contributed a cool Texturing Tutorial that describes how to fill the submesh and cab parts of the truck file. When the tag "backmesh" is added, the triangles backsides of the submesh will be black instead of see-through. - 'submesh':[ - {'name':'groupno', 'type':'int'}, - ], - 'texcoords':[ - {'name':'node', 'type':'node'}, - {'name':'u', 'type':'float'}, - {'name':'v', 'type':'float'}, - ], - 'cab':[ - {'name':'node1', 'type':'node'}, - {'name':'node2', 'type':'node'}, - {'name':'node3', 'type':'node'}, - {'name':'options', 'type':'string', - 'required':False, - 'default':None, - 'validvalues':[ - 'c', # triangle will be a contact triangle - 'n', # normal - 'b', # buoy - 'D', # WHAT IS THIS? - ]}, - ], + #This last part defines the most visible part of the truck: the body. It will dress the chassis with solid triangles. You must define each body panel (a continuous almost-flat section) in a different submesh section, in order to have sharp body angles, and to simplify texturing. A submesh has two subsection: the texcoords, that places nodes of the submesh on the texture image (coordinates between 0.0 and 1.0) , and then the cab subsection, that draws the triangles, with triplets of node numbers. The nodes used in the cab subsection must be present in the texcoord subsection. The order in which the three points forming the triangles is given is important, as its winding defines in which direction it will be visible. The winding must be counterclockwise to be visible (IIRC). There is an optional flag to the cab subsection: if you add "c" to the triangle, this triangle will be a contact triangle, that can contact with contacters nodes. mcreed has contributed a cool Texturing Tutorial that describes how to fill the submesh and cab parts of the truck file. When the tag "backmesh" is added, the triangles backsides of the submesh will be black instead of see-through. + 'submesh':[ + {'name':'groupno', 'type':'int'}, + ], + 'texcoords':[ + {'name':'node', 'type':'node'}, + {'name':'u', 'type':'float'}, + {'name':'v', 'type':'float'}, + ], + 'cab':[ + {'name':'node1', 'type':'node'}, + {'name':'node2', 'type':'node'}, + {'name':'node3', 'type':'node'}, + {'name':'options', 'type':'string', + 'required':False, + 'default':None, + 'validvalues':[ + 'c', # triangle will be a contact triangle + 'n', # normal + 'b', # buoy + 'D', # WHAT IS THIS? + ]}, + ], - # This section declares parts of the chassis as wings, and that they should bear aerodynamic forces. Each line of this section designs a wing segment, that is a homogeneous part of a wing. You can (and you should!) make a plane's wing from several contiguous wing segments. Rudder and elevators are also made with one or more wing segments. Each wing segment is bounded by 8 nodes, that defines the "bounding box" of the wing, specifically its span, chord and thickness. You must ensure that these nodes are properly interconnected by beams to ensure the structural integrity of the wing. Notice that it is VERY IMPORTANT to declare contiguous wing segments (i.e. that shares nodes) IN SEQUENTIAL ORDER FROM RIGHT TO LEFT, and you should avoid cutting a wing in two at the fuselage, but make the whole wing continuous across the fuselage because it helps to compute whole-wing effects like induced drag and other things like wing lights. A very important aerodynamic parameter is the wing airfoil. The airfoil is the tear-like shape of the wing, and its exact geometry is very important for the characteristics and performances of real-world wings. RoR uses precomputed performances curves from standard airfoils, interpolated from wing tunnel tests. These curves are stored in .afl files. Standard aifoils provided in RoR are: - 'wings':[ - # Front left down node number - {'name':'front left down node', 'type':'node'}, - # Front right down node number - {'name':'front right down node', 'type':'node'}, - # Front left up node number - {'name':'front left up node', 'type':'node'}, - # Front right up node number - {'name':'front right up node', 'type':'node'}, - # Back left down node number - {'name':'back left down node', 'type':'node'}, - # Back right down node number - {'name':'back right down node', 'type':'node'}, - # Back left up node number - {'name':'back left up node', 'type':'node'}, - # Back right up node number - {'name':'back right up node', 'type':'node'}, - # Texture X coordinate of the front left of the wing (in the texture defined in "globals") - {'name':'texture x front left', 'type':'float'}, - # Texture Y coordinate of the front left of the wing (in the texture defined in "globals") - {'name':'texture y front left', 'type':'float'}, - # Texture X coordinate of the front right of the wing (in the texture defined in "globals") - {'name':'texture x front right', 'type':'float'}, - # Texture Y coordinate of the front right of the wing (in the texture defined in "globals") - {'name':'texture y front right', 'type':'float'}, - # Texture X coordinate of the back left of the wing (in the texture defined in "globals") - {'name':'texture x back left', 'type':'float'}, - # Texture Y coordinate of the back left of the wing (in the texture defined in "globals") - {'name':'texture y back left', 'type':'float'}, - # Texture X coordinate of the back right of the wing (in the texture defined in "globals") - {'name':'texture x back right', 'type':'float'}, - # Texture Y coordinate of the back right of the wing (in the texture defined in "globals") - {'name':'texture y back right', 'type':'float'}, - # Type of control surface: 'n'=none, 'a'=right aileron, 'b'=left aileron, 'f'=flap, 'e'=elevator, 'r'=rudder - {'name':'controltype', 'type':'string', - 'default':'n', - 'validvalues':[ - 'n', # none - 'a', # right aileron - 'b', # left aileron - 'f', # flap - 'e', # elevator - 'r', # rudder - ]}, - # Relative chord point at which st... [truncated message content] |
From: <ror...@us...> - 2008-03-13 00:47:24
|
Revision: 195 http://roreditor.svn.sourceforge.net/roreditor/?rev=195&view=rev Author: rorthomas Date: 2008-03-12 17:47:22 -0700 (Wed, 12 Mar 2008) Log Message: ----------- fixed parts of the terrain editor Modified Paths: -------------- trunk/lib_common/ror/terrainparser.py trunk/lib_common/roreditor/GUIObjectTree.py trunk/lib_common/roreditor/RoRObjectPreviewOgreWindow.py trunk/lib_common/roreditor/RoRTerrainOgreWindow.py Modified: trunk/lib_common/ror/terrainparser.py =================================================================== --- trunk/lib_common/ror/terrainparser.py 2008-03-13 00:12:58 UTC (rev 194) +++ trunk/lib_common/ror/terrainparser.py 2008-03-13 00:47:22 UTC (rev 195) @@ -30,6 +30,9 @@ self.rotx = x self.roty = y self.rotz = z + + def __str__(self): + return self.filename class RoRTerrain: @@ -146,8 +149,9 @@ log().error("unable to parse line: %s. ignoring it!" % content[i]) continue - #print objname - if objname[0][0:5].lower() == "truck" and len(objname) > 1: + print objname + if objname[0].lower() == "truck" and len(objname) > 1: + #print "truck" truck = Object() truck.name = "truck" truck.filename = objname[-1].strip() @@ -160,7 +164,8 @@ #truck.mayRotate=False self.trucks.append(truck) continue - if objname[0][0:4] == "load" and len(objname) > 1: + if objname[0] == "load" and len(objname) > 1: + #print "load" load = Object() load.name = "load" load.filename = objname[-1].strip() @@ -174,6 +179,7 @@ self.loads.append(load) continue + #print "object" # now it can just be an static object objectname = objname[0].strip() obj = Object() Modified: trunk/lib_common/roreditor/GUIObjectTree.py =================================================================== --- trunk/lib_common/roreditor/GUIObjectTree.py 2008-03-13 00:12:58 UTC (rev 194) +++ trunk/lib_common/roreditor/GUIObjectTree.py 2008-03-13 00:47:22 UTC (rev 195) @@ -73,10 +73,13 @@ files=[] for pattern in filepattern: + #print pattern newfiles = self.getInstalledFiles(pattern) for newfile in newfiles: files.append(newfile) + #print files + files_editable=[] files_uneditable=[] for file in files: @@ -84,9 +87,19 @@ if file.archive: type = file.archive.getType() if type == 'FileSystem': - files_editable.append(file) + ok = True + for filecheck in files_editable: + if filecheck.filename == file.filename: + ok=False + if ok: + files_editable.append(file) else: - files_uneditable.append(file) + ok = True + for filecheck in files_uneditable: + if filecheck.filename == file.filename: + ok=False + if ok: + files_uneditable.append(file) section = None if len(files_editable) > 0 or len(files_uneditable) > 0: Modified: trunk/lib_common/roreditor/RoRObjectPreviewOgreWindow.py =================================================================== --- trunk/lib_common/roreditor/RoRObjectPreviewOgreWindow.py 2008-03-13 00:12:58 UTC (rev 194) +++ trunk/lib_common/roreditor/RoRObjectPreviewOgreWindow.py 2008-03-13 00:47:22 UTC (rev 195) @@ -116,9 +116,23 @@ terrain = RoRTerrain(filename) cfgfile = os.path.join(os.path.dirname(filename), terrain.TerrainConfig) self.objnode = self.sceneManager.getRootSceneNode().createChildSceneNode(uuid+"objnode") - self.objnode.setPosition(1500, 0, 1500) + (x, z) = self.getTerrainSize(cfgfile) + self.terrainsize = (x, z) + print "terrain size: ", x, z + self.objnode.setPosition(x/2, 0, z/2) self.sceneManager.setWorldGeometry(cfgfile) + def getTerrainSize(self, filename): + lines = loadResourceFile(filename) + x=1500 + z=1500 + for line in lines: + if line.lower().strip()[:11] == 'pageworldx=': + x = int(line.lower().strip()[11:]) + if line.lower().strip()[:11] == 'pageworldz=': + z = int(line.lower().strip()[11:]) + return (x, z) + def loadodef(self, filename, uuid): try: meshname, sx, sy, sz, ismovable, boxes = loadOdef(filename) @@ -187,14 +201,14 @@ #self.MainLight.setPosition (ogre.Vector3(20, 80, 130)) # add some fog - self.sceneManager.setFog(ogre.FOG_EXP, ogre.ColourValue.White, 0.00002) + self.sceneManager.setFog(ogre.FOG_EXP, ogre.ColourValue.White, 0.0000002) # create a floor Mesh plane = ogre.Plane() plane.normal = ogre.Vector3(0, 1, 0) plane.d = 200 uuid = str(randomID()) - ogre.MeshManager.getSingleton().createPlane(uuid + 'FloorPlane', "General", plane, 200000.0, 200000.0, + ogre.MeshManager.getSingleton().createPlane(uuid + 'FloorPlane', "General", plane, 20000000.0, 20000000.0, 20, 20, True, 1, 50.0, 50.0,ogre.Vector3(0, 0, 1), ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, @@ -246,8 +260,8 @@ pos = self.objnode.getPosition() + rotateheight + (self.objentity.getBoundingBox().getMinimum() + self.objentity.getBoundingBox().getMaximum() ) / 2 lookheight = ogre.Vector3(0, height / 2, 0) elif self.mode == "terrain": - self.radius = 3000 - rotateheight = ogre.Vector3(0, 1600, 0) + self.radius = self.terrainsize[0] + rotateheight = ogre.Vector3(0, self.terrainsize[0]/2, 0) pos = self.objnode.getPosition() + rotateheight lookheight = -rotateheight Modified: trunk/lib_common/roreditor/RoRTerrainOgreWindow.py =================================================================== --- trunk/lib_common/roreditor/RoRTerrainOgreWindow.py 2008-03-13 00:12:58 UTC (rev 194) +++ trunk/lib_common/roreditor/RoRTerrainOgreWindow.py 2008-03-13 00:47:22 UTC (rev 195) @@ -457,6 +457,10 @@ self.createWaterPlane() self.createArrows() + + for t in self.terrain.trucks: + print str(t) + try: if not self.terrain.CharacterStartPosition is None: self.camera.setPosition(self.terrain.CharacterStartPosition) @@ -960,7 +964,7 @@ if self.terrain is None: return - print event.m_keyCode + #print event.m_keyCode d = 0.5 if event.ShiftDown(): d *= SHIFT_SPEED_FACTOR This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ror...@us...> - 2008-03-13 22:17:13
|
Revision: 196 http://roreditor.svn.sourceforge.net/roreditor/?rev=196&view=rev Author: rorthomas Date: 2008-03-13 15:17:09 -0700 (Thu, 13 Mar 2008) Log Message: ----------- * lots of bugfixes * now able to delete things (use 'delete' keyboard key) * removed pseudo red/green line thing Modified Paths: -------------- trunk/lib_common/ror/terrainparser.py trunk/lib_common/roreditor/MainFrame.py trunk/lib_common/roreditor/RoRTerrainOgreWindow.py Modified: trunk/lib_common/ror/terrainparser.py =================================================================== --- trunk/lib_common/ror/terrainparser.py 2008-03-13 00:47:22 UTC (rev 195) +++ trunk/lib_common/ror/terrainparser.py 2008-03-13 22:17:09 UTC (rev 196) @@ -18,8 +18,10 @@ additionaloptions = [] comments = [] mayRotate = True + type="" error = None + deleted=False def setPosition(self, x, y, z): self.x = x @@ -32,7 +34,7 @@ self.rotz = z def __str__(self): - return self.filename + return "Terrain entry: "+self.filename class RoRTerrain: @@ -41,9 +43,9 @@ TerrainConfig = "" filename = "" - trucks = [] - loads = [] + beamobjs = [] objects = [] + procroads = [] UsingCaelum = False WaterHeight = None @@ -62,8 +64,7 @@ def __init__(self, filename): self.filename = filename content = loadResourceFile(filename) - self.trucks = [] - self.loads = [] + self.beamobj = [] self.objects = [] log().info("processing terrain file: %s" % filename) self.processTerrnFile(content) @@ -84,19 +85,52 @@ def processTerrnFile(self, content): linecounter = 0 comm = [] + treemode=False + procroad=False + procroadlines=[] for i in range(0, len(content)): # convert tabs to spaces! content[i] = content[i].replace("\t", " ") + if treemode: + comm.append(content[i]) + if content[i].strip()[:8] == "tree_end": + treemode=False + continue + if procroad: + procroadlines.append(content[i].strip().split(',')) + if content[i].strip()[:20] == "end_procedural_roads": + procroad=False + self.procroads.append(copy.copy(procroadlines)) + # process now + continue + if content[i].strip() == "": comm.append(content[i]) continue if content[i].strip()[0:4] == "////": # ignore editor self made comments (usefull for those error msgs) continue - if content[i].strip()[0:2] == "//": + if content[i].strip()[:2] == "//": comm.append(content[i]) continue + if content[i].strip()[:5] == "grass": + comm.append(content[i]) + continue + if content[i].strip()[:7] == "mpspawn": + comm.append(content[i]) + continue + if content[i].strip()[:7] == "mpspawn": + comm.append(content[i]) + continue + if content[i].strip()[:10] == "tree_begin": + comm.append(content[i]) + treemode=True + continue + if content[i].strip()[:22] == "begin_procedural_roads": + procroad=True + continue + if content[i].strip()[0:1] == ";": # bugfix wrong characters! comm.append(content[i].replace(";","//")) @@ -149,35 +183,23 @@ log().error("unable to parse line: %s. ignoring it!" % content[i]) continue - print objname - if objname[0].lower() == "truck" and len(objname) > 1: + #print objname + if objname[0].lower() in ["truck", "load", "machine", "boat"] and len(objname) > 1: #print "truck" truck = Object() - truck.name = "truck" + truck.name = objname[1] truck.filename = objname[-1].strip() truck.comments = comm comm = [] truck.setPosition(x, y, z) truck.setRotation(rx, ry, -rz) - truck.additionaloptions = objname[1:] + #if len(objname)>1: + #truck.additionaloptions = objname[2:] truck.line = i + truck.type = objname[0].lower() #truck.mayRotate=False - self.trucks.append(truck) + self.beamobjs.append(truck) continue - if objname[0] == "load" and len(objname) > 1: - #print "load" - load = Object() - load.name = "load" - load.filename = objname[-1].strip() - load.comments = comm - load.line=i - comm = [] - load.setPosition(x, y, z) - load.setRotation(rx, ry, -rz) - load.additionaloptions = objname[1:] - #load.mayRotate=False - self.loads.append(load) - continue #print "object" # now it can just be an static object @@ -192,6 +214,8 @@ obj.setRotation(rx, ry, rz) obj.additionaloptions = objname[1:] self.objects.append(obj) + + print "number of proceddual roads: %d" % len(self.procroads) def getObjectLines(self, object): lines = [] @@ -199,14 +223,16 @@ # add comments if len(object.comments) > 0: for comment in object.comments: - lines.append(comment) + lines.append(comment+"\n") # construct objects name - objname = object.name + #print object.name, object.type + objname = object.type+" "+object.name if len(object.additionaloptions) > 0: - tmp = (" " + " ".join(object.additionaloptions)).strip() - objname += " " + tmp + objname += " " + " ".join(object.additionaloptions) + #print objname + # add line itself linearray = [self.formatFloat(object.x), self.formatFloat(object.y), @@ -216,6 +242,8 @@ self.formatFloat(object.rotz), objname] line = ", ".join(linearray) + if object.deleted: + line = "//"+line if not object.error is None: lines.append("//// the next object had errors, so the terraineditor commented it out:\n") @@ -230,7 +258,9 @@ def save(self, filename = None): if filename is None: - filename = self.filename + rordir = getSettingsManager().getSetting("RigsOfRods", "BasePath") + filename = os.path.join(rordir, "data", "terrains", self.filename) + print "saving terrain as %s" % filename lines = [] lines.append(self.TerrainName+"\n") lines.append(self.TerrainConfig+"\n") @@ -265,15 +295,10 @@ #save trucks - for truck in self.trucks: + for truck in self.beamobjs: trucklines = self.getObjectLines(truck) for l in trucklines: lines.append(l) - # save loads - for load in self.loads: - loadlines = self.getObjectLines(load) - for l in loadlines: - lines.append(l) # save objects for object in self.objects: Modified: trunk/lib_common/roreditor/MainFrame.py =================================================================== --- trunk/lib_common/roreditor/MainFrame.py 2008-03-13 00:47:22 UTC (rev 195) +++ trunk/lib_common/roreditor/MainFrame.py 2008-03-13 22:17:09 UTC (rev 196) @@ -116,11 +116,7 @@ # see the end up FrameManager::Update() for the test # code. For now, just hard code a frame minimum size self.SetMinSize(wx.Size(600, 400)) - try: - import ror.svn - self.SetTitle("Rigs of Rods Terrain Editor revision %d" % ror.svn.getRevision()) - except: - self.SetTitle("Rigs of Rods Terrain Editor") + self.SetTitle("Rigs of Rods Terrain Editor 0.34") # create some toolbars self.terraintoolbar = wx.ToolBar(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TB_FLAT | wx.TB_NODIVIDER) @@ -387,11 +383,14 @@ #if comment.strip() != "": # txt = "%s / %s" % (n.getName(), comment) #else: - txt = "%s %s" % (entry.data.name, " ".join(entry.data.additionaloptions)) - self.statusbar.SetStatusText(txt, 2) - - posx, posy, posz, rotx, roty, rotz = self.terrainOgreWin.getSelectionPositionRotation() - txt = "%d, %0.2f, %0.2f, %0.2f / %0.2f, %0.2f, %0.2f" % (entry.data.line, posx, posy, posz, rotx, roty, rotz) + try: + txt = "%s %s" % (entry.data.name, " ".join(entry.data.additionaloptions)) + self.statusbar.SetStatusText(txt, 2) + + posx, posy, posz, rotx, roty, rotz = self.terrainOgreWin.getSelectionPositionRotation() + txt = "%d, %0.2f, %0.2f, %0.2f / %0.2f, %0.2f, %0.2f" % (entry.data.line, posx, posy, posz, rotx, roty, rotz) + except: + txt = "" self.statusbar.SetStatusText(txt, 3) def OnGUITimer(self, event): Modified: trunk/lib_common/roreditor/RoRTerrainOgreWindow.py =================================================================== --- trunk/lib_common/roreditor/RoRTerrainOgreWindow.py 2008-03-13 00:47:22 UTC (rev 195) +++ trunk/lib_common/roreditor/RoRTerrainOgreWindow.py 2008-03-13 22:17:09 UTC (rev 196) @@ -204,7 +204,7 @@ self.Bind(wx.EVT_KEY_UP, self.onKeyUp) self.Bind(wx.EVT_MOUSE_EVENTS, self.onMouseEvent) - + """ self.spline = ogre.SimpleSpline() # some spline material mat = ogre.MaterialManager.getSingleton().create("matline","debugger") @@ -242,7 +242,7 @@ # this is for debugging of the grid system: #self.virtualMoveNode.attachObject(self.sceneManager.createEntity("afsdfsdfsfsdfsdfasdf", "arrow.mesh") ) - +""" #create objects self.populateScene() @@ -458,8 +458,8 @@ self.createWaterPlane() self.createArrows() - for t in self.terrain.trucks: - print str(t) + #for t in self.terrain.trucks: + # print str(t) try: if not self.terrain.CharacterStartPosition is None: @@ -470,20 +470,13 @@ log().error("Error while setting initial camera:") log().error(str(err)) - for truck in self.terrain.trucks: + for beam in self.terrain.beamobjs: try: self.addTruckToTerrain(data=truck) except Exception, err: - log().error("Error while adding a truck to the terrain:") + log().error("Error while adding a Beam Construction to the terrain:") log().error(str(err)) - for load in self.terrain.loads: - try: - self.addTruckToTerrain(data=load) - except Exception, err: - log().error("Error while adding a load to the terrain:") - log().error(str(err)) - for object in self.terrain.objects: try: self.addObjectToTerrain(data=object) @@ -544,7 +537,26 @@ self.entries[uuid] = entry return True - + + def deleteObjectFromFile(self, entry): + if entry.line == 0: + return + + for truck in self.terrain.beamobjs: + if truck.line == entry.line: + truck.deleted=True + print "truck in line %d deleted" % entry.line + return True + + for object in self.terrain.objects: + if object.line == entry.line: + object.deleted=True + print "object in line %d deleted" % entry.line + return True + + print "object in line %d not found!" % entry.line + return False + def addTruckToTerrain(self, data=None, truckFilename=None, coords=None): if coords is None: coords = self.selectedCoords @@ -560,16 +572,19 @@ data.comments = ['// added by terrain editor\n'] data.setPosition(coords.x, coords.y, coords.z) data.setRotation(0, 0, 0) + data.type="truck" data.additionaloptions =[data.filename] if truckFilename.split(".")[-1].lower() == "truck": - self.terrain.trucks.append(data) + data.type="truck" elif truckFilename.split(".")[-1].lower() == "load": - self.terrain.loads.append(data) + data.type="load" + self.terrain.beamobj.append(data) else: + #print data truckFilename = data.filename - if os.path.basename(truckFilename) == truckFilename: - truckFilename = self.rordir + "\\data\\trucks\\"+truckFilename + #if os.path.basename(truckFilename) == truckFilename: + # truckFilename = truckFilename entry = Entry() entry.uuid = uuid @@ -863,7 +878,9 @@ width, height, a, b, c = self.renderWindow.getMetrics() self.controlArrows(event) + """ if event.LeftDown(): + pos = self.getPointedPosition(event) self.spline.addPoint(pos) @@ -911,8 +928,8 @@ self.line[3].position(point) self.line[3].position(point+ogre.Vector3(0,2,0)) self.line[3].end() + """ - if event.RightDown() or event.LeftDown(): self.SetFocus() @@ -964,14 +981,13 @@ if self.terrain is None: return + # print keycode for debugging purposes #print event.m_keyCode d = 0.5 if event.ShiftDown(): d *= SHIFT_SPEED_FACTOR - if event.m_keyCode == 65: # A, wx.WXK_LEFT: - self.keyPress.x = -d - + """ elif event.m_keyCode == 66: # B lines = [] factor = 1 @@ -991,6 +1007,17 @@ f = open("roads.out", 'w') f.writelines(lines) f.close() + """ + + if event.m_keyCode == 65: # A, wx.WXK_LEFT: + self.keyPress.x = -d + elif event.m_keyCode == 127: + # delete key + self.deleteObjectFromFile(self.selectedEntry.data) + self.selectedEntry.entity.getParentSceneNode().setVisible(False) + self.deselectSelection() + self.selectTerrain(event) + elif event.m_keyCode == 68: # D, wx.WXK_RIGHT: self.keyPress.x = d elif event.m_keyCode == 87: # W ,wx.WXK_UP: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <ror...@us...> - 2008-03-14 12:31:37
|
Revision: 198 http://roreditor.svn.sourceforge.net/roreditor/?rev=198&view=rev Author: rorthomas Date: 2008-03-14 05:31:32 -0700 (Fri, 14 Mar 2008) Log Message: ----------- bugfixes Modified Paths: -------------- trunk/lib_common/ror/rorcommon.py trunk/lib_common/roreditor/MainFrame.py trunk/lib_common/roreditor/RoRTerrainOgreWindow.py Modified: trunk/lib_common/ror/rorcommon.py =================================================================== --- trunk/lib_common/ror/rorcommon.py 2008-03-13 22:25:30 UTC (rev 197) +++ trunk/lib_common/ror/rorcommon.py 2008-03-14 12:31:32 UTC (rev 198) @@ -12,7 +12,7 @@ except: pass - dlg = wx.MessageDialog(None, "RoR Toolkit revision %s\nAuthors: Aperion, Thomas" % rev, + dlg = wx.MessageDialog(None, "RoR Toolkit version 0.34 %s\nAuthors: Thomas, Aperion", "About This", wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() Modified: trunk/lib_common/roreditor/MainFrame.py =================================================================== --- trunk/lib_common/roreditor/MainFrame.py 2008-03-13 22:25:30 UTC (rev 197) +++ trunk/lib_common/roreditor/MainFrame.py 2008-03-14 12:31:32 UTC (rev 198) @@ -116,7 +116,7 @@ # see the end up FrameManager::Update() for the test # code. For now, just hard code a frame minimum size self.SetMinSize(wx.Size(600, 400)) - self.SetTitle("Rigs of Rods Terrain Editor 0.34") + self.SetTitle("Rigs of Rods Toolkit version 0.34") # create some toolbars self.terraintoolbar = wx.ToolBar(self, wx.ID_ANY, wx.DefaultPosition, wx.DefaultSize, wx.TB_FLAT | wx.TB_NODIVIDER) @@ -127,24 +127,24 @@ self.terraintoolbar.AddLabelTool(ID_SaveTerrainAs, "Save Terrain as", wx.ArtProvider_GetBitmap(wx.ART_FILE_SAVE_AS)) self.terraintoolbar.EnableTool(ID_SaveTerrainAs, False) self.terraintoolbar.AddSeparator() - self.terraintoolbar.AddLabelTool(ID_AddObject, "Add Something", wx.ArtProvider_GetBitmap(wx.ART_NEW)) - self.terraintoolbar.EnableTool(ID_AddObject, False) - self.terraintoolbar.AddLabelTool(ID_DeleteSelection, "Delete Selection", wx.ArtProvider_GetBitmap(wx.ART_DELETE)) - self.terraintoolbar.EnableTool(ID_DeleteSelection, False) - self.terraintoolbar.AddSeparator() - self.terraintoolbar.AddLabelTool(ID_CopySelection, "Copy Selection", wx.ArtProvider_GetBitmap(wx.ART_COPY)) - self.terraintoolbar.EnableTool(ID_CopySelection, False) - self.terraintoolbar.AddLabelTool(ID_PasteSelection, "Paste Selection", wx.ArtProvider_GetBitmap(wx.ART_PASTE)) - self.terraintoolbar.EnableTool(ID_PasteSelection, False) - self.terraintoolbar.AddSeparator() - self.terraintoolbar.AddLabelTool(ID_UndoAction, "Undo last Action", wx.ArtProvider_GetBitmap(wx.ART_UNDO)) - self.terraintoolbar.EnableTool(ID_UndoAction, False) - self.terraintoolbar.AddLabelTool(ID_RedoAction, "Redo last Undo", wx.ArtProvider_GetBitmap(wx.ART_REDO)) - self.terraintoolbar.EnableTool(ID_RedoAction, False) - self.terraintoolbar.AddSeparator() - self.terraintoolbar.AddLabelTool(ID_FindObject, "Find Object", wx.ArtProvider_GetBitmap(wx.ART_FIND)) - self.terraintoolbar.EnableTool(ID_FindObject, False) - self.terraintoolbar.AddSeparator() + #self.terraintoolbar.AddLabelTool(ID_AddObject, "Add Something", wx.ArtProvider_GetBitmap(wx.ART_NEW)) + #self.terraintoolbar.EnableTool(ID_AddObject, False) + #self.terraintoolbar.AddLabelTool(ID_DeleteSelection, "Delete Selection", wx.ArtProvider_GetBitmap(wx.ART_DELETE)) + #self.terraintoolbar.EnableTool(ID_DeleteSelection, False) + #self.terraintoolbar.AddSeparator() + #self.terraintoolbar.AddLabelTool(ID_CopySelection, "Copy Selection", wx.ArtProvider_GetBitmap(wx.ART_COPY)) + #self.terraintoolbar.EnableTool(ID_CopySelection, False) + #self.terraintoolbar.AddLabelTool(ID_PasteSelection, "Paste Selection", wx.ArtProvider_GetBitmap(wx.ART_PASTE)) + #self.terraintoolbar.EnableTool(ID_PasteSelection, False) + #self.terraintoolbar.AddSeparator() + #self.terraintoolbar.AddLabelTool(ID_UndoAction, "Undo last Action", wx.ArtProvider_GetBitmap(wx.ART_UNDO)) + #self.terraintoolbar.EnableTool(ID_UndoAction, False) + #self.terraintoolbar.AddLabelTool(ID_RedoAction, "Redo last Undo", wx.ArtProvider_GetBitmap(wx.ART_REDO)) + #self.terraintoolbar.EnableTool(ID_RedoAction, False) + #self.terraintoolbar.AddSeparator() + #self.terraintoolbar.AddLabelTool(ID_FindObject, "Find Object", wx.ArtProvider_GetBitmap(wx.ART_FIND)) + #self.terraintoolbar.EnableTool(ID_FindObject, False) + #self.terraintoolbar.AddSeparator() self.terraintoolbar.AddLabelTool(ID_Quit, "Quit", wx.ArtProvider_GetBitmap(wx.ART_QUIT)) self.terraintoolbar.Realize() @@ -410,13 +410,13 @@ def openTerrain(self, filename): self.changeEditorMode(1) self.terrainOgreWin.LoadTerrain(filename) - self.terraintoolbar.EnableTool(ID_AddObject, True) - self.terraintoolbar.EnableTool(ID_DeleteSelection, True) - self.terraintoolbar.EnableTool(ID_CopySelection, True) - self.terraintoolbar.EnableTool(ID_PasteSelection, True) - self.terraintoolbar.EnableTool(ID_UndoAction, True) - self.terraintoolbar.EnableTool(ID_RedoAction, True) - self.terraintoolbar.EnableTool(ID_FindObject, True) + #self.terraintoolbar.EnableTool(ID_AddObject, True) + #self.terraintoolbar.EnableTool(ID_DeleteSelection, True) + #self.terraintoolbar.EnableTool(ID_CopySelection, True) + #self.terraintoolbar.EnableTool(ID_PasteSelection, True) + #self.terraintoolbar.EnableTool(ID_UndoAction, True) + #self.terraintoolbar.EnableTool(ID_RedoAction, True) + #self.terraintoolbar.EnableTool(ID_FindObject, True) self.terraintoolbar.EnableTool(ID_SaveTerrain, True) self.terraintoolbar.EnableTool(ID_SaveTerrainAs, True) Modified: trunk/lib_common/roreditor/RoRTerrainOgreWindow.py =================================================================== --- trunk/lib_common/roreditor/RoRTerrainOgreWindow.py 2008-03-13 22:25:30 UTC (rev 197) +++ trunk/lib_common/roreditor/RoRTerrainOgreWindow.py 2008-03-14 12:31:32 UTC (rev 198) @@ -237,12 +237,11 @@ self.line[i].setDynamic(True) self.linenode.append(self.sceneManager.getRootSceneNode().createChildSceneNode()) self.linenode[i].attachObject(self.line[i]) - +""" self.virtualMoveNode = self.sceneManager.getRootSceneNode().createChildSceneNode() # this is for debugging of the grid system: #self.virtualMoveNode.attachObject(self.sceneManager.createEntity("afsdfsdfsfsdfsdfasdf", "arrow.mesh") ) -""" #create objects self.populateScene() @@ -291,15 +290,18 @@ return pos.x, pos.y, pos.z, rotx, roty, rotz def reattachArrows(self, entity): - self.TranslateNode.setPosition(entity.getParentNode().getPosition()) - #self.TranslateNode.setOrientation(entity.getParentNode().getOrientation()) + try: + self.TranslateNode.setPosition(entity.getParentNode().getPosition()) + #self.TranslateNode.setOrientation(entity.getParentNode().getOrientation()) + + self.RotateNode.setOrientation(entity.getParentNode().getOrientation()) + self.RotateNode.setPosition(entity.getParentNode().getPosition()) + + self.virtualMoveNode.setOrientation(entity.getParentNode().getOrientation()) + self.virtualMoveNode.setPosition(entity.getParentNode().getPosition()) + except: + pass - self.RotateNode.setOrientation(entity.getParentNode().getOrientation()) - self.RotateNode.setPosition(entity.getParentNode().getPosition()) - - self.virtualMoveNode.setOrientation(entity.getParentNode().getOrientation()) - self.virtualMoveNode.setPosition(entity.getParentNode().getPosition()) - def createArrows(self): if not self.TranslateNode is None: return This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |