Last active
August 29, 2015 14:25
-
-
Save ashumeow/ccd95e08a1ab1c407a01 to your computer and use it in GitHub Desktop.
Revisions
-
James Halliday created this gist
Apr 21, 2011 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,301 @@ import pyscene scene = pyscene.pyscene() import osg, osgDB import math, re, os scene.setScale(5e4, 0.5) scene.viewer.getCamera().setClearColor(osg.Vec4f(0, 0, 0, 0)) mars = scene.readNodeFile("mars.osg") # make the north pole face up instead of down mars_trans = osg.MatrixTransform() mars_trans.postMult( osg.Matrixd.rotate( math.radians(180), 1, 0, 0 ) ) # and position the planet with the meridian facing the camera mars_trans.postMult( osg.Matrixd.rotate( math.radians(180), 0, 0, 1 ) ) mars_trans.addChild(mars) # make it blend (http://www.palomino3d.org/pal/openscenegraph/) GL_BLEND=3042 GL_DEPTH_TEST=2929 GL_LIGHTING=2896 trans_state = osg.StateSet() trans_state.setMode(GL_BLEND, osg.StateAttribute.ON) trans_state.setRenderingHint(osg.StateSet.TRANSPARENT_BIN) trans_state.setMode(GL_DEPTH_TEST, osg.StateAttribute.OFF) trans_state.setMode(GL_LIGHTING, osg.StateAttribute.OFF) trans = 0.15 for radius in 6.4, 6.45, 6.5, 6.6, 6.7, 6.75 : trans /= 1.5 atmo = osg.Sphere( osg.Vec3f(0, 0, 0), radius * 1e6 ) atmo_drawable = osg.ShapeDrawable(atmo) atmo_drawable.setColor( osg.Vec4f(0.76, 0.54, 0.37, trans) ) atmo_geode = osg.Geode() atmo_geode.addDrawable(atmo_drawable) atmo_drawable.setStateSet(trans_state) mars_trans.addChild(atmo_geode) scene.addChild(mars_trans) def plot_coord(lat, lon, image=None, flag=None) : """ Plot a coordinate on the globe with a pin and a billboard that changes its opacity based on the viewer's location """ geode = osg.Geode() cone = osg.Cone( osg.Vec3f(0, 0, 6.7e6), 3e4, -0.3e6 ) cone_drawable = osg.ShapeDrawable(cone) cone_drawable.setColor( osg.Vec4f(1, 0, 0, 1) ) geode.addDrawable(cone_drawable) sphere = osg.Sphere( osg.Vec3f(0, 0, 6.775e6), 3e4 ) sphere_drawable = osg.ShapeDrawable(sphere) sphere_drawable.setColor( osg.Vec4f(1, 0, 0, 0.5) ) geode.addDrawable(sphere_drawable) # Use negative dimensions on the Box to trick out plane-like behaviour board = osg.Box( osg.Vec3f(0, 0, 7.2e6), -5e5 * 1.6, -1e3, 5e5 ) board_drawable = osg.ShapeDrawable(board) bb = osg.Billboard() bb.setNormal( osg.Vec3f(0, 1, 0) ) bb.addDrawable(board_drawable) texture = osg.Texture2D() if isinstance(image, str) : im = osgDB.readImageFile(image) texture.setImage(im) state = osg.StateSet(trans_state) bb.setStateSet(state) depth = osg.Depth() depth.setWriteMask(True) state.setAttributeAndModes(depth, osg.StateAttribute.ON) state.setTextureAttributeAndModes(0, texture, osg.StateAttribute.ON) pin_trans = osg.MatrixTransform() pin_trans.addChild(geode) pin_trans.addChild(bb) pin_trans.postMult( osg.Matrixd.rotate( math.radians(90.0 + lat), 1, 0, 0 ) ) pin_trans.postMult( osg.Matrixd.rotate( math.radians(lon - 90.0), 0, 0, 1 ) ) position = pin_trans.getMatrix() * osg.Vec3d(0, 0, 7.2e6) flag_drawable = None if isinstance(flag, str) : flag_im = osgDB.readImageFile(flag) flag_texture = osg.Texture2D() flag_texture.setImage(flag_im) flag_board = osg.Box( osg.Vec3f( -683.0 / 2 * 5e5 / 512, 1e3, 7.2e6 + (512.0 - 50.0 - 20.0) / 2 * 5.0e5 / 512, ), -100.0 * 5.0e5 / 512, -1e3, 50.0 * 5.0e5 / 512, ) flag_drawable = osg.ShapeDrawable(flag_board) flag_bb = osg.Billboard() flag_bb.setNormal( osg.Vec3f(0, 1, 0) ) flag_bb.addDrawable(flag_drawable) flag_state = osg.StateSet(trans_state) flag_bb.setStateSet(flag_state) flag_state.setAttributeAndModes(depth, osg.StateAttribute.ON) flag_state.setTextureAttributeAndModes( 0, flag_texture, osg.StateAttribute.ON ) pin_trans.addChild(flag_bb) return { "board_drawable" : board_drawable, "flag_drawable" : flag_drawable, "position" : position, "trans" : pin_trans, } labels = { "Olympus Mons" : plot_coord( 18.4, -134, "images/olympus_mons.png", ), "Arsia Mons" : plot_coord( -9.5, -120.5, "images/arsia_mons.png" ), "Ascraeus Mons" : plot_coord( 11.3, -104.5, "images/ascraeus_mons.png" ), "Pavonis Mons" : plot_coord( 0.8, -113.4, "images/pavonis_mons.png" ), "Cydonia Mensae" : plot_coord( 40.7, -170.2, "images/cydonia_mensae.png" ), "Phoenix Lander" : plot_coord( 68, 234, "images/phoenix_lander.png", "images/usa.png", ), "Spirit Rover" : plot_coord( -14.6, 175.5, "images/spirit_rover.png", "images/usa.png", ), "Opportunity Rover" : plot_coord( -1.9, 354.5, "images/opportunity_rover.png", "images/usa.png", ), "Sojourner Rover" : plot_coord( 19.1, -33.2, "images/sojourner_rover.png", "images/usa.png", ), "Viking 1 Lander" : plot_coord( 22.7, -48.2, "images/viking_1_lander.png", "images/usa.png", ), "Viking 2 Lander" : plot_coord( 48.3, -226.0, "images/viking_2_lander.png", "images/usa.png", ), "Mars 2 Lander" : plot_coord( 4, -47, "images/mars_2_lander.png", "images/ussr.png", ), "Mars 3 Lander" : plot_coord( -45, -158, "images/mars_3_lander.png", "images/ussr.png", ), } for value in labels.itervalues() : mars_trans.addChild(value["trans"]) scene.setLighting(False) def label_proximity(self, nv, node) : for (key, value) in labels.iteritems() : d = ( osg.Matrixd.inverse( mars_trans.getMatrix() ) * value["position"] - self.getPosition() ).length() if d > 2e7 : d = 0 else : d = (1 - d / 2e7) ** 2 * 3 color = osg.Vec4f(1, 1, 1, d) labels[key]["board_drawable"].setColor(color) if labels[key]["flag_drawable"] : labels[key]["flag_drawable"].setColor(color) scene.addCallback(label_proximity) scene.planet_velocity = osg.Matrixd() def spin_planet(self, nv, node) : mars_trans.postMult(scene.planet_velocity) scene.addCallback(spin_planet) def button_handler(self, event) : if event["mode"] != "button" : return r = osg.Matrixd.inverse( osg.Matrixd.rotate( self.getViewMatrix().getRotate() ) ) if event["data"][0] == 9 : scene.planet_velocity = osg.Matrixd() elif event["data"][1] == "released" and event["data"][0] in range(4) : scene.planet_velocity = osg.Matrixd() elif event["data"][0] in [ 0, 4 ] : scene.planet_velocity = osg.Matrixd.rotate( math.radians(0.1), r * osg.Vec3d(0, 1, 0) ) elif event["data"][0] == 1 : scene.planet_velocity = osg.Matrixd.rotate( math.radians(0.1), r * osg.Vec3d(1, 0, 0) ) elif event["data"][0] in [ 2, 5 ] : scene.planet_velocity = osg.Matrixd.rotate( math.radians(0.1), r * osg.Vec3d(0, -1, 0) ) elif event["data"][0] == 3 : scene.planet_velocity = osg.Matrixd.rotate( math.radians(0.1), r * osg.Vec3d(-1, 0, 0) ) scene.add_vrpn_handler("mars_buttons", button_handler) scene.postMult( osg.Matrixd.translate(0, 0, 3e7) ) scene.ds.setEyeSeparation(0.001) coordinates = [ (-6.209900, -99.394042, 0), (-6.642782, -92.307128, 0), (-7.079088, -84.440917, 0), (-8.537565, -77.255859, 0), (-10.639013, -70.620117, 0), (-13.304102, -60.644531, 0), (-14.753635, -56.381835, 0), (-15.199386, -50.009765, 0), (-13.432366, -41.352539, 0), (-5.244127, -36.079101, 0), (2.591888, -33.156738, 0), ] def build_links(n=0) : if not coordinates[n:] : return None lat, lon, elev = coordinates[n] point_trans = osg.MatrixTransform() point_trans.postMult( osg.Matrixd.translate(0, 0, 7e6 + elev) ) point_trans.postMult( osg.Matrixd.rotate( math.radians(90.0 + lat), 1, 0, 0 ) ) point_trans.postMult( osg.Matrixd.rotate( math.radians(lon - 90.0), 0, 0, 1 ) ) sphere = osg.Sphere(osg.Vec3f(), 5e4) drawable = osg.ShapeDrawable(sphere) drawable.setColor( osg.Vec4f(0.76, 0.54, 0.37, 0.5) ) geode = osg.Geode() geode.addDrawable(drawable) point_trans.addChild(geode) mars_trans.addChild(point_trans) m = point_trans.getMatrix().getTrans() point = osg.Vec3f(m[0], m[1], m[2]) return { "geode" : geode, "drawable" : drawable, "bound" : osg.BoundingSphere(point, 5e5), "next" : build_links(n+1), } scene.links = build_links() scene.link = scene.links def link_path(self, nv, node) : v = osg.Matrixd.inverse( mars_trans.getMatrix() ) * self.getPosition() v = osg.Vec3f(v[0], v[1], v[2]) if self.link["bound"].contains(v) : print "bound" self.link["drawable"].setColor( osg.Vec4f(0.8, 0.2, 0.2, 0.5) ) self.link = self.link["next"] if not self.link : print "none" self.link = self.links return c = self.link["bound"].center() p = self.getPosition() velocity = osg.Vec3f(p[0], p[1], p[2]) - c #velocity = v - c velocity = osg.Vec3d( velocity[0] / 5e2, velocity[1] / 5e2, velocity[2] / -5e2, ) self.velocity = osg.Matrixd.translate(velocity) #self.getPosition() - osg.Vec3d(c[0], c[1], c[2]) scene.addCallback(link_path) scene.run()