def test_quat(self): "Adapted from examples/osgunittests/osgunittests.cpp" q1 = osg.Quat() q1.makeRotate(osg.DegreesToRadians(30.0), 0.0, 0.0, 1.0) q2 = osg.Quat() q2.makeRotate(osg.DegreesToRadians(133.0), 0.0, 1.0, 1.0) q1_2 = q1 * q2 q2_1 = q2 * q1 m1 = osg.Matrix.rotate(q1) m2 = osg.Matrix.rotate(q2) m1_2 = m1 * m2 m2_1 = m2 * m1 qm1_2 = osg.Quat() qm1_2.set(m1_2) qm2_1 = osg.Quat() qm2_1.set(m2_1) print "q1*q2 = ", q1_2 print "q2*q1 = ", q2_1 print "m1*m2 = ", qm1_2 print "m2*m1 = ", qm2_1 testQuatRotate(osg.Vec3d(1.0, 0.0, 0.0), osg.Vec3d(0.0, 1.0, 0.0)) testQuatRotate(osg.Vec3d(0.0, 1.0, 0.0), osg.Vec3d(1.0, 0.0, 0.0)) testQuatRotate(osg.Vec3d(0.0, 0.0, 1.0), osg.Vec3d(0.0, 1.0, 0.0)) testQuatRotate(osg.Vec3d(1.0, 1.0, 1.0), osg.Vec3d(1.0, 0.0, 0.0)) testQuatRotate(osg.Vec3d(1.0, 0.0, 0.0), osg.Vec3d(1.0, 0.0, 0.0)) testQuatRotate(osg.Vec3d(1.0, 0.0, 0.0), osg.Vec3d(-1.0, 0.0, 0.0)) testQuatRotate(osg.Vec3d(-1.0, 0.0, 0.0), osg.Vec3d(1.0, 0.0, 0.0)) testQuatRotate(osg.Vec3d(0.0, 1.0, 0.0), osg.Vec3d(0.0, -1.0, 0.0)) testQuatRotate(osg.Vec3d(0.0, -1.0, 0.0), osg.Vec3d(0.0, 1.0, 0.0)) testQuatRotate(osg.Vec3d(0.0, 0.0, 1.0), osg.Vec3d(0.0, 0.0, -1.0)) testQuatRotate(osg.Vec3d(0.0, 0.0, -1.0), osg.Vec3d(0.0, 0.0, 1.0)) # Test a range of rotations testGetQuatFromMatrix(quat_scale) # This is a specific test case for a matrix containing scale and rotation matrix = osg.Matrix(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 1.0, 1.0, 1.0, 1.0) quat = osg.Quat() matrix.get(quat) print "Matrix = ", matrix, "rotation = ", quat, ", expected quat = (0,0,0,1)"
def testQuatRotate(from_quat, to): q_nicolas = osg.Quat() q_nicolas.makeRotate(from_quat, to) q_original = osg.Quat() q_original.makeRotate_original(from_quat, to) print "osg.Quat.makeRotate(", from_quat, ", ", to, ")" print " q_nicolas = ", q_nicolas print " q_original = ", q_original print " from * M4x4(q_nicolas) = ", from_quat * osg.Matrixd.rotate( q_nicolas) print " from * M4x4(q_original) = ", from_quat * osg.Matrixd.rotate( q_original)
def createAnimationPath(center, radius, looptime): # set up the animation path animationPath = osg.AnimationPath() animationPath.setLoopMode(osg.AnimationPath.LOOP) numSamples = 40 yaw = 0.0 yaw_delta = 2.0*osg.PI/(numSamples-1.0) roll = osg.inDegrees(30.0) time = 0.0 time_delta = looptime/float(numSamples) for i in range(numSamples): position = center+osg.Vec3(math.sin(yaw)*radius,math.cos(yaw)*radius,0.0) rotation = osg.Quat(roll,osg.Vec3(0.0,1.0,0.0))*osg.Quat(-(yaw+osg.inDegrees(90.0)),osg.Vec3(0.0,0.0,1.0)) animationPath.insert(time,osg.AnimationPath.ControlPoint(position,rotation)) yaw += yaw_delta time += time_delta return animationPath
def createAnimationPath(center, radius, looptime): # set up the animation path animationPath = osg.AnimationPath() animationPath.setLoopMode(osg.AnimationPath.LOOP) numSamples = 1000 yaw = 0.0 yaw_delta = -2.0*osg.PI/((float)numSamples-1.0) roll = osg.inDegrees(30.0) time = 0.0 time_delta = looptime/(double)numSamples for(int i=0i<numSamples++i) position = osg.Vec3(center+osg.Vec3(sinf(yaw)*radius,cosf(yaw)*radius,0.0)) rotation = osg.Quat(osg.Quat(roll,osg.Vec3(0.0,1.0,0.0))*osg.Quat(-(yaw+osg.inDegrees(90.0)),osg.Vec3(0.0,0.0,1.0))) animationPath.insert(time,osg.AnimationPath.ControlPoint(position,rotation)) yaw += yaw_delta time += time_delta
def computeLocalToWorldMatrix(matrix, nv): billboardRotation = osg.Quat() cullvisitor = dynamic_cast<osgUtil.CullVisitor*>(nv) if cullvisitor : eyevector = cullvisitor.getEyeLocal()-_position eyevector.normalize() side = _axis^_normal side.normalize() angle = atan2(eyevector*_normal,eyevector*side) billboardRotation.makeRotate(osg.PI_2-angle,_axis) matrix.preMultTranslate(_position) matrix.preMultRotate(billboardRotation) matrix.preMultRotate(_attitude) matrix.preMultTranslate(-_pivotPoint) return True
def createReflector(): pat = osg.PositionAttitudeTransform() pat.setPosition(osg.Vec3(0.0,0.0,0.0)) pat.setAttitude(osg.Quat(osg.inDegrees(0.0),osg.Vec3(0.0,0.0,1.0))) geode_1 = Geode() pat.addChild(geode_1) radius = 0.8 hints = TessellationHints() hints.setDetailRatio(2.0) shape = ShapeDrawable(Sphere(Vec3(0.0, 0.0, 0.0), radius * 1.5), hints) shape.setColor(Vec4(0.8, 0.8, 0.8, 1.0)) geode_1.addDrawable(shape) nodeList = osg.NodePath() nodeList.push_back(pat) nodeList.push_back(geode_1) return nodeList
class TestManipulator (osgGA.CameraManipulator) : TestManipulator() virtual ~TestManipulator() #* set the position of the matrix manipulator using a 4x4 Matrix. setByMatrix = virtual void( osg.Matrixd matrix) #* set the position of the matrix manipulator using a 4x4 Matrix. def setByInverseMatrix(matrix): setByMatrix(osg.Matrixd.inverse(matrix)) #* get the position of the manipulator as 4x4 Matrix. virtual osg.Matrixd getMatrix() #* get the position of the manipulator as a inverse matrix of the manipulator, typically used as a model view matrix. virtual osg.Matrixd getInverseMatrix() #* Attach a node to the manipulator. # Automatically detaches previously attached node. # setNode(NULL) detaches previously nodes. # Is ignored by manipulators which do not require a reference model. setNode = virtual void(osg.Node*) #* Return node if attached. virtual osg.Node* getNode() #* Return node if attached. getNode = virtual osg.Node*() #* Move the camera to the default position. # May be ignored by manipulators if home functionality is not appropriate. home = virtual void( osgGA.GUIEventAdapter ea,osgGA.GUIActionAdapter us) #* Start/restart the manipulator. init = virtual void( osgGA.GUIEventAdapter ea,osgGA.GUIActionAdapter us) #* handle events, return True if handled, False otherwise. handle = virtual bool( osgGA.GUIEventAdapter ea,osgGA.GUIActionAdapter us) #* Reset the internal GUIEvent stack. flushMouseEventStack = void() #* Add the current mouse GUIEvent to internal stack. addMouseEvent = void( osgGA.GUIEventAdapter ea) computePosition = void( osg.Vec3 eye, osg.Vec3 lv, osg.Vec3 up) #* For the give mouse movement calculate the movement of the camera. # Return True is camera has moved and a redraw is required. calcMovement = bool() #* Check the speed at which the mouse is moving. # If speed is below a threshold then return False, otherwise return True. isMouseMoving = bool() # Internal event stack comprising last three mouse events. _ga_t1 = osgGA.GUIEventAdapter() _ga_t0 = osgGA.GUIEventAdapter() _node = osg.Node() _modelScale = float() _minimumZoomScale = float() _thrown = bool() _center = osg.Vec3() _rotation = osg.Quat() _distance = float()
# return if less then two events have been added. if _ga_t0==NULL or _ga_t1==NULL : return False dx = _ga_t0.getXnormalized()-_ga_t1.getXnormalized() dy = _ga_t0.getYnormalized()-_ga_t1.getYnormalized() # return if there is no movement. if dx==0 and dy==0 : return False buttonMask = _ga_t1.getButtonMask() if buttonMask==GUIEventAdapter.LEFT_MOUSE_BUTTON : # rotate camera. new_rotate = osg.Quat() new_rotate.makeRotate(dx / 3.0, osg.Vec3(0.0, 0.0, 1.0)) _rotation = _rotation*new_rotate return True elif buttonMask==GUIEventAdapter.MIDDLE_MOUSE_BUTTON : # pan model. dv = osg.Vec3(0.0, 0.0, -500.0) * dy _center += dv return True
_firstTime = 0.0 _period = 4.0 _range = bs.radius()*0.5 virtual void operator()(osg.Node* node, osg.NodeVisitor* nv) pat = dynamic_cast<osg.PositionAttitudeTransform*>(node) frameStamp = nv.getFrameStamp() if pat and frameStamp : if _firstTime==0.0 : _firstTime = frameStamp.getSimulationTime() phase = (frameStamp.getSimulationTime()-_firstTime)/_period phase -= floor(phase) phase *= (2.0 * osg.PI) rotation = osg.Quat() rotation.makeRotate(phase,1.0,1.0,1.0) pat.setAttitude(rotation) pat.setPosition(osg.Vec3(0.0,0.0,sin(phase))*_range) # must traverse the Node's subgraph traverse(node,nv) _firstTime = double() _period = double() _range = double()
def testGetQuatFromMatrix(scale): # Options # acceptable error range eps = 1e-6 # scale matrix # To not test with scale, use 1,1,1 # Not sure if 0's or negative values are acceptable scalemat = osg.Matrixd() scalemat.makeScale(scale) # range of rotations if True: # wide range rol1start = 0.0 rol1stop = 360.0 rol1step = 20.0 pit1start = 0.0 pit1stop = 90.0 pit1step = 20.0 yaw1start = 0.0 yaw1stop = 360.0 yaw1step = 20.0 rol2start = 0.0 rol2stop = 360.0 rol2step = 20.0 pit2start = 0.0 pit2stop = 90.0 pit2step = 20.0 yaw2start = 0.0 yaw2stop = 360.0 yaw2step = 20.0 else: # focussed range rol1start = 0.0 rol1stop = 0.0 rol1step = 0.1 pit1start = 0.0 pit1stop = 5.0 pit1step = 5.0 yaw1start = 89.0 yaw1stop = 91.0 yaw1step = 0.0 rol2start = 0.0 rol2stop = 0.0 rol2step = 0.0 pit2start = 0.0 pit2stop = 0.0 pit2step = 0.1 yaw2start = 89.0 yaw2stop = 91.0 yaw2step = 0.1 #endif print "Starting testGetQuatFromMatrix, it can take a while ..." tstart = osg.Timer.instance().tick() count = 0 for rol1 in arange(rol1start, rol1stop + 1, rol1step): # for (double pit1 = pit1start pit1 <= pit1stop pit1 += pit1step) for pit1 in arange(pit1start, pit1stop + 1, pit1step): # for (double yaw1 = yaw1start yaw1 <= yaw1stop yaw1 += yaw1step) for yaw1 in arange(yaw1start, yaw1stop + 1, yaw1step): # for (double rol2 = rol2start rol2 <= rol2stop rol2 += rol2step) for rol2 in arange(rol2start, rol2stop + 1, rol2step): # for (double pit2 = pit2start pit2 <= pit2stop pit2 += pit2step) for pit2 in arange(pit2start, pit2stop, pit2step): # for (double yaw2 = yaw2start yaw2 <= yaw2stop yaw2 += yaw2step) for yaw2 in arange(yaw2start, yaw2stop + 1, yaw2step): count += 1 # create two quats based on the roll, pitch and yaw values rot_quat1 = osg.Quat(osg.DegreesToRadians(rol1), osg.Vec3d(1, 0, 0), osg.DegreesToRadians(pit1), osg.Vec3d(0, 1, 0), osg.DegreesToRadians(yaw1), osg.Vec3d(0, 0, 1)) rot_quat2 = osg.Quat(osg.DegreesToRadians(rol2), osg.Vec3d(1, 0, 0), osg.DegreesToRadians(pit2), osg.Vec3d(0, 1, 0), osg.DegreesToRadians(yaw2), osg.Vec3d(0, 0, 1)) # create an output quat using quaternion math out_quat1 = rot_quat2 * rot_quat1 # create two matrices based on the input quats # osg.Matrixd mat1,mat2 mat1 = osg.Matrixd() mat2 = osg.Matrixd() mat1.makeRotate(rot_quat1) mat2.makeRotate(rot_quat2) # create an output quat by matrix multiplication and getRotate out_mat = mat2 * mat1 # add matrix scale for even more nastiness out_mat = out_mat * scalemat out_quat2 = out_mat.getRotate() # If the quaternion W is <0, then we should reflect # to get it into the positive W. # Unfortunately, when W is very small (close to 0), the sign # does not really make sense because of precision problems # and the reflection might not work. if out_quat1.w() < 0: out_quat1 = out_quat1 * -1.0 if out_quat2.w() < 0: out_quat2 = out_quat2 * -1.0 # if the output quat length is not one # or if the components do not match, # something is amiss componentsOK = False if (((abs(out_quat1.x() - out_quat2.x())) < eps) and ((abs(out_quat1.y() - out_quat2.y())) < eps) and ((abs(out_quat1.z() - out_quat2.z())) < eps) and ((abs(out_quat1.w() - out_quat2.w())) < eps)): componentsOK = True # We should also test for q = -q which is valid, so reflect # one quat. out_quat2 = out_quat2 * -1.0 if (((abs(out_quat1.x() - out_quat2.x())) < eps) and ((abs(out_quat1.y() - out_quat2.y())) < eps) and ((abs(out_quat1.z() - out_quat2.z())) < eps) and ((abs(out_quat1.w() - out_quat2.w())) < eps)): componentsOK = True lengthOK = False if (abs(1.0 - out_quat2.length()) < eps): lengthOK = True if (not lengthOK) or (not componentsOK): print[ "testGetQuatFromMatrix problem at: \n", " r1=", rol1, " p1=", pit1, " y1=", yaw1, " r2=", rol2, " p2=", pit2, " y2=", yaw2 ] print "quats: ", out_quat1, " length: ", out_quat1.length( ), "\n" print "mats and get: ", out_quat2, " length: ", out_quat2.length( ), "\n\n" tstop = osg.Timer.instance().tick() duration = osg.Timer.instance().delta_s(tstart, tstop) print "Time for testGetQuatFromMatrix with ", count, " iterations: ", duration
def main(argv): # use an ArgumentParser object to manage the program arguments. arguments = osg.ArgumentParser(argv) # set up the usage document, in case we need to print out how to use this program. arguments.getApplicationUsage().setDescription(arguments.getApplicationName()+" is the example which demonstrates use of node tracker.") arguments.getApplicationUsage().setCommandLineUsage(arguments.getApplicationName()) arguments.getApplicationUsage().addCommandLineOption("-h or --help","Display this information") # construct the viewer. viewer = osgViewer.Viewer(arguments) # add the state manipulator viewer.addEventHandler( osgGA.StateSetManipulator(viewer.getCamera().getOrCreateStateSet()) ) # add the thread model handler viewer.addEventHandler(osgViewer.ThreadingHandler)() # add the window size toggle handler viewer.addEventHandler(osgViewer.WindowSizeHandler)() # add the stats handler viewer.addEventHandler(osgViewer.StatsHandler)() # add the record camera path handler viewer.addEventHandler(osgViewer.RecordCameraPathHandler)() # add the help handler viewer.addEventHandler(osgViewer.HelpHandler(arguments.getApplicationUsage())) # set the near far ration computation up. viewer.getCamera().setComputeNearFarMode(osg.CullSettings.COMPUTE_NEAR_FAR_USING_PRIMITIVES) viewer.getCamera().setNearFarRatio(0.000003) speed = 1.0 while arguments.read("-f") or arguments.read("--fixed") : speed = 0.0 rotation = osg.Quat() vec4 = osg.Vec4() while arguments.read("--rotate-model",vec4[0],vec4[1],vec4[2],vec4[3]) : local_rotate = osg.Quat() local_rotate.makeRotate(osg.DegreesToRadians(vec4[0]),vec4[1],vec4[2],vec4[3]) rotation = rotation * local_rotate nc = 0 flightpath_filename = str() while arguments.read("--flight-path",flightpath_filename) : fin = osgDB.ifstream(flightpath_filename.c_str()) if fin : path = osg.AnimationPath() path.read(fin) nc = osg.AnimationPathCallback(path) trackerMode = osgGA.NodeTrackerManipulator.NODE_CENTER_AND_ROTATION mode = str() while arguments.read("--tracker-mode",mode) : if mode=="NODE_CENTER_AND_ROTATION" : trackerMode = osgGA.NodeTrackerManipulator.NODE_CENTER_AND_ROTATION elif mode=="NODE_CENTER_AND_AZIM" : trackerMode = osgGA.NodeTrackerManipulator.NODE_CENTER_AND_AZIM elif mode=="NODE_CENTER" : trackerMode = osgGA.NodeTrackerManipulator.NODE_CENTER else: print "Unrecognized --tracker-mode option ", mode, ", valid options are:" print " NODE_CENTER_AND_ROTATION" print " NODE_CENTER_AND_AZIM" print " NODE_CENTER" return 1 rotationMode = osgGA.NodeTrackerManipulator.TRACKBALL while arguments.read("--rotation-mode",mode) : if mode=="TRACKBALL" : rotationMode = osgGA.NodeTrackerManipulator.TRACKBALL elif mode=="ELEVATION_AZIM" : rotationMode = osgGA.NodeTrackerManipulator.ELEVATION_AZIM else: print "Unrecognized --rotation-mode option ", mode, ", valid options are:" print " TRACKBALL" print " ELEVATION_AZIM" return 1 useOverlay = True while arguments.read("--no-overlay") or arguments.read("-n") : useOverlay = False technique = osgSim.OverlayNode.OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY while arguments.read("--object") : technique = osgSim.OverlayNode.OBJECT_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY while arguments.read("--ortho") or arguments.read("--orthographic") : technique = osgSim.OverlayNode.VIEW_DEPENDENT_WITH_ORTHOGRAPHIC_OVERLAY while arguments.read("--persp") or arguments.read("--perspective") : technique = osgSim.OverlayNode.VIEW_DEPENDENT_WITH_PERSPECTIVE_OVERLAY overlayTextureUnit = 1 while arguments.read("--unit", overlayTextureUnit) : pathfile = str() while arguments.read("-p",pathfile) : addFireEffect = arguments.read("--fire") # if user request help write it out to cout. if arguments.read("-h") or arguments.read("--help") : arguments.getApplicationUsage().write(std.cout) return 1 tm = osgGA.NodeTrackerManipulator() overlayFilename = str() while arguments.read("--overlay", overlayFilename) : # read the scene from the list of file specified commandline args. root = osgDB.readNodeFiles(arguments) if not root : root = createEarth() if not root : return 0 if not overlayFilename.empty() : #osg.Object *pObj = osgDB.readObjectFile("alaska_clean.shp") #osg.Geode shapefile = dynamic_cast<osg.Geode*> (pObj) # #ConvertLatLon2EllipsoidCoordinates latlon2em #shapefile.accept(latlon2em) shapefile = osgDB.readNodeFile(overlayFilename) if not shapefile : osg.notify(osg.NOTICE), "File `", overlayFilename, "` not found" return 1 csn = dynamic_cast<osg.CoordinateSystemNode*>(root) if csn : overlayNode = osgSim.OverlayNode(technique) overlayNode.getOrCreateStateSet().setTextureAttribute(1, osg.TexEnv(osg.TexEnv.DECAL)) overlayNode.setOverlaySubgraph(shapefile) overlayNode.setOverlayTextureSizeHint(1024) overlayNode.setOverlayTextureUnit(overlayTextureUnit) # insert the OverlayNode between the coordinate system node and its children. for(unsigned int i=0 i<csn.getNumChildren() ++i) overlayNode.addChild( csn.getChild(i) ) csn.removeChildren(0, csn.getNumChildren()) csn.addChild(overlayNode) viewer.setSceneData(csn) else: overlayNode = osgSim.OverlayNode(technique) overlayNode.getOrCreateStateSet().setTextureAttribute(1, osg.TexEnv(osg.TexEnv.DECAL)) overlayNode.setOverlaySubgraph(shapefile) overlayNode.setOverlayTextureSizeHint(1024) overlayNode.addChild(root) viewer.setSceneData(overlayNode) else: # add a viewport to the viewer and attach the scene graph. viewer.setSceneData(root) csn = dynamic_cast<osg.CoordinateSystemNode*>(root) if csn : overlayNode = osgSim.OverlayNode() if useOverlay : overlayNode = osgSim.OverlayNode(technique) # insert the OverlayNode between the coordinate system node and its children. for(unsigned int i=0 i<csn.getNumChildren() ++i) overlayNode.addChild( csn.getChild(i) ) csn.removeChildren(0, csn.getNumChildren()) csn.addChild(overlayNode) # tell the overlay node to continously update its overlay texture # as we know we'll be tracking a moving target. overlayNode.setContinuousUpdate(True) cessna = osgDB.readNodeFile("cessna.osgt") if cessna : s = 200000.0 / cessna.getBound().radius() scaler = osg.MatrixTransform() scaler.addChild(cessna) scaler.setMatrix(osg.Matrixd.scale(s,s,s)*osg.Matrixd.rotate(rotation)) scaler.getOrCreateStateSet().setMode(GL_RESCALE_NORMAL,osg.StateAttribute.ON) if addFireEffect : center = cessna.getBound().center() fire = osgParticle.FireEffect(center, 10.0) scaler.addChild(fire) if False : ss = osgSim.SphereSegment( osg.Vec3(0.0,0.0,0.0), # center 19.9, # radius osg.DegreesToRadians(135.0), osg.DegreesToRadians(240.0), osg.DegreesToRadians(-10.0), osg.DegreesToRadians(30.0), 60) scaler.addChild(ss) mt = osg.MatrixTransform() mt.addChild(scaler) if not nc : nc = ModelPositionCallback(speed) mt.setUpdateCallback(nc) csn.addChild(mt) # if we are using an overaly node, use the cessna subgraph as the overlay subgraph if overlayNode.valid() : overlayNode.setOverlaySubgraph(mt) tm = osgGA.NodeTrackerManipulator() tm.setTrackerMode(trackerMode) tm.setRotationMode(rotationMode) tm.setTrackNode(scaler) else: print "Failed to read cessna.osgt" # set up camera manipulators. keyswitchManipulator = osgGA.KeySwitchMatrixManipulator() if tm.valid() : keyswitchManipulator.addMatrixManipulator( ord("0"), "NodeTracker", tm ) keyswitchManipulator.addMatrixManipulator( ord("1"), "Trackball", osgGA.TrackballManipulator() ) keyswitchManipulator.addMatrixManipulator( ord("2"), "Flight", osgGA.FlightManipulator() ) keyswitchManipulator.addMatrixManipulator( ord("3"), "Drive", osgGA.DriveManipulator() ) keyswitchManipulator.addMatrixManipulator( ord("4"), "Terrain", osgGA.TerrainManipulator() ) if not pathfile.empty() : apm = osgGA.AnimationPathManipulator(pathfile) if apm or not apm.valid() : num = keyswitchManipulator.getNumMatrixManipulators() keyswitchManipulator.addMatrixManipulator( ord("5"), "Path", apm ) keyswitchManipulator.selectMatrixManipulator(num) viewer.setCameraManipulator( keyswitchManipulator ) # viewer.setThreadingModel(osgViewer.Viewer.SingleThreaded) return viewer.run() if __name__ == "__main__": main(sys.argv)
class #OSGTEXT_EXPORT TextNode : public osg.Group TextNode() TextNode( TextNode text, osg.CopyOp copyop=osg.CopyOp.SHALLOW_COPY) META_Node(osgText, TextNode) traverse = virtual void(osg.NodeVisitor nv) def setFont(font): _font = font def getFont(): return _font def getFont(): return _font def getActiveFont(): return _font : Font: if (_font.valid()) else getDefaultFont() def getActiveFont(): return _font : Font: if (_font.valid()) else getDefaultFont() def setStyle(style): _style = style def getStyle(): return _style def getStyle(): return _style def getActiveStyle(): return _style : Style: if (_style.valid()) else getDefaultStyle() def getActiveStyle(): return _style : Style: if (_style.valid()) else getDefaultStyle() def setLayout(layout): _layout = layout def getLayout(): return _layout def getLayout(): return _layout def getActiveLayout(): return _layout : Layout: if (_layout.valid()) else getDefaultLayout() setTextTechnique = void(TextTechnique* technique) def getTextTechnique(): return _technique def getTextTechnique(): return _technique setText = void( str str) def setText(str): _string = str def getText(): return _string def getText(): return _string def setPosition(position): _position = position def getPosition(): return _position def setRotation(rotation): _rotation = rotation def getRotation(): return _rotation def setCharacterSize(characterSize): _characterSize = characterSize def getCharacterSize(): return _characterSize #/ force a regeneration of the rendering backend required to represent the text. update = virtual void() virtual ~TextNode() _font = Font() _style = Style() _layout = Layout() _technique = TextTechnique() _string = String() _position = osg.Vec3d() _rotation = osg.Quat() _characterSize = float()
static TextTechnique s_defaultTextTechnique = TextTechnique() return s_defaultTextTechnique void TextTechnique.start() OSG_NOTICE, "TextTechnique.start()" void TextTechnique.addCharacter( osg.Vec3 position, osg.Vec3 size, Glyph* glyph, Style* style) OSG_NOTICE, "TextTechnique.addCharacter 2D(", position, ", ", size, ", ", glyph, ", ", style, ")" void TextTechnique.addCharacter( osg.Vec3 position, osg.Vec3 size, Glyph3D* glyph, Style* style) OSG_NOTICE, "TextTechnique.addCharacter 3D(", position, ", ", size, ", ", glyph, ", ", style, ")" transform = osg.PositionAttitudeTransform() transform.setPosition(position) transform.setAttitude(osg.Quat(osg.inDegrees(90.0),osg.Vec3d(1.0,0.0,0.0))) transform.setScale(size) geode = osg.Geode() bevel = style.getBevel() if (style) else 0 outline = style.getOutlineRatio()>0.0 if (style) else False width = style.getThicknessRatio() creaseAngle = 30.0 smooth = True if bevel : thickness = bevel.getBevelThickness() glyphGeometry = osgText.computeGlyphGeometry(glyph, thickness, width) textGeometry = osgText.computeTextGeometry(glyphGeometry, *bevel, width)