Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
paddywwoof committed Apr 20, 2017
2 parents 2c898d1 + 67738fc commit 9c01c15
Show file tree
Hide file tree
Showing 10 changed files with 145 additions and 51 deletions.
26 changes: 16 additions & 10 deletions ReadMe.rst
Original file line number Diff line number Diff line change
Expand Up @@ -132,15 +132,16 @@ pi3d with different levels of complexity.
Files and folders in this repository
====================================

Total zipped download from github c. 574 kB extracts to 1.2 MB
Installation tar.gz on python.pypi.org is c.190kB extracts to 770kB. Total
zipped download from github is c.600 kB extracts to c.1100kB

#. **pi3d** The main pi3d module files 446 kB
#. **pyxlib** Library to enable use on general linux machines 209 kB
#. **images** To show in ReadMe on github 325 kB
#. **ReadMe** This file in markup and plain text 31 kB
#. **ChangeLog.txt** Latest changes of pi3d 19 kB
#. **six_mod.py** utilities to help run under python2 and python3 13 kB
#. **misc. others** 10 kB
#. **pi3d** The main pi3d module files 517kB
#. **pyxlib** Library to enable use on general linux machines 209kB
#. **images** To show in ReadMe on github 325kB
#. **ReadMe** This file in markup and plain text 27kB
#. **ChangeLog.txt** Latest changes of pi3d 16kB
#. **six_mod.py** utilities to help run under python2 and python3 13kB
#. **misc. others** 10kB

Setup on the Raspberry Pi
=========================
Expand Down Expand Up @@ -293,11 +294,16 @@ Setup on desktop and laptop machines

The machine will need to have a gpu that runs OpenGL2+ and obviously
it will need to have python installed. Setting up in a Linux environment
is most similar to the procedure for the Raspberry Pi. Linux can be set
is most similar to the procedure for the Raspberry Pi. In fact by far the
most staightforward route is to make a Raspbian Pixel USB stick following
the instructions here https://www.raspberrypi.org/blog/pixel-pc-mac/
After that your PC will behave pretty much like the Raspberry Pi and pi3d
will work after a simple ``sudo pip3 install pi3d`` The USB isn't as fast
as a hard drive but everything else will run at PC speed. Linux can be set
up in its own boot partition or in vmware (eg Player which is free, you
will also need to ``enable 3d acceleration``.)

You need to install libraries
For non Pixel linux you will need to install libraries
that emulate OpenGLES behaviour for the gpu::

$ sudo apt-get install mesa-utils-extra
Expand Down
2 changes: 1 addition & 1 deletion pi3d/Display.py
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ def __init__(self, tkwin=None, use_pygame=False):
self.vbufs_dict = {}
self.ebufs_dict = {}
self.last_shader = None
self.last_textures = [None, None, None] # if more than 3 used this will break in Buffer.draw()
self.last_textures = [None for i in range(8)] # 8 is max no. texture2D on broadcom GPU
self.external_mouse = None
self.offscreen_tex = False # used in Buffer.draw() to force reload of textures

Expand Down
3 changes: 2 additions & 1 deletion pi3d/Shader.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,8 @@ def make_shader(src, suffix, shader_type):
opengles.glEnableVertexAttribArray(self.attr_texcoord)
self.unif_tex = []
self.textures = []
for s in [b'tex0', b'tex1', b'tex2']:
for i in range(8):
s = 'tex{}'.format(i).encode()
self.unif_tex.append(opengles.glGetUniformLocation(self.program, s))
self.textures.append(None)
"""
Expand Down
16 changes: 13 additions & 3 deletions pi3d/Texture.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,10 @@ def __init__(self, file_string, blend=False, flip=False, size=0,
by the shader. If set to true then this texture needs to be
drawn AFTER other objects that are FURTHER AWAY
*flip*
flips the image [not used for numpy arrays]
flips the image [not used for numpy arrays]. Now this parameter could
be an integer value. If bit #0 is 1, a up-down flip is perfomed,
also if bit #1 is set, a left-right flip occurs
*size*
to resize image to [not used for numpy arrays]
*defer*
Expand Down Expand Up @@ -240,8 +243,15 @@ def _load_disk(self):

LOGGER.debug('Loading ...%s', s)

if self.flip:
im = im.transpose(Image.FLIP_TOP_BOTTOM)
if isinstance(self.flip, bool):
# Old behaviour
if self.flip:
im = im.transpose(Image.FLIP_TOP_BOTTOM)
else:
if self.flip & 1:
im = im.transpose(Image.FLIP_TOP_BOTTOM)
if self.flip & 2:
im = im.transpose(Image.FLIP_LEFT_RIGHT)

#self.image = im.tostring('raw', RGBs) # TODO change to tobytes WHEN Pillow is default PIL in debian (jessie becomes current)
self.image = self._img_to_array(im)
Expand Down
2 changes: 1 addition & 1 deletion pi3d/constants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"""
import time

