diff --git a/components/scg/base/scg_alphabet.py b/components/scg/base/scg_alphabet.py index f488ee1..3bbe145 100644 --- a/components/scg/base/scg_alphabet.py +++ b/components/scg/base/scg_alphabet.py @@ -195,6 +195,11 @@ def createContour(): """Create scg-contour """ return scg_objects.SCgContour(render_engine.SceneManager.createSceneNode()) + +def createBus(): + """Create scg-bus + """ + return scg_objects.SCgBus(render_engine.SceneManager.createSceneNode()) def changeObjectType(_obj, _type): """Changing node type @@ -252,4 +257,4 @@ def get_node_types(): for alias in elementsDescMap.iterkeys(): if alias.startswith('node'): res.append(alias) - return res \ No newline at end of file + return res diff --git a/components/scg/base/scg_editor.py b/components/scg/base/scg_editor.py index d1b3f14..e306cce 100644 --- a/components/scg/base/scg_editor.py +++ b/components/scg/base/scg_editor.py @@ -177,7 +177,22 @@ def _createContour(self, points): sheet.addChild(contour) contour.setPoints(points) contour.setState(objects.Object.OS_Normal) - + def _createBus(self, _beg, _end_pos): + """Create bus + @param _beg: begin object + @type _beg: object.Object + @param _end_pos: end position + @type _end_pos: tuple + + @return: created bus + """ + bus = scg_alphabet.createBus() + sheet = self._getSheet() + sheet.addChild(bus) + bus.setAttachedNode(_beg) + bus.setEndPointPos(_end_pos) + bus.setState(objects.Object.OS_Normal) + + return bus - \ No newline at end of file diff --git a/components/scg/base/scg_modes.py b/components/scg/base/scg_modes.py index 3236893..6c7a17a 100644 --- a/components/scg/base/scg_modes.py +++ b/components/scg/base/scg_modes.py @@ -120,6 +120,7 @@ class SCgEditMode(BaseEditMode): ES_ContType = ES_TypeChange + 1 # content type changing ES_Translate = ES_ContType + 1 # translate camera position ES_ContourCreate= ES_Translate + 1 # contour creation + ES_BusCreate = ES_ContourCreate + 1 # bus creation ES_Count = ES_ContourCreate + 1 # count of all states EM_Select = 0 @@ -331,6 +332,13 @@ def _onMouseMoved(self, _evt): self._updateLineCreationObjects() self._highlight() return True + + elif self.state is SCgEditMode.ES_BusCreate: + pos = render_engine.pos2dTo3dIsoPos(self.mouse_pos) + self.line_mode_obj.setPosition(pos) + self._updateLineCreationObjects() + self._highlight() + return True elif self.state is SCgEditMode.ES_Translate: if render_engine.viewMode is render_engine.Mode_Isometric: @@ -408,6 +416,15 @@ def _onMousePressed(self, _evt, _id): self.state = SCgEditMode.ES_LineCreate # setting begin object self.line_mode_beg = mobjects[0][1] + + if isinstance(self.line_mode_beg, scg_objects.SCgBus): + bus = self.line_mode_beg + self.line_mode_beg = scg_objects.AttachmentPoint(render_engine.SceneManager.createSceneNode(), + bus, + render_engine.pos2dTo3dIsoPos((mstate.X.abs, mstate.Y.abs))) + sheet = self._logic._getSheet() + sheet.addChild(self.line_mode_beg) + self.line_mode_line.setBegin(self.line_mode_beg) self.line_mode_obj.setPosition(render_engine.pos2dTo3dIsoPos((mstate.X.abs, mstate.Y.abs))) # adding to scene @@ -417,6 +434,34 @@ def _onMousePressed(self, _evt, _id): self._updateLineCreationObjects() return True + + # line bus state + elif (self.state is SCgEditMode.ES_BusCreate) and (self.line_mode_beg is None): + # setting begin object + self.line_mode_beg = mobjects[0][1] + self.line_mode_line.setBegin(self.line_mode_beg) + self.line_mode_obj.setPosition(render_engine.pos2dTo3dIsoPos((mstate.X.abs, mstate.Y.abs))) + # adding to scene + sheet = self._logic._getSheet() + render_engine.SceneNode.addChild(sheet.sceneNodeChilds, self.line_mode_line.sceneNode) + + self._updateLineCreationObjects() + + return True + + elif (self.state is SCgEditMode.ES_BusCreate) and (self.line_mode_beg is not None): + # check if is there + if len(mobjects) is 0: + sheet = self._logic._getSheet() + self._logic._createBus(self.line_mode_beg, (mstate.X.abs, mstate.Y.abs)) + + sheet = self._logic._getSheet() + render_engine.SceneNode.removeChild(sheet.sceneNodeChilds, self.line_mode_line.sceneNode) + self.line_mode_line.setBegin(None) + self.line_mode_beg = None + self.state = SCgEditMode.ES_None + + return True # line creation state elif (self.state is SCgEditMode.ES_LineCreate) and (self.line_mode_beg is not None): @@ -502,6 +547,10 @@ def _onKeyPressed(self, _evt): else: layout_group.play() + elif key == ois.KC_B: + if self.state != SCgEditMode.ES_BusCreate: + self.state = SCgEditMode.ES_BusCreate + elif _evt.key == ois.KC_F9: if render_engine.viewMode is render_engine.Mode_Isometric: self._logic._getSheet().changeMode(render_engine.Mode_Perspective) @@ -823,6 +872,15 @@ def _onKeyReleased(self, _evt): if key == ois.KC_LSHIFT: self._shift = False + + elif key == ois.KC_B: + if self.state == SCgEditMode.ES_BusCreate: + sheet = self._logic._getSheet() + render_engine.SceneNode.removeChild(sheet.sceneNodeChilds, self.line_mode_line.sceneNode) + self.line_mode_line.setBegin(None) + self.line_mode_beg = None + + self.state = SCgEditMode.ES_None return False diff --git a/components/scg/base/scg_objects.py b/components/scg/base/scg_objects.py index 8ebd1b2..2fe6f40 100644 --- a/components/scg/base/scg_objects.py +++ b/components/scg/base/scg_objects.py @@ -692,15 +692,203 @@ def _recreateArrows2d(self, countNormals = False): class SCgBus(objects.ObjectDepth): - + """Class that represents realization of scg-bus object. + """ def __init__(self, sceneNode): - objects.ObjectDepth(self, sceneNode) - + """Constructor + @param sceneNode: Ogre Scene node for bus object + """ + objects.ObjectDepth.__init__(self, sceneNode) + + self.__manualObject = None + + self.radius = 0.12 + self.length = 0.5 + + self.attachedNode = None + self.attachmentPoints = [] + + self.begin_pos = None + self.end_pos = None + self.orient = None + + self.needGeometryUpdate = True + def __del__(self): - pass - + """Destructor + """ + objects.ObjectDepth.__del__(self) + def delete(self): - pass + # destroying ogre objects + if self.__manualObject: + render_engine.SceneManager.destroyManualObject(self.__manualObject) + + objects.ObjectDepth.__del__(self) + + def _update(self, timeSinceLastFrame): + """Update bus. Creates new geometry. + """ + objects.ObjectDepth._update(self, timeSinceLastFrame) + + if self.needViewUpdate: + self._updateView() + self.needViewUpdate = False + + if self.needGeometryUpdate: + self.needGeometryUpdate = False + + self._updateGeometry() + + def _updateGeometry(self): + """Updates geometry. + """ + if self.__manualObject is None: + self.__manualObject = render_engine._ogreSceneManager.createManualObject(str(self)) + self.__manualObject.setDynamic(False) + self.sceneNode.attachObject(self.__manualObject) + self.__manualObject.begin(self._getMaterialName()) + else: + self.__manualObject.beginUpdate(0) + + self.begin_pos = self.attachedNode._getCross(self.attachedNode.getPosition() - self.orient) + self.end_pos = self.attachedNode.getPosition() - self.orient + + length = self.begin_pos.distance(self.end_pos) + + if render_engine.viewMode == render_engine.Mode_Isometric: + + self.__manualObject.position(-self.radius, 0.0, 0.0) + self.__manualObject.textureCoord(0.0, 0.0) + self.__manualObject.normal(0, 0, 1) + + self.__manualObject.position(-self.radius, length, 0.0) + self.__manualObject.textureCoord(1.0, 0.0) + self.__manualObject.normal(0, 0, 1) + + self.__manualObject.position(self.radius, length, 0.0) + self.__manualObject.textureCoord(1.0, 1.0) + self.__manualObject.normal(0, 0, 1) + + self.__manualObject.position(self.radius, 0.0, 0.0) + self.__manualObject.textureCoord(0.0, 1.0) + self.__manualObject.normal(0, 0, 1) + + self.__manualObject.quad(0, 1, 2, 3) + + self.__manualObject.end() + + self.sceneNode.setPosition(self.begin_pos) + self.length = length + self.__orientV = self.end_pos - self.begin_pos + self.sceneNode.setDirection(-self.orient, ogre.SceneNode.TS_PARENT, [0, 1, 0]) + + def _updateView(self): + """Update object view + Updating object materials based on state. + """ + objects.ObjectDepth._updateView(self) + + if self.needStateUpdate: + if self.__manualObject is not None: + self.needStateUpdate = False + self.__materialName = self._getMaterialName() + if self.__manualObject.getNumSections() > 0: + self.__manualObject.setMaterialName(0, self.__materialName) + else: + self.needUpdate = True + self.needViewUpdate = True + + def appendPoint(self, point): + """Add the point to which the line will be attached + """ + self.attachmentPoints.append(point) + + def _getCross(self, pos): + """Count cross position + """ + return (self.begin_pos + self.end_pos) / 2.0 + + def _getMaterialName(self): + return "scg_Node_" + state_post[self.getState()] + + def setAttachedNode(self, node): + if self.attachedNode: + self.attachedNode.removeLinkedObject(objects.Object.LS_BASEONTHIS, self) + + self.attachedNode = node + if self.attachedNode: + self.attachedNode.addLinkedObject(objects.Object.LS_BASEONTHIS, self) + + self.attachedNode.sceneNode._updateBounds() + self.needUpdate = True + + def getAttachedNode(self): + return self.attachedNode + + def setEndPointPos(self, end_point_pos): + self.end_pos = render_engine.pos2dTo3dIsoPos(end_point_pos) + self.orient = self.attachedNode.getPosition() - self.end_pos + + def _checkRayIntersect(self, ray): + """Check if ray intersects object + @param ray: ray to check intersection with + @type ray: ogre.Ray + @returns tuple (intersection result, distance to intersection point) + """ + if self.begin_pos is None or self.end_pos is None: + return False, -1 + + v1 = self.__orientV + v2 = ray.getDirection() + + r = v1.crossProduct(v2) + s = self.begin_pos - ray.getOrigin() + d = abs(r.normalisedCopy().dotProduct(s)) + + if d <= self.radius: + return True, 0 + + return False, -1 + + def getType(self): + return self.attachedNode.getType() + + +class AttachmentPoint(objects.ObjectDepth): + """Class that represents realization of point to which line will be attached to the bus + """ + def __init__(self, sceneNode, bus, pos): + """Constructor + """ + objects.ObjectDepth.__init__(self, sceneNode) + + self.bus = bus + if self.bus: + self.bus.addLinkedObject(objects.Object.LS_BASEONTHIS, self) + bus.appendPoint(self) + + self.pos = pos + self.orient = self.bus.getAttachedNode().getPosition() - self.pos + + def __del__(self): + """Destructor + """ + objects.ObjectDepth.__del__(self) + + def delete(self): + objects.ObjectDepth.__del__(self) + + def _getCross(self, pos): + return self.pos + + def _update(self, timeSinceLastFrame): + objects.ObjectDepth._update(self, timeSinceLastFrame) + + self.pos = self.bus.getAttachedNode().getPosition() - self.orient + + def _getScAddr(self): + return self.bus.getAttachedNode()._getScAddr() class SCgContour(objects.ObjectDepth): @@ -868,4 +1056,4 @@ def _updateGeometry(self): self.__manualObject.quad(idx1, idx1 + 1, idx1 + 3, idx1 + 2) self.__manualObject.quad(n*2, n*2 + 1, 1, 0) self.__manualObject.end() - \ No newline at end of file +