mirror of
https://github.com/quantum5/punyverse.git
synced 2025-04-24 13:11:57 -04:00
Punyverse 0.3: adding Python 3 support.
This commit is contained in:
parent
bb928b6c55
commit
b4dce48fa7
|
@ -8,7 +8,7 @@ Python simulator of a puny universe. (How many words can I stick into one?)
|
||||||
Installation
|
Installation
|
||||||
------------
|
------------
|
||||||
|
|
||||||
Currently, only Python 2 on Windows is supported.
|
Currently, only Windows is supported.
|
||||||
|
|
||||||
To install, run `pip install punyverse`.
|
To install, run `pip install punyverse`.
|
||||||
|
|
||||||
|
|
|
@ -36,9 +36,9 @@ def main():
|
||||||
raise SystemExit('Graphics configuration not supported.')
|
raise SystemExit('Graphics configuration not supported.')
|
||||||
else:
|
else:
|
||||||
if hasattr(config, '_attribute_names'):
|
if hasattr(config, '_attribute_names'):
|
||||||
print 'OpenGL configuration:'
|
print('OpenGL configuration:')
|
||||||
for key in config._attribute_names:
|
for key in config._attribute_names:
|
||||||
print ' %-17s %s' % (key + ':', getattr(config, key))
|
print(' %-17s %s' % (key + ':', getattr(config, key)))
|
||||||
|
|
||||||
world_options = {
|
world_options = {
|
||||||
'normal': args.normal,
|
'normal': args.normal,
|
||||||
|
|
|
@ -41,11 +41,11 @@ cdef class Face(object):
|
||||||
self.textures = textures
|
self.textures = textures
|
||||||
|
|
||||||
cdef class Material(object):
|
cdef class Material(object):
|
||||||
cdef public str name, texture
|
cdef public unicode name, texture
|
||||||
cdef public tuple Ka, Kd, Ks
|
cdef public tuple Ka, Kd, Ks
|
||||||
cdef public double shininess
|
cdef public double shininess
|
||||||
|
|
||||||
def __init__(self, str name, str texture=None, tuple Ka=(0, 0, 0),
|
def __init__(self, unicode name, unicode texture=None, tuple Ka=(0, 0, 0),
|
||||||
tuple Kd=(0, 0, 0), tuple Ks=(0, 0, 0), double shininess=0.0):
|
tuple Kd=(0, 0, 0), tuple Ks=(0, 0, 0), double shininess=0.0):
|
||||||
self.name = name
|
self.name = name
|
||||||
self.texture = texture
|
self.texture = texture
|
||||||
|
@ -55,15 +55,15 @@ cdef class Material(object):
|
||||||
self.shininess = shininess
|
self.shininess = shininess
|
||||||
|
|
||||||
cdef class Group(object):
|
cdef class Group(object):
|
||||||
cdef public str name
|
cdef public unicode name
|
||||||
cdef public tuple min
|
cdef public tuple min
|
||||||
cdef public Material material
|
cdef public Material material
|
||||||
cdef public list faces, indices, vertices, normals, textures
|
cdef public list faces, indices, vertices, normals, textures
|
||||||
cdef public int idx_count
|
cdef public int idx_count
|
||||||
|
|
||||||
def __init__(self, str name=None):
|
def __init__(self, unicode name=None):
|
||||||
if name is None:
|
if name is None:
|
||||||
self.name = str(uuid4())
|
self.name = unicode(uuid4())
|
||||||
else:
|
else:
|
||||||
self.name = name
|
self.name = name
|
||||||
self.min = ()
|
self.min = ()
|
||||||
|
@ -103,8 +103,9 @@ cdef class WavefrontObject(object):
|
||||||
self.perform_io(self.path)
|
self.perform_io(self.path)
|
||||||
|
|
||||||
cdef void new_material(self, list words):
|
cdef void new_material(self, list words):
|
||||||
material = Material(words[1])
|
name = words[1].decode('utf-8')
|
||||||
self.materials[words[1]] = material
|
material = Material(name)
|
||||||
|
self.materials[name] = material
|
||||||
self.current_material = material
|
self.current_material = material
|
||||||
|
|
||||||
cdef void Ka(self, list words):
|
cdef void Ka(self, list words):
|
||||||
|
@ -120,7 +121,7 @@ cdef class WavefrontObject(object):
|
||||||
self.current_material.shininess = min(float(words[1]), 125)
|
self.current_material.shininess = min(float(words[1]), 125)
|
||||||
|
|
||||||
cdef void material_texture(self, list words):
|
cdef void material_texture(self, list words):
|
||||||
self.current_material.texture = words[-1]
|
self.current_material.texture = words[-1].decode('utf-8')
|
||||||
|
|
||||||
@cython.nonecheck(False)
|
@cython.nonecheck(False)
|
||||||
cdef void vertex(self, list words):
|
cdef void vertex(self, list words):
|
||||||
|
@ -157,7 +158,7 @@ cdef class WavefrontObject(object):
|
||||||
cdef list raw_faces, vindices = [], nindices = [], tindices = []
|
cdef list raw_faces, vindices = [], nindices = [], tindices = []
|
||||||
|
|
||||||
for i in xrange(1, vertex_count + 1):
|
for i in xrange(1, vertex_count + 1):
|
||||||
raw_faces = words[i].split('/')
|
raw_faces = words[i].split(b'/')
|
||||||
l = len(raw_faces)
|
l = len(raw_faces)
|
||||||
|
|
||||||
current_value = int(raw_faces[0])
|
current_value = int(raw_faces[0])
|
||||||
|
@ -193,10 +194,10 @@ cdef class WavefrontObject(object):
|
||||||
group.faces.append(Face(type, vindices, nindices, tindices, face_vertices, face_normals, face_textures))
|
group.faces.append(Face(type, vindices, nindices, tindices, face_vertices, face_normals, face_textures))
|
||||||
|
|
||||||
cdef bint material(self, list words) except False:
|
cdef bint material(self, list words) except False:
|
||||||
return self.perform_io(os.path.join(self.root, words[1]))
|
return self.perform_io(os.path.join(self.root, words[1].decode('utf-8')))
|
||||||
|
|
||||||
cdef void use_material(self, list words):
|
cdef void use_material(self, list words):
|
||||||
mat = words[1]
|
mat = words[1].decode('utf-8')
|
||||||
try:
|
try:
|
||||||
self.current_group.material = self.materials[mat]
|
self.current_group.material = self.materials[mat]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
|
@ -205,7 +206,7 @@ cdef class WavefrontObject(object):
|
||||||
print "Warning: no group"
|
print "Warning: no group"
|
||||||
|
|
||||||
cdef void group(self, list words):
|
cdef void group(self, list words):
|
||||||
name = words[1]
|
name = words[1].decode('utf-8')
|
||||||
group = Group(name)
|
group = Group(name)
|
||||||
|
|
||||||
if self.groups:
|
if self.groups:
|
||||||
|
@ -219,10 +220,10 @@ cdef class WavefrontObject(object):
|
||||||
cdef int hash, length
|
cdef int hash, length
|
||||||
|
|
||||||
ext = os.path.splitext(file)[1].lstrip('.')
|
ext = os.path.splitext(file)[1].lstrip('.')
|
||||||
reader = openers.get(ext, open)(file)
|
reader = openers.get(ext, lambda x: open(x, 'rb'))(file)
|
||||||
with reader:
|
with reader:
|
||||||
for buf in reader:
|
for buf in reader:
|
||||||
if not buf or buf.startswith(('\r', '\n', '#')):
|
if not buf or buf.startswith((b'\r', b'\n', b'#')):
|
||||||
continue # Empty or comment
|
continue # Empty or comment
|
||||||
words = buf.split()
|
words = buf.split()
|
||||||
type = words[0]
|
type = words[0]
|
||||||
|
@ -267,11 +268,7 @@ model_base = None
|
||||||
def load_model(path):
|
def load_model(path):
|
||||||
global model_base
|
global model_base
|
||||||
if model_base is None:
|
if model_base is None:
|
||||||
import sys
|
model_base = os.path.join(os.path.dirname(__file__), 'assets', 'models')
|
||||||
if hasattr(sys, 'frozen'):
|
|
||||||
model_base = os.path.dirname(sys.executable)
|
|
||||||
else:
|
|
||||||
model_base = os.path.join(os.path.dirname(__file__), 'assets', 'models')
|
|
||||||
if not os.path.isabs(path):
|
if not os.path.isabs(path):
|
||||||
path = os.path.join(model_base, path)
|
path = os.path.join(model_base, path)
|
||||||
if not isinstance(path, unicode):
|
if not isinstance(path, unicode):
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
from math import sqrt
|
from math import sqrt
|
||||||
|
|
||||||
from punyverse.orbit import KeplerOrbit
|
from six.moves import range
|
||||||
from pyglet.gl import *
|
from pyglet.gl import *
|
||||||
|
|
||||||
|
from punyverse.orbit import KeplerOrbit
|
||||||
|
|
||||||
|
|
||||||
class Entity(object):
|
class Entity(object):
|
||||||
def __init__(self, id, location, rotation=(0, 0, 0), direction=(0, 0, 0), background=False):
|
def __init__(self, id, location, rotation=(0, 0, 0), direction=(0, 0, 0), background=False):
|
||||||
|
@ -118,7 +120,7 @@ class Satellite(Body):
|
||||||
id = glGenLists(1)
|
id = glGenLists(1)
|
||||||
glNewList(id, GL_COMPILE)
|
glNewList(id, GL_COMPILE)
|
||||||
glBegin(GL_LINE_LOOP)
|
glBegin(GL_LINE_LOOP)
|
||||||
for theta in xrange(360):
|
for theta in range(360):
|
||||||
x, z, y = self.orbit.orbit(theta)
|
x, z, y = self.orbit.orbit(theta)
|
||||||
glVertex3f(x, y, z)
|
glVertex3f(x, y, z)
|
||||||
glEnd()
|
glEnd()
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
from operator import attrgetter
|
from operator import attrgetter
|
||||||
from math import hypot, sqrt, atan2, degrees
|
from math import hypot, sqrt, atan2, degrees
|
||||||
from time import clock
|
from time import clock
|
||||||
from itertools import izip_longest
|
|
||||||
import time
|
import time
|
||||||
import random
|
import random
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
from punyverse.camera import Camera
|
from punyverse.camera import Camera
|
||||||
from punyverse.world import World
|
from punyverse.world import World
|
||||||
from punyverse.glgeom import *
|
from punyverse.glgeom import *
|
||||||
|
@ -18,6 +19,11 @@ try:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
from punyverse.model import model_list, load_model
|
from punyverse.model import model_list, load_model
|
||||||
|
|
||||||
|
try:
|
||||||
|
from itertools import zip_longest
|
||||||
|
except ImportError:
|
||||||
|
from itertools import izip_longest as zip_longest
|
||||||
|
|
||||||
from pyglet.gl import *
|
from pyglet.gl import *
|
||||||
from pyglet.window import key, mouse
|
from pyglet.window import key, mouse
|
||||||
|
|
||||||
|
@ -50,7 +56,7 @@ class Applet(pyglet.window.Window):
|
||||||
info = [' %-22s %s' % (key + ':', getattr(self.config, key))
|
info = [' %-22s %s' % (key + ':', getattr(self.config, key))
|
||||||
for key in self.config._attribute_names]
|
for key in self.config._attribute_names]
|
||||||
info = ['%-30s %-30s' % group for group in
|
info = ['%-30s %-30s' % group for group in
|
||||||
izip_longest(info[::2], info[1::2], fillvalue='')]
|
zip_longest(info[::2], info[1::2], fillvalue='')]
|
||||||
info = 'OpenGL configuration:\n' + '\n'.join(info)
|
info = 'OpenGL configuration:\n' + '\n'.join(info)
|
||||||
else:
|
else:
|
||||||
info = 'Unknown OpenGL configuration'
|
info = 'Unknown OpenGL configuration'
|
||||||
|
@ -89,7 +95,7 @@ class Applet(pyglet.window.Window):
|
||||||
self.fps = 0
|
self.fps = 0
|
||||||
self.world = World('world.json', callback, self.world_options)
|
self.world = World('world.json', callback, self.world_options)
|
||||||
phase = 'Initializing game...'
|
phase = 'Initializing game...'
|
||||||
print phase
|
print(phase)
|
||||||
callback(phase, '', 0)
|
callback(phase, '', 0)
|
||||||
self.speed = INITIAL_SPEED
|
self.speed = INITIAL_SPEED
|
||||||
self.keys = set()
|
self.keys = set()
|
||||||
|
@ -158,7 +164,6 @@ class Applet(pyglet.window.Window):
|
||||||
key.C: attribute_toggler(self, 'cloud'),
|
key.C: attribute_toggler(self, 'cloud'),
|
||||||
key.X: attribute_toggler(self, 'atmosphere'),
|
key.X: attribute_toggler(self, 'atmosphere'),
|
||||||
key.ENTER: attribute_toggler(self, 'running'),
|
key.ENTER: attribute_toggler(self, 'running'),
|
||||||
#key.Q: self.screenshot,
|
|
||||||
key.INSERT: increment_tick,
|
key.INSERT: increment_tick,
|
||||||
key.DELETE: decrement_tick,
|
key.DELETE: decrement_tick,
|
||||||
key.SPACE: self.launch_meteor,
|
key.SPACE: self.launch_meteor,
|
||||||
|
@ -203,7 +208,7 @@ class Applet(pyglet.window.Window):
|
||||||
glLightfv(GL_LIGHT1, GL_SPECULAR, fv4(1, 1, 1, 1))
|
glLightfv(GL_LIGHT1, GL_SPECULAR, fv4(1, 1, 1, 1))
|
||||||
|
|
||||||
phase = 'Loading asteroids...'
|
phase = 'Loading asteroids...'
|
||||||
print phase
|
print(phase)
|
||||||
|
|
||||||
def load_asteroids(files):
|
def load_asteroids(files):
|
||||||
for id, file in enumerate(files):
|
for id, file in enumerate(files):
|
||||||
|
@ -217,12 +222,12 @@ class Applet(pyglet.window.Window):
|
||||||
c.pitch, c.yaw, c.roll = self.world.direction
|
c.pitch, c.yaw, c.roll = self.world.direction
|
||||||
|
|
||||||
phase = 'Updating entities...'
|
phase = 'Updating entities...'
|
||||||
print phase
|
print(phase)
|
||||||
callback(phase, '', 0)
|
callback(phase, '', 0)
|
||||||
for entity in self.world.tracker:
|
for entity in self.world.tracker:
|
||||||
entity.update()
|
entity.update()
|
||||||
|
|
||||||
print 'Loaded in %s seconds.' % (clock() - start)
|
print('Loaded in %s seconds.' % (clock() - start))
|
||||||
self.loaded = True
|
self.loaded = True
|
||||||
pyglet.clock.schedule(self.update)
|
pyglet.clock.schedule(self.update)
|
||||||
self.on_resize(self.width, self.height) # On resize handler does nothing unless it's loaded
|
self.on_resize(self.width, self.height) # On resize handler does nothing unless it's loaded
|
||||||
|
@ -235,13 +240,13 @@ class Applet(pyglet.window.Window):
|
||||||
import tempfile
|
import tempfile
|
||||||
CF_BITMAP = 2
|
CF_BITMAP = 2
|
||||||
|
|
||||||
image = Image.fromstring(image.format, (image.width, image.height), image.get_image_data().data)
|
image = Image.frombytes(image.format, (image.width, image.height), image.get_image_data().data)
|
||||||
image = image.convert('RGB').transpose(Image.FLIP_TOP_BOTTOM)
|
image = image.convert('RGB').transpose(Image.FLIP_TOP_BOTTOM)
|
||||||
fd, filename = tempfile.mkstemp('.bmp')
|
fd, filename = tempfile.mkstemp('.bmp')
|
||||||
try:
|
try:
|
||||||
with os.fdopen(fd, 'w') as file:
|
with os.fdopen(fd, 'wb') as file:
|
||||||
image.save(file, 'BMP')
|
image.save(file, 'BMP')
|
||||||
if not isinstance(filename, unicode):
|
if isinstance(filename, six.binary_type):
|
||||||
filename = filename.decode('mbcs')
|
filename = filename.decode('mbcs')
|
||||||
image = windll.user32.LoadImageW(None, filename, 0, 0, 0, 0x10)
|
image = windll.user32.LoadImageW(None, filename, 0, 0, 0, 0x10)
|
||||||
windll.user32.OpenClipboard(self._hwnd)
|
windll.user32.OpenClipboard(self._hwnd)
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
from math import *
|
from math import *
|
||||||
from pyglet.gl import *
|
|
||||||
from random import random, gauss, choice
|
from random import random, gauss, choice
|
||||||
|
|
||||||
|
from six.moves import range
|
||||||
|
from pyglet.gl import *
|
||||||
from pyglet.gl.gl_info import have_extension
|
from pyglet.gl.gl_info import have_extension
|
||||||
|
|
||||||
TWOPI = pi * 2
|
TWOPI = pi * 2
|
||||||
|
@ -68,7 +70,8 @@ def frustrum():
|
||||||
glEnable(GL_DEPTH_TEST)
|
glEnable(GL_DEPTH_TEST)
|
||||||
|
|
||||||
|
|
||||||
def crosshair(size, (cx, cy)):
|
def crosshair(size, coords):
|
||||||
|
cx, cy = coords
|
||||||
with glSection(GL_LINES):
|
with glSection(GL_LINES):
|
||||||
glVertex2f(cx - size, cy)
|
glVertex2f(cx - size, cy)
|
||||||
glVertex2f(cx + size, cy)
|
glVertex2f(cx + size, cy)
|
||||||
|
@ -76,9 +79,10 @@ def crosshair(size, (cx, cy)):
|
||||||
glVertex2f(cx, cy + size)
|
glVertex2f(cx, cy + size)
|
||||||
|
|
||||||
|
|
||||||
def circle(r, seg, (cx, cy)):
|
def circle(r, seg, coords):
|
||||||
|
cx, cy = coords
|
||||||
with glSection(GL_LINE_LOOP):
|
with glSection(GL_LINE_LOOP):
|
||||||
for i in xrange(seg):
|
for i in range(seg):
|
||||||
theta = TWOPI * i / seg
|
theta = TWOPI * i / seg
|
||||||
glVertex2f(cx + cos(theta) * r, cy + sin(theta) * r)
|
glVertex2f(cx + cos(theta) * r, cy + sin(theta) * r)
|
||||||
|
|
||||||
|
@ -95,7 +99,7 @@ def disk(rinner, router, segs, tex):
|
||||||
with glSection(GL_TRIANGLE_STRIP):
|
with glSection(GL_TRIANGLE_STRIP):
|
||||||
factor = TWOPI / res
|
factor = TWOPI / res
|
||||||
theta = 0
|
theta = 0
|
||||||
for n in xrange(res + 1):
|
for n in range(res + 1):
|
||||||
theta += factor
|
theta += factor
|
||||||
x = cos(theta)
|
x = cos(theta)
|
||||||
y = sin(theta)
|
y = sin(theta)
|
||||||
|
@ -117,7 +121,7 @@ def flare(rinner, router, res, prob, tex):
|
||||||
factor = TWOPI / res
|
factor = TWOPI / res
|
||||||
rdelta = (router - rinner)
|
rdelta = (router - rinner)
|
||||||
with glSection(GL_QUADS):
|
with glSection(GL_QUADS):
|
||||||
for i in xrange(res + 1):
|
for i in range(res + 1):
|
||||||
theta = last_theta + factor
|
theta = last_theta + factor
|
||||||
x = cos(theta)
|
x = cos(theta)
|
||||||
y = sin(theta)
|
y = sin(theta)
|
||||||
|
@ -192,7 +196,7 @@ def normal_sphere(r, divide, tex, normal, lighting=True, fv4=GLfloat * 4):
|
||||||
if (not have_extension('GL_ARB_multitexture') or not
|
if (not have_extension('GL_ARB_multitexture') or not
|
||||||
have_extension('GL_ARB_texture_env_combine') or not
|
have_extension('GL_ARB_texture_env_combine') or not
|
||||||
have_extension('GL_EXT_texture_env_dot3')):
|
have_extension('GL_EXT_texture_env_dot3')):
|
||||||
print 'No hardware normal mapping support. No bumping for you.'
|
print('No hardware normal mapping support. No bumping for you.')
|
||||||
return sphere(r, divide, divide, tex, lighting)
|
return sphere(r, divide, divide, tex, lighting)
|
||||||
|
|
||||||
from texture import load_texture
|
from texture import load_texture
|
||||||
|
@ -228,11 +232,11 @@ def normal_sphere(r, divide, tex, normal, lighting=True, fv4=GLfloat * 4):
|
||||||
twopi_divide = TWOPI / divide
|
twopi_divide = TWOPI / divide
|
||||||
pi_divide = pi / divide
|
pi_divide = pi / divide
|
||||||
with glSection(GL_TRIANGLE_STRIP):
|
with glSection(GL_TRIANGLE_STRIP):
|
||||||
for j in xrange(divide + 1):
|
for j in range(divide + 1):
|
||||||
phi1 = j * twopi_divide
|
phi1 = j * twopi_divide
|
||||||
phi2 = (j + 1) * twopi_divide
|
phi2 = (j + 1) * twopi_divide
|
||||||
|
|
||||||
for i in xrange(divide + 1):
|
for i in range(divide + 1):
|
||||||
theta = i * pi_divide
|
theta = i * pi_divide
|
||||||
|
|
||||||
s = phi2 / TWOPI
|
s = phi2 / TWOPI
|
||||||
|
@ -252,7 +256,7 @@ def normal_sphere(r, divide, tex, normal, lighting=True, fv4=GLfloat * 4):
|
||||||
|
|
||||||
|
|
||||||
def belt(radius, cross, object, count):
|
def belt(radius, cross, object, count):
|
||||||
for i in xrange(count):
|
for i in range(count):
|
||||||
theta = TWOPI * random()
|
theta = TWOPI * random()
|
||||||
r = gauss(radius, cross)
|
r = gauss(radius, cross)
|
||||||
x, y, z = cos(theta) * r, gauss(0, cross), sin(theta) * r
|
x, y, z = cos(theta) * r, gauss(0, cross), sin(theta) * r
|
||||||
|
@ -285,7 +289,7 @@ except ImportError:
|
||||||
m = 1.0 / sqrt(x * x + y * y + z * z)
|
m = 1.0 / sqrt(x * x + y * y + z * z)
|
||||||
return x * m, y * m, z * m
|
return x * m, y * m, z * m
|
||||||
|
|
||||||
for i in xrange(n_major):
|
for i in range(n_major):
|
||||||
a0 = i * major_s
|
a0 = i * major_s
|
||||||
a1 = a0 + major_s
|
a1 = a0 + major_s
|
||||||
x0 = cos(a0)
|
x0 = cos(a0)
|
||||||
|
@ -294,7 +298,7 @@ except ImportError:
|
||||||
y1 = sin(a1)
|
y1 = sin(a1)
|
||||||
|
|
||||||
with glSection(GL_TRIANGLE_STRIP):
|
with glSection(GL_TRIANGLE_STRIP):
|
||||||
for j in xrange(n_minor + 1):
|
for j in range(n_minor + 1):
|
||||||
b = j * minor_s
|
b = j * minor_s
|
||||||
c = cos(b)
|
c = cos(b)
|
||||||
r = minor_radius * c + major_radius
|
r = minor_radius * c + major_radius
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
from punyverse.texture import load_texture
|
|
||||||
|
|
||||||
from pyglet.gl import *
|
|
||||||
from uuid import uuid4
|
from uuid import uuid4
|
||||||
import os
|
import os
|
||||||
import gzip
|
import gzip
|
||||||
import bz2
|
import bz2
|
||||||
import zipfile
|
import zipfile
|
||||||
|
|
||||||
|
import six
|
||||||
|
from six.moves import range
|
||||||
|
from pyglet.gl import *
|
||||||
|
|
||||||
|
from punyverse.texture import load_texture
|
||||||
|
|
||||||
|
|
||||||
def zip_open(file):
|
def zip_open(file):
|
||||||
zip = zipfile.ZipFile(file)
|
zip = zipfile.ZipFile(file)
|
||||||
|
@ -82,8 +85,9 @@ class WavefrontObject(object):
|
||||||
self.perform_io(self.path)
|
self.perform_io(self.path)
|
||||||
|
|
||||||
def new_material(self, words):
|
def new_material(self, words):
|
||||||
material = Material(words[1])
|
name = words[1].decode('utf-8')
|
||||||
self.materials[words[1]] = material
|
material = Material(name)
|
||||||
|
self.materials[name] = material
|
||||||
self.current_material = material
|
self.current_material = material
|
||||||
|
|
||||||
def Ka(self, words):
|
def Ka(self, words):
|
||||||
|
@ -99,7 +103,7 @@ class WavefrontObject(object):
|
||||||
self.current_material.shininess = min(float(words[1]), 125)
|
self.current_material.shininess = min(float(words[1]), 125)
|
||||||
|
|
||||||
def material_texture(self, words):
|
def material_texture(self, words):
|
||||||
self.current_material.texture = words[-1]
|
self.current_material.texture = words[-1].decode('utf-8')
|
||||||
|
|
||||||
def vertex(self, words):
|
def vertex(self, words):
|
||||||
self.vertices.append((float(words[1]), float(words[2]), float(words[3])))
|
self.vertices.append((float(words[1]), float(words[2]), float(words[3])))
|
||||||
|
@ -138,8 +142,8 @@ class WavefrontObject(object):
|
||||||
nindices = []
|
nindices = []
|
||||||
tindices = []
|
tindices = []
|
||||||
|
|
||||||
for i in xrange(1, vertex_count + 1):
|
for i in range(1, vertex_count + 1):
|
||||||
raw_faces = words[i].split('/')
|
raw_faces = words[i].split(b'/')
|
||||||
l = len(raw_faces)
|
l = len(raw_faces)
|
||||||
|
|
||||||
current_value = int(raw_faces[0])
|
current_value = int(raw_faces[0])
|
||||||
|
@ -174,19 +178,19 @@ class WavefrontObject(object):
|
||||||
group.faces.append(Face(type, vindices, nindices, tindices, face_vertices, face_normals, face_textures))
|
group.faces.append(Face(type, vindices, nindices, tindices, face_vertices, face_normals, face_textures))
|
||||||
|
|
||||||
def material(self, words):
|
def material(self, words):
|
||||||
self.perform_io(os.path.join(self.root, words[1]))
|
self.perform_io(os.path.join(self.root, words[1].decode('utf-8')))
|
||||||
|
|
||||||
def use_material(self, words):
|
def use_material(self, words):
|
||||||
mat = words[1]
|
mat = words[1].decode('utf-8')
|
||||||
try:
|
try:
|
||||||
self.current_group.material = self.materials[mat]
|
self.current_group.material = self.materials[mat]
|
||||||
except KeyError:
|
except KeyError:
|
||||||
print "Warning: material %s undefined, only %s defined." % (mat, self.materials)
|
print("Warning: material %s undefined, only %s defined." % (mat, self.materials))
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
print "Warning: no group"
|
print("Warning: no group")
|
||||||
|
|
||||||
def group(self, words):
|
def group(self, words):
|
||||||
name = words[1]
|
name = words[1].decode('utf-8')
|
||||||
group = Group(name)
|
group = Group(name)
|
||||||
|
|
||||||
if self.groups:
|
if self.groups:
|
||||||
|
@ -196,29 +200,29 @@ class WavefrontObject(object):
|
||||||
|
|
||||||
def perform_io(self, file):
|
def perform_io(self, file):
|
||||||
ext = os.path.splitext(file)[1].lstrip('.')
|
ext = os.path.splitext(file)[1].lstrip('.')
|
||||||
reader = openers.get(ext, open)(file)
|
reader = openers.get(ext, lambda x: open(x, 'rb'))(file)
|
||||||
|
|
||||||
dispatcher = {
|
dispatcher = {
|
||||||
'v': self.vertex,
|
b'v': self.vertex,
|
||||||
'vn': self.normal,
|
b'vn': self.normal,
|
||||||
'vt': self.texture,
|
b'vt': self.texture,
|
||||||
'f': self.face,
|
b'f': self.face,
|
||||||
'mtllib': self.material,
|
b'mtllib': self.material,
|
||||||
'usemtl': self.use_material,
|
b'usemtl': self.use_material,
|
||||||
'g': self.group,
|
b'g': self.group,
|
||||||
'o': self.group,
|
b'o': self.group,
|
||||||
'newmtl': self.new_material,
|
b'newmtl': self.new_material,
|
||||||
'Ka': self.Ka,
|
b'Ka': self.Ka,
|
||||||
'Kd': self.Kd,
|
b'Kd': self.Kd,
|
||||||
'Ks': self.Ks,
|
b'Ks': self.Ks,
|
||||||
'Ns': self.material_shininess,
|
b'Ns': self.material_shininess,
|
||||||
'map_Kd': self.material_texture,
|
b'map_Kd': self.material_texture,
|
||||||
}
|
}
|
||||||
default = lambda words: None
|
default = lambda words: None
|
||||||
|
|
||||||
with reader:
|
with reader:
|
||||||
for buf in reader:
|
for buf in reader:
|
||||||
if not buf or buf.startswith(('\r', '\n', '#')):
|
if not buf or buf.startswith((b'\r', b'\n', b'#')):
|
||||||
continue # Empty or comment
|
continue # Empty or comment
|
||||||
words = buf.split()
|
words = buf.split()
|
||||||
type = words[0]
|
type = words[0]
|
||||||
|
@ -236,13 +240,13 @@ else:
|
||||||
def load_model(path):
|
def load_model(path):
|
||||||
if not os.path.isabs(path):
|
if not os.path.isabs(path):
|
||||||
path = os.path.join(model_base, path)
|
path = os.path.join(model_base, path)
|
||||||
if not isinstance(path, unicode):
|
if isinstance(path, six.binary_type):
|
||||||
path = path.decode('mbcs')
|
path = path.decode('mbcs')
|
||||||
return WavefrontObject(path)
|
return WavefrontObject(path)
|
||||||
|
|
||||||
|
|
||||||
def model_list(model, sx=1, sy=1, sz=1, rotation=(0, 0, 0)):
|
def model_list(model, sx=1, sy=1, sz=1, rotation=(0, 0, 0)):
|
||||||
for m, text in model.materials.iteritems():
|
for m, text in six.iteritems(model.materials):
|
||||||
if text.texture:
|
if text.texture:
|
||||||
load_texture(os.path.join(model.root, text.texture))
|
load_texture(os.path.join(model.root, text.texture))
|
||||||
|
|
||||||
|
@ -300,18 +304,13 @@ def model_list(model, sx=1, sy=1, sz=1, rotation=(0, 0, 0)):
|
||||||
x, y, z = vertices[f.verts[n]]
|
x, y, z = vertices[f.verts[n]]
|
||||||
glVertex3f(x * sx, y * sy, z * sz)
|
glVertex3f(x * sx, y * sy, z * sz)
|
||||||
|
|
||||||
|
glBegin(GL_TRIANGLES)
|
||||||
for f in g.faces:
|
for f in g.faces:
|
||||||
if type != f.type:
|
|
||||||
if type != -1:
|
|
||||||
glEnd()
|
|
||||||
glBegin(GL_TRIANGLES)
|
|
||||||
type = f.type
|
|
||||||
|
|
||||||
point(f, vertices, normals, textures, 0)
|
point(f, vertices, normals, textures, 0)
|
||||||
point(f, vertices, normals, textures, 1)
|
point(f, vertices, normals, textures, 1)
|
||||||
point(f, vertices, normals, textures, 2)
|
point(f, vertices, normals, textures, 2)
|
||||||
|
|
||||||
if type == FACE_QUADS:
|
if f.type == FACE_QUADS:
|
||||||
point(f, vertices, normals, textures, 2)
|
point(f, vertices, normals, textures, 2)
|
||||||
point(f, vertices, normals, textures, 3)
|
point(f, vertices, normals, textures, 3)
|
||||||
point(f, vertices, normals, textures, 0)
|
point(f, vertices, normals, textures, 0)
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
@ -60,7 +62,7 @@ def shrink(file):
|
||||||
image = get_image(file)
|
image = get_image(file)
|
||||||
width, height = get_size(image)
|
width, height = get_size(image)
|
||||||
if fits(width, height):
|
if fits(width, height):
|
||||||
print 'no need'
|
print('no need')
|
||||||
return
|
return
|
||||||
width, height = resize(width, height, 2048)
|
width, height = resize(width, height, 2048)
|
||||||
if fits(width, height):
|
if fits(width, height):
|
||||||
|
@ -68,14 +70,14 @@ def shrink(file):
|
||||||
else:
|
else:
|
||||||
width, height = resize(width, height, 1024) # 1024 is minimum
|
width, height = resize(width, height, 1024) # 1024 is minimum
|
||||||
size = 'small'
|
size = 'small'
|
||||||
print 'size %s, %dx%d...' % (size, width, height),
|
print('size %s, %dx%d...' % (size, width, height), end=' ')
|
||||||
name = make_name(file, size)
|
name = make_name(file, size)
|
||||||
if not os.path.exists(name):
|
if not os.path.exists(name):
|
||||||
image = scale(image, width, height)
|
image = scale(image, width, height)
|
||||||
print 'saved to:', os.path.basename(name)
|
print('saved to:', os.path.basename(name))
|
||||||
save(image, name)
|
save(image, name)
|
||||||
else:
|
else:
|
||||||
print 'alrady there'
|
print('alrady there')
|
||||||
|
|
||||||
textures = [
|
textures = [
|
||||||
'mercury.jpg',
|
'mercury.jpg',
|
||||||
|
@ -106,12 +108,12 @@ def main():
|
||||||
files = textures
|
files = textures
|
||||||
texture = os.path.join(punyverse, 'assets', 'textures')
|
texture = os.path.join(punyverse, 'assets', 'textures')
|
||||||
for file in files:
|
for file in files:
|
||||||
print 'Resizing %s:' % file,
|
print('Resizing %s:' % file, end=' ')
|
||||||
file = os.path.join(texture, file.replace('/', os.sep))
|
file = os.path.join(texture, file.replace('/', os.sep))
|
||||||
if os.path.exists(file):
|
if os.path.exists(file):
|
||||||
shrink(file)
|
shrink(file)
|
||||||
else:
|
else:
|
||||||
print 'exists not'
|
print('exists not')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
main()
|
main()
|
||||||
|
|
|
@ -1,12 +1,18 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
from pyglet import image
|
from pyglet import image
|
||||||
from pyglet.gl import *
|
from pyglet.gl import *
|
||||||
from ctypes import c_int, byref, c_ulong
|
from ctypes import c_int, byref, c_ulong
|
||||||
import os.path
|
import os.path
|
||||||
import struct
|
import struct
|
||||||
import itertools
|
import itertools
|
||||||
|
from io import BytesIO
|
||||||
|
|
||||||
|
import six
|
||||||
|
from six.moves import zip
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from _glgeom import bgr_to_rgb
|
from punyverse._glgeom import bgr_to_rgb
|
||||||
except ImportError:
|
except ImportError:
|
||||||
import warnings
|
import warnings
|
||||||
warnings.warn('Compile _glgeom.c, or double the start up time.')
|
warnings.warn('Compile _glgeom.c, or double the start up time.')
|
||||||
|
@ -19,17 +25,19 @@ except ImportError:
|
||||||
else:
|
else:
|
||||||
magick = True
|
magick = True
|
||||||
|
|
||||||
|
from six.moves import range
|
||||||
|
|
||||||
def bgr_to_rgb(source, width, height, alpha=False, bottom_up=True):
|
def bgr_to_rgb(source, width, height, alpha=False, bottom_up=True):
|
||||||
length = len(source)
|
length = len(source)
|
||||||
depth = length / (width * height)
|
depth = length // (width * height)
|
||||||
depth2 = depth - alpha
|
depth2 = depth - alpha
|
||||||
result = bytearray(length)
|
result = bytearray(length)
|
||||||
row = width * depth
|
row = width * depth
|
||||||
for y in xrange(height):
|
for y in range(height):
|
||||||
for x in xrange(width):
|
for x in range(width):
|
||||||
ioffset = y * width * depth + x * depth
|
ioffset = y * width * depth + x * depth
|
||||||
ooffset = (height - y - 1 if bottom_up else y) * row + x * depth
|
ooffset = (height - y - 1 if bottom_up else y) * row + x * depth
|
||||||
for i in xrange(depth2):
|
for i in range(depth2):
|
||||||
result[ooffset+i] = source[ioffset+depth2-i-1]
|
result[ooffset+i] = source[ioffset+depth2-i-1]
|
||||||
if alpha:
|
if alpha:
|
||||||
result[ooffset+depth2] = source[ioffset+depth2]
|
result[ooffset+depth2] = source[ioffset+depth2]
|
||||||
|
@ -37,11 +45,6 @@ except ImportError:
|
||||||
else:
|
else:
|
||||||
magick = False
|
magick = False
|
||||||
|
|
||||||
try:
|
|
||||||
from cStringIO import StringIO
|
|
||||||
except ImportError:
|
|
||||||
from StringIO import StringIO
|
|
||||||
|
|
||||||
__all__ = ['load_texture', 'load_clouds', 'load_image', 'pil_load']
|
__all__ = ['load_texture', 'load_clouds', 'load_image', 'pil_load']
|
||||||
|
|
||||||
id = 0
|
id = 0
|
||||||
|
@ -64,10 +67,8 @@ def init():
|
||||||
if badcard:
|
if badcard:
|
||||||
import warnings
|
import warnings
|
||||||
warnings.warn('Please update your graphics drivers if possible')
|
warnings.warn('Please update your graphics drivers if possible')
|
||||||
#extensions = gl_info.get_extensions()
|
# Currently, BGRA images are flipped.
|
||||||
#bgra = 'GL_EXT_bgra' in extensions
|
# bgra = gl_info.have_extension('GL_EXT_bgra')
|
||||||
#if bgra and magick:
|
|
||||||
# magick = False # Disable magick because BGRA needs it not
|
|
||||||
|
|
||||||
if power_of_two is None:
|
if power_of_two is None:
|
||||||
power_of_two = gl_info.have_version(2) or gl_info.have_extension('GL_ARB_texture_non_power_of_two')
|
power_of_two = gl_info.have_version(2) or gl_info.have_extension('GL_ARB_texture_non_power_of_two')
|
||||||
|
@ -111,7 +112,7 @@ def image_info(data):
|
||||||
# handle JPEGs
|
# handle JPEGs
|
||||||
elif (size >= 2) and data.startswith('\377\330'):
|
elif (size >= 2) and data.startswith('\377\330'):
|
||||||
content_type = 'image/jpeg'
|
content_type = 'image/jpeg'
|
||||||
jpeg = StringIO(data)
|
jpeg = BytesIO(data)
|
||||||
jpeg.read(2)
|
jpeg.read(2)
|
||||||
b = jpeg.read(1)
|
b = jpeg.read(1)
|
||||||
try:
|
try:
|
||||||
|
@ -140,21 +141,21 @@ def image_info(data):
|
||||||
def check_size(width, height):
|
def check_size(width, height):
|
||||||
init()
|
init()
|
||||||
if width > max_texture or height > max_texture:
|
if width > max_texture or height > max_texture:
|
||||||
print 'too large'
|
print('too large')
|
||||||
raise ValueError('Texture too large')
|
raise ValueError('Texture too large')
|
||||||
elif not power_of_two:
|
elif not power_of_two:
|
||||||
if not is_power2(width) or not is_power2(height):
|
if not is_power2(width) or not is_power2(height):
|
||||||
print 'not power of two'
|
print('not power of two')
|
||||||
raise ValueError('Texture not power of two')
|
raise ValueError('Texture not power of two')
|
||||||
|
|
||||||
|
|
||||||
def load_image(file, path):
|
def load_image(file, path):
|
||||||
print "Loading image %s..." % file,
|
print('Loading image %s...' % file, end=' ')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
file = open(path, 'rb')
|
file = open(path, 'rb')
|
||||||
except IOError:
|
except IOError:
|
||||||
print 'exists not'
|
print('exists not')
|
||||||
raise ValueError('Texture exists not')
|
raise ValueError('Texture exists not')
|
||||||
type, width, height = image_info(file.read(65536))
|
type, width, height = image_info(file.read(65536))
|
||||||
file.seek(0, 0)
|
file.seek(0, 0)
|
||||||
|
@ -166,7 +167,7 @@ def load_image(file, path):
|
||||||
file = Image(path.encode('mbcs' if os.name == 'nt' else 'utf8'))
|
file = Image(path.encode('mbcs' if os.name == 'nt' else 'utf8'))
|
||||||
geo = file.size()
|
geo = file.size()
|
||||||
check_size(geo.width(), geo.height())
|
check_size(geo.width(), geo.height())
|
||||||
print
|
print()
|
||||||
blob = Blob()
|
blob = Blob()
|
||||||
file.flip()
|
file.flip()
|
||||||
file.write(blob, 'RGBA')
|
file.write(blob, 'RGBA')
|
||||||
|
@ -176,12 +177,12 @@ def load_image(file, path):
|
||||||
try:
|
try:
|
||||||
raw = image.load(path, file=file)
|
raw = image.load(path, file=file)
|
||||||
except IOError:
|
except IOError:
|
||||||
print 'exists not'
|
print('exists not')
|
||||||
raise ValueError('Texture exists not')
|
raise ValueError('Texture exists not')
|
||||||
|
|
||||||
width, height = raw.width, raw.height
|
width, height = raw.width, raw.height
|
||||||
check_size(width, height)
|
check_size(width, height)
|
||||||
print
|
print()
|
||||||
|
|
||||||
mode = GL_RGBA if 'A' in raw.format else GL_RGB
|
mode = GL_RGBA if 'A' in raw.format else GL_RGB
|
||||||
# Flip from BGR to RGB
|
# Flip from BGR to RGB
|
||||||
|
@ -252,17 +253,16 @@ def load_clouds(file):
|
||||||
id = buffer.value
|
id = buffer.value
|
||||||
|
|
||||||
pixels = bytearray(len(texture) * 4)
|
pixels = bytearray(len(texture) * 4)
|
||||||
white = chr(255)
|
white = b'\xff'[0]
|
||||||
pixels[:] = itertools.chain.from_iterable(itertools.izip(itertools.repeat(white), itertools.repeat(white),
|
pixels[:] = itertools.chain.from_iterable(zip(itertools.repeat(white), itertools.repeat(white),
|
||||||
itertools.repeat(white),
|
itertools.repeat(white),
|
||||||
itertools.islice(texture, 0, None, depth)))
|
itertools.islice(texture, 0, None, depth)))
|
||||||
|
|
||||||
glBindTexture(GL_TEXTURE_2D, id)
|
glBindTexture(GL_TEXTURE_2D, id)
|
||||||
|
|
||||||
filter = GL_LINEAR
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, filter)
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, filter)
|
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, six.binary_type(pixels))
|
||||||
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, str(pixels))
|
|
||||||
|
|
||||||
cache[path] = id
|
cache[path] = id
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
import os.path
|
import os
|
||||||
|
|
||||||
try:
|
try:
|
||||||
import json
|
import json
|
||||||
|
@ -9,6 +11,8 @@ except ImportError:
|
||||||
except ImportError:
|
except ImportError:
|
||||||
raise SystemExit('No JSON module found')
|
raise SystemExit('No JSON module found')
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from punyverse._model import model_list, load_model
|
from punyverse._model import model_list, load_model
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
@ -97,11 +101,11 @@ class World(object):
|
||||||
self._current_object = 0
|
self._current_object = 0
|
||||||
|
|
||||||
def count_objects(bodies):
|
def count_objects(bodies):
|
||||||
for body in bodies.itervalues():
|
for body in six.itervalues(bodies):
|
||||||
self._objects += 1
|
self._objects += 1
|
||||||
count_objects(body.get('satellites', {}))
|
count_objects(body.get('satellites', {}))
|
||||||
count_objects(root['bodies'])
|
count_objects(root['bodies'])
|
||||||
print self._objects, 'objects to be loaded...'
|
print(self._objects, 'objects to be loaded...')
|
||||||
|
|
||||||
if 'start' in root:
|
if 'start' in root:
|
||||||
info = root['start']
|
info = root['start']
|
||||||
|
@ -114,9 +118,9 @@ class World(object):
|
||||||
self.start = (x, y, z)
|
self.start = (x, y, z)
|
||||||
self.direction = (pitch, yaw, roll)
|
self.direction = (pitch, yaw, roll)
|
||||||
|
|
||||||
for planet, info in root['bodies'].iteritems():
|
for planet, info in six.iteritems(root['bodies']):
|
||||||
message = 'Loading %s.' % planet
|
message = 'Loading %s.' % planet
|
||||||
print message
|
print(message)
|
||||||
self.callback('Loading objects (%d of %d)...' % (self._current_object, self._objects),
|
self.callback('Loading objects (%d of %d)...' % (self._current_object, self._objects),
|
||||||
message, float(self._current_object) / self._objects)
|
message, float(self._current_object) / self._objects)
|
||||||
self._body(planet, info)
|
self._body(planet, info)
|
||||||
|
@ -125,9 +129,9 @@ class World(object):
|
||||||
if 'belts' in root:
|
if 'belts' in root:
|
||||||
self._phase = 'Loading belts...'
|
self._phase = 'Loading belts...'
|
||||||
self._current_object = 0
|
self._current_object = 0
|
||||||
for name, info in root['belts'].iteritems():
|
for name, info in six.iteritems(root['belts']):
|
||||||
message = 'Loading %s.' % name
|
message = 'Loading %s.' % name
|
||||||
print message
|
print(message)
|
||||||
self.callback(self._phase, message, float(self._current_object) / len(root['belts']))
|
self.callback(self._phase, message, float(self._current_object) / len(root['belts']))
|
||||||
self._belt(name, info)
|
self._belt(name, info)
|
||||||
|
|
||||||
|
@ -189,7 +193,7 @@ class World(object):
|
||||||
object_id = model_list(load_model(info['model']), info.get('sx', scale), info.get('sy', scale),
|
object_id = model_list(load_model(info['model']), info.get('sx', scale), info.get('sy', scale),
|
||||||
info.get('sz', scale), (0, 0, 0))
|
info.get('sz', scale), (0, 0, 0))
|
||||||
else:
|
else:
|
||||||
print 'Nothing to load for %s.' % name
|
print('Nothing to load for %s.' % name)
|
||||||
return
|
return
|
||||||
|
|
||||||
params = {'world': self, 'orbit_distance': orbit_distance, 'radius': None if background else radius}
|
params = {'world': self, 'orbit_distance': orbit_distance, 'radius': None if background else radius}
|
||||||
|
@ -243,7 +247,7 @@ class World(object):
|
||||||
if not cheap:
|
if not cheap:
|
||||||
atmosphere_id = compile(disk, radius, radius + atm_size, 30, atm_texture)
|
atmosphere_id = compile(disk, radius, radius + atm_size, 30, atm_texture)
|
||||||
|
|
||||||
theta = 360 / (rotation + .0) if rotation else 0
|
theta = 360.0 / rotation if rotation else 0
|
||||||
object = type(object_id, (x, y, z), (pitch, yaw, roll), rotation_angle=theta,
|
object = type(object_id, (x, y, z), (pitch, yaw, roll), rotation_angle=theta,
|
||||||
atmosphere=atmosphere_id, cloudmap=cloudmap_id, background=background,
|
atmosphere=atmosphere_id, cloudmap=cloudmap_id, background=background,
|
||||||
corona=corona_id, **params)
|
corona=corona_id, **params)
|
||||||
|
@ -264,9 +268,9 @@ class World(object):
|
||||||
type(compile(disk, distance, distance + size, 30, texture), (x, y, z),
|
type(compile(disk, distance, distance + size, 30, texture), (x, y, z),
|
||||||
(pitch, yaw, roll), **params))
|
(pitch, yaw, roll), **params))
|
||||||
|
|
||||||
for satellite, info in info.get('satellites', {}).iteritems():
|
for satellite, info in six.iteritems(info.get('satellites', {})):
|
||||||
message = 'Loading %s, satellite of %s.' % (satellite, name)
|
message = 'Loading %s, satellite of %s.' % (satellite, name)
|
||||||
print message
|
print(message)
|
||||||
self.callback('Loading objects (%d of %d)...' % (self._current_object, self._objects),
|
self.callback('Loading objects (%d of %d)...' % (self._current_object, self._objects),
|
||||||
message, float(self._current_object) / self._objects)
|
message, float(self._current_object) / self._objects)
|
||||||
self._body(satellite, info, object)
|
self._body(satellite, info, object)
|
||||||
|
|
4
setup.py
4
setup.py
|
@ -28,7 +28,7 @@ with open(os.path.join(os.path.dirname(__file__), 'README.md')) as f:
|
||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='punyverse',
|
name='punyverse',
|
||||||
version='0.2',
|
version='0.3',
|
||||||
packages=['punyverse'],
|
packages=['punyverse'],
|
||||||
package_data={
|
package_data={
|
||||||
'punyverse': [
|
'punyverse': [
|
||||||
|
@ -60,7 +60,7 @@ setup(
|
||||||
]
|
]
|
||||||
|
|
||||||
},
|
},
|
||||||
install_requires=['pyglet', 'Pillow'],
|
install_requires=['pyglet', 'Pillow', 'six'],
|
||||||
|
|
||||||
author='quantum',
|
author='quantum',
|
||||||
author_email='quantum2048@gmail.com',
|
author_email='quantum2048@gmail.com',
|
||||||
|
|
Loading…
Reference in a new issue