__version__ = '2.18'
__version__ = '2.19'
year = time.localtime().tm_year

STARTUP_MESSAGE = """
Expand Down
28 changes: 14 additions & 14 deletions pi3d/event/EventHandler.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,20 +20,20 @@ def __init__(self, keyHandler=None, relHandler=None, absHandler=None, synHandler

self.mutex = threading.Lock()

self.absx = [0.0]*4
self.absy = [0.0]*4
self.absz = [0.0]*4
self.absx2 = [0.0]*4
self.absy2 = [0.0]*4
self.absz2 = [0.0]*4
self.abshatx = [0.0]*4
self.abshaty = [0.0]*4

self.relx = [0]*4
self.rely = [0]*4
self.relv = [0]*4
self.relh = [0]*4
self.reld = [0]*4
self.absx = [0.0]*16
self.absy = [0.0]*16
self.absz = [0.0]*16
self.absx2 = [0.0]*16
self.absy2 = [0.0]*16
self.absz2 = [0.0]*16
self.abshatx = [0.0]*16
self.abshaty = [0.0]*16

self.relx = [0]*16
self.rely = [0]*16
self.relv = [0]*16
self.relh = [0]*16
self.reld = [0]*16

def event(self, event):
"""
Expand Down
2 changes: 1 addition & 1 deletion pi3d/event/FindDevices.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ def find_devices(identifier, butNot= [ ]):
else:
pass
# print "No need to remove", old[1]
else:
else: # i.e. there was no break from above for loop (horrible for-else syntax!)
ret.append((index, int(eventindex)))
index += 1

Expand Down
33 changes: 33 additions & 0 deletions pi3d/shaders/uv_elev_map.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#include std_head_fs.inc

uniform sampler2D tex3;
uniform sampler2D tex4;
uniform sampler2D tex5;
uniform sampler2D tex6;
uniform sampler2D tex7;

varying vec2 texcoordout;
varying vec2 bumpcoordout;
varying vec3 lightVector;
varying float dist;
varying float lightFactor;
varying float texFactor;

void main(void) {
vec4 texc = mix(
mix(texture2D(tex0, texcoordout), texture2D(tex2, texcoordout), clamp(texFactor, 0.0, 1.0)),
mix(texture2D(tex4, texcoordout), texture2D(tex6, texcoordout), clamp((texFactor - 2.0), 0.0, 1.0)),
clamp((texFactor - 1.0), 0.0, 1.0));
texc.rgb += unib[1] - vec3(0.5);
float ffact = smoothstep(unif[5][0]/3.0, unif[5][0], dist); // ------ smoothly increase fog between 1/3 and full fogdist
vec3 bump = normalize(mix(
mix(texture2D(tex1, bumpcoordout), texture2D(tex3, bumpcoordout), clamp(texFactor, 0.0, 1.0)),
mix(texture2D(tex5, bumpcoordout), texture2D(tex7, bumpcoordout), clamp((texFactor - 2.0), 0.0, 1.0)),
clamp((texFactor - 1.0), 0.0, 1.0)).rgb * 2.0 - 1.0);
#include std_bump.inc

gl_FragColor = (1.0 - ffact) * texc + ffact * vec4(unif[4], unif[5][1]); // ------ combine using factors
gl_FragColor.a *= unif[5][2];
}


22 changes: 22 additions & 0 deletions pi3d/shaders/uv_elev_map.vs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#include std_head_vs.inc

varying vec2 texcoordout;
varying vec2 bumpcoordout;
varying float dist;
varying vec3 lightVector;
varying float lightFactor;
varying float texFactor;

void main(void) {
vec3 normout;
#include std_main_vs.inc
texcoordout = fract(texcoord * unib[2].xy + unib[3].xy);
bumpcoordout = texcoordout * vec2(1.0, 1.0) * unib[0][0];
texFactor = floor(texcoord[0]); // ----- u and v expected to go up together!

vec3 inray = vec3(relPosn - vec4(unif[6], 0.0)); // ----- vector from the camera to this vertex
dist = length(inray);

gl_Position = modelviewmatrix[1] * vec4(vertex,1.0);
gl_PointSize = unib[2][2] / dist;
}
62 changes: 42 additions & 20 deletions pi3d/shape/ElevationMap.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@
if PIL_OK:
from PIL import Image

def file_pathify(file_path):
if file_path[0] != '/':
for p in sys.path:
if os.path.isfile(p + '/' + file_path): # this could theoretically get different files with same name
file_path = p + '/' + file_path
break
return file_path

# a rectangular surface where elevation is defined by a greyscal image
class ElevationMap(Shape):
""" 3d model inherits from Shape
Expand All @@ -26,7 +34,8 @@ def __init__(self, mapfile, camera=None, light=None,
width=100.0, depth=100.0, height=10.0,
divx=0, divy=0, ntiles=1.0, name="",
x=0.0, y=0.0, z=0.0, rx=0.0, ry=0.0, rz=0.0,
sx=1.0, sy=1.0, sz=1.0, cx=0.0, cy=0.0, cz=0.0, smooth=True, cubic=False):
sx=1.0, sy=1.0, sz=1.0, cx=0.0, cy=0.0, cz=0.0, smooth=True,
cubic=False, texmap=None):
"""uses standard constructor for Shape
Arguments:
Expand All @@ -51,6 +60,13 @@ def __init__(self, mapfile, camera=None, light=None,
*smooth*
Calculate normals with averaging rather than pointing
straight up, slightly faster if false.
*texmap*
Image file path or PIL.Image to be used to represent each of four
textures and normals using the uv_elev_map shader. The image is
converted to greyscale and apportioned between darkest (first and
second entries in Buffer.textures list) and lightest (seventh and
eighth entries). The resulting 0.0, 1.0, 2.0 or 3.0 is added to the
uv texture coordinate i.e. Buffer.array_buffer[:,6:8]
"""
super(ElevationMap, self).__init__(camera, light, name, x, y, z, rx, ry, rz,
sx, sy, sz, cx, cy, cz)
Expand All @@ -65,11 +81,7 @@ def __init__(self, mapfile, camera=None, light=None,
if PIL_OK:
try:
if '' + mapfile == mapfile: #HORRIBLE. Only way to cope with python2v3
if mapfile[0] != '/':
for p in sys.path:
if os.path.isfile(p + '/' + mapfile): # this could theoretically get different files with same name
mapfile = p + '/' + mapfile
break
mapfile = file_pathify(mapfile)
LOGGER.info("Loading height map ...%s", mapfile)

im = Image.open(mapfile)
Expand All @@ -84,20 +96,28 @@ def __init__(self, mapfile, camera=None, light=None,
divy = 200
im = im.resize((divx, divy), Image.ANTIALIAS)
ix, iy = im.size

im = im.convert('L')
im = im.transpose(Image.FLIP_TOP_BOTTOM)
im = im.transpose(Image.FLIP_LEFT_RIGHT)
self.pixels = im.load()
if texmap is not None:
try:
texmap = file_pathify(texmap)
tm = Image.open(texmap)
except:
tm = texmap
tm = tm.convert('L')
tm = tm.resize((ix, iy))
tm = np.array(tm)
tm = np.floor(tm * 3.99 / (tm.max() - tm.min()))

else:
''' images saved as compressed numpy npz file. No resizing so needs
to be right size. TODO make this repeated code less WET'''
if mapfile[0] != '/':
for p in sys.path:
if os.path.isfile(p + '/' + mapfile): # this could theoretically get different files with same name
mapfile = p + '/' + mapfile
break
to be right size.'''
mapfile = file_pathify(mapfile)
self.pixels = np.load(mapfile)['arr_0'][::-1,::-1] # has to be saved with default key
ix, iy = self.pixels.shape[:2]

self.width = width
self.depth = depth
self.height = height
Expand All @@ -124,13 +144,15 @@ def __init__(self, mapfile, camera=None, light=None,

for y in xrange(0, iy):
for x in xrange(0, ix):
pxl = self.pixels[x, y]
hgt = pxl[0] if hasattr(pxl, '__iter__') else pxl
hgt *= self.ht
this_x = -self.wh + x * self.ws
this_z = -self.hh + y * self.hs
verts.append((this_x, hgt, this_z))
tex_coords.append(((ix - x) * tx, (iy - y) * ty))
hgt = self.pixels[x, y] * self.ht
verts.append((-self.wh + x * self.ws,
hgt,
-self.hh + y * self.hs))
if texmap is not None:
tex_n = tm[x, y]
else:
tex_n = 0.0
tex_coords.append((tex_n + (ix - x) * tx, (iy - y) * ty))

s = 0
#create one long triangle_strip by alternating X directions
Expand Down

0 comments on commit 9c01c15

Please sign in to comment.