1#!/usr/bin/env python 2# coding: utf-8 3 4### 5# Copyright (c) 2005 Øystein Handegard <handegar@sim.no> 6# 7# Permission to use, copy, modify, and distribute this software for any 8# purpose with or without fee is hereby granted, provided that the above 9# copyright notice and this permission notice appear in all copies. 10# 11# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18# 19 20from __future__ import print_function 21import math 22from pivy.coin import * 23from pivy.sogui import * 24 25############################################################## 26 27def generateColoredLights(distance): 28 scenegraph = SoSeparator() 29 rotor = SoRotor() 30 rotor.rotation = (1, 1, 1, 0) 31 rotor.speed = 0.2 32 33 redlight = SoPointLight() 34 redlight.color = (1, 0, 0) 35 redlight.location = (0, distance, 0) 36 37 goldlight = SoPointLight() 38 goldlight.color = (1, 185.0/256, 75.0/256) 39 goldlight.location = (distance, 0, 0) 40 41 trans = SoTranslation() 42 trans.translation = (distance, 0, distance) 43 44 scenegraph.addChild(rotor) 45 scenegraph.addChild(redlight) 46 scenegraph.addChild(rotor) 47 scenegraph.addChild(goldlight) 48 return scenegraph 49 50def generateTile(height, width, thickness): 51 h = height*(1-(8*thickness)) 52 w = width*(1-(8*thickness)) 53 s = (8*thickness)+1.0 54 t = -thickness 55 56 points = ((0, -w/2.0, -h/2.0), (0, w/2.0, -h/2.0), (0, w/2.0, h/2.0), (0, -w/2.0, h/2.0), 57 (t, -(s*w)/2.0, -(s*h)/2.0), (t, (s*w)/2.0, (-s*h)/2.0), (t, (s*w)/2.0, (s*h)/2.0), (t, (-s*w)/2.0, (s*h)/2.0)) 58 indices = (0, 1, 2, 3, -1, 4, 5, 1, 0, -1, 5, 6, 2, 1, -1, 3, 2, 6, 7, -1, 0, 3, 7, 4, -1 ) 59 60 coordset = SoCoordinate3() 61 coordset.point.setValues(0, len(points), points) 62 63 faceset = SoIndexedFaceSet() 64 faceset.coordIndex.setValues(0, len(indices), indices) 65 66 sep = SoSeparator() 67 sep.addChild(coordset) 68 sep.addChild(faceset) 69 70 return sep 71 72 73def generateMirrorBall(radius, tileheight, tilewidth): 74 root = SoSeparator() 75 76 tilethickness = ((tilewidth + tileheight)/2.0)/50.0 # looks nice 77 tile = generateTile(tileheight, tilewidth, tilethickness) 78 79 radiustrans = SoTranslation() 80 radiustrans.translation = SbVec3f(radius,0,0) 81 82 mirrormat = SoMaterial() 83 mirrormat.specularColor = (1, 1, 1) 84 mirrormat.diffuseColor = (0.2, 0.2, 0.2) 85 mirrormat.shinyness = 0.5 86 root.addChild(mirrormat) 87 88 rot1 = SbRotation() 89 rot2 = SbRotation() 90 91 x = M_PI 92 anglesteplong = M_PI / (2.0 * math.asin(tileheight / (2.0 * radius))) 93 anglesteplat = M_PI / (2.0 * math.asin(tilewidth / (2.0 * radius))) 94 95 while x > 0: 96 y = M_PI*2 97 while y > 0: 98 sep = SoSeparator() 99 rot1.setValue(SbVec3f(0,0,1), x) 100 rot2.setValue(SbVec3f(1, 0, 0), y) 101 y = y - (M_PI*2 / ((anglesteplong*2)*math.sin(x))) 102 rot = SoRotation() 103 rot.rotation = (rot1*rot2) 104 sep.addChild(rot) 105 sep.addChild(radiustrans) 106 sep.addChild(tile) 107 root.addChild(sep) 108 x = x - (M_PI / anglesteplat) 109 110 return root 111 112############################################################## 113 114def main(): 115 myWindow = SoGui.init(sys.argv[0]) 116 if myWindow == None: sys.exit(1) 117 118 # Radius and tile size of the mirror-ball 119 radius = 8 120 tilesizex = 1 121 tilesizey = 0.8 122 123 # Create rotating lights around the ball 124 lights = generateColoredLights(radius * 50.0) 125 lights.addChild(SoResetTransform()) 126 127 # Generate mirror ball. 128 print("Generating a mirror ball with radius %d and tile size %.1fx%.1f..." % (radius, tilesizex, tilesizey)) 129 lights.addChild(generateMirrorBall(radius, tilesizex, tilesizey)) 130 print("...finished.") 131 132 # setup viewer 133 myViewer = SoGuiExaminerViewer(myWindow) 134 myViewer.setSceneGraph(lights) 135 myViewer.setTitle("Examiner Viewer") 136 myViewer.viewAll() 137 myViewer.show() 138 139 SoGui.show(myWindow) 140 SoGui.mainLoop() 141 142 return 0 143 144if __name__ == "__main__": 145 sys.exit(main()) 146