<s> from __future__ import absolute_import , division , print_function , unicode_literals <EOL> import math <EOL> import sys , os <EOL> from six . moves import xrange <EOL> from PIL import Image , ImageOps <EOL> from numpy import cross , dot , array , sum <EOL> from math import atan2 , asin , degrees , sqrt <EOL> from pi3d import * <EOL> from pi3d . Buffer import Buffer <EOL> from pi3d . Shape import Shape <EOL> from pi3d . util import Utility <EOL> class ElevationMap ( Shape ) : <EOL> """<STR_LIT>""" <EOL> def __init__ ( self , mapfile , camera = None , light = None , <EOL> width = <NUM_LIT> , depth = <NUM_LIT> , height = <NUM_LIT> , <EOL> divx = <NUM_LIT:0> , divy = <NUM_LIT:0> , ntiles = <NUM_LIT:1.0> , name = "<STR_LIT>" , <EOL> x = <NUM_LIT:0.0> , y = <NUM_LIT:0.0> , z = <NUM_LIT:0.0> , rx = <NUM_LIT:0.0> , ry = <NUM_LIT:0.0> , rz = <NUM_LIT:0.0> , <EOL> sx = <NUM_LIT:1.0> , sy = <NUM_LIT:1.0> , sz = <NUM_LIT:1.0> , cx = <NUM_LIT:0.0> , cy = <NUM_LIT:0.0> , cz = <NUM_LIT:0.0> , smooth = True , cubic = False ) : <EOL> """<STR_LIT>""" <EOL> super ( ElevationMap , self ) . __init__ ( camera , light , name , x , y , z , rx , ry , rz , <EOL> sx , sy , sz , cx , cy , cz ) <EOL> divx += <NUM_LIT:1> <EOL> divy += <NUM_LIT:1> <EOL> if divx > <NUM_LIT:200> or divy > <NUM_LIT:200> : <EOL> print ( "<STR_LIT>" ) <EOL> divx = <NUM_LIT:200> <EOL> divy = <NUM_LIT:200> <EOL> try : <EOL> if '<STR_LIT>' + mapfile == mapfile : <EOL> if mapfile [ <NUM_LIT:0> ] != '<STR_LIT:/>' : <EOL> for p in sys . path : <EOL> if os . path . isfile ( p + '<STR_LIT:/>' + mapfile ) : <EOL> mapfile = p + '<STR_LIT:/>' + mapfile <EOL> break <EOL> if VERBOSE : <EOL> print ( "<STR_LIT>" , mapfile ) <EOL> im = Image . open ( mapfile ) <EOL> else : <EOL> im = mapfile <EOL> except : <EOL> im = mapfile <EOL> ix , iy = im . size <EOL> if ( ix > <NUM_LIT:200> and divx == <NUM_LIT:0> ) or ( ix != divx and iy != divy ) : <EOL> if divx == <NUM_LIT:0> : <EOL> divx = <NUM_LIT:200> <EOL> divy = <NUM_LIT:200> <EOL> im = im . resize ( ( divx , divy ) , Image . ANTIALIAS ) <EOL> ix , iy = im . size <EOL> im = im . transpose ( Image . FLIP_TOP_BOTTOM ) <EOL> im = im . transpose ( Image . FLIP_LEFT_RIGHT ) <EOL> self . pixels = im . load ( ) <EOL> self . width = width <EOL> self . depth = depth <EOL> self . height = height <EOL> self . ix = ix <EOL> self . iy = iy <EOL> self . ttype = GL_TRIANGLE_STRIP <EOL> if VERBOSE : <EOL> print ( "<STR_LIT>" , ix , iy ) <EOL> wh = width * <NUM_LIT:0.5> <EOL> hh = depth * <NUM_LIT:0.5> <EOL> ws = width / ( ix - <NUM_LIT:1.0> ) <EOL> hs = depth / ( iy - <NUM_LIT:1.0> ) <EOL> ht = height / <NUM_LIT> <EOL> tx = <NUM_LIT:1.0> * ntiles / ix <EOL> ty = <NUM_LIT:1.0> * ntiles / iy <EOL> verts = [ ] <EOL> norms = [ ] <EOL> tex_coords = [ ] <EOL> idx = [ ] <EOL> for y in xrange ( <NUM_LIT:0> , iy ) : <EOL> for x in xrange ( <NUM_LIT:0> , ix ) : <EOL> pxl = self . pixels [ x , y ] <EOL> hgt = pxl [ <NUM_LIT:0> ] if type ( pxl ) is tuple else pxl <EOL> hgt *= ht <EOL> this_x = - wh + x * ws <EOL> this_z = - hh + y * hs <EOL> if cubic : <EOL> """<STR_LIT>""" <EOL> if hgt > height / <NUM_LIT:2> : <EOL> hgt = height <EOL> else : <EOL> hgt = <NUM_LIT:0.0> <EOL> if hgt == <NUM_LIT:0> and y > <NUM_LIT:0> and y < iy - <NUM_LIT:1> and x > <NUM_LIT:0> and x < ix - <NUM_LIT:1> : <EOL> if self . pixels [ x - <NUM_LIT:1> , y ] > <NUM_LIT> : <EOL> this_x = - wh + ( x - <NUM_LIT:1> ) * ws <EOL> elif self . pixels [ x + <NUM_LIT:1> , y ] > <NUM_LIT> : <EOL> this_x = - wh + ( x + <NUM_LIT:1> ) * ws <EOL> elif self . pixels [ x , y - <NUM_LIT:1> ] > <NUM_LIT> : <EOL> this_z = - hh + ( y - <NUM_LIT:1> ) * hs <EOL> elif self . pixels [ x , y + <NUM_LIT:1> ] > <NUM_LIT> : <EOL> this_z = - hh + ( y + <NUM_LIT:1> ) * hs <EOL> elif self . pixels [ x - <NUM_LIT:1> , y - <NUM_LIT:1> ] > <NUM_LIT> : <EOL> this_x = - wh + ( x - <NUM_LIT:1> ) * ws <EOL> this_z = - hh + ( y - <NUM_LIT:1> ) * hs <EOL> elif self . pixels [ x - <NUM_LIT:1> , y + <NUM_LIT:1> ] > <NUM_LIT> : <EOL> this_x = - wh + ( x - <NUM_LIT:1> ) * ws <EOL> this_z = - hh + ( y + <NUM_LIT:1> ) * hs <EOL> elif self . pixels [ x + <NUM_LIT:1> , y - <NUM_LIT:1> ] > <NUM_LIT> : <EOL> this_x = - wh + ( x + <NUM_LIT:1> ) * ws <EOL> this_z = - hh + ( y - <NUM_LIT:1> ) * hs <EOL> elif self . pixels [ x + <NUM_LIT:1> , y + <NUM_LIT:1> ] > <NUM_LIT> : <EOL> this_x = - wh + ( x + <NUM_LIT:1> ) * ws <EOL> this_z = - hh + ( y + <NUM_LIT:1> ) * hs <EOL> verts . append ( ( this_x , hgt , this_z ) ) <EOL> tex_coords . append ( ( ( ix - x ) * tx , ( iy - y ) * ty ) ) <EOL> s = <NUM_LIT:0> <EOL> for y in range ( <NUM_LIT:0> , iy - <NUM_LIT:1> ) : <EOL> for x in range ( <NUM_LIT:0> , ix - <NUM_LIT:1> ) : <EOL> i = ( y * ix ) + x <EOL> idx . append ( ( i , i + ix , i + ix + <NUM_LIT:1> ) ) <EOL> idx . append ( ( i + ix + <NUM_LIT:1> , i + <NUM_LIT:1> , i ) ) <EOL> s += <NUM_LIT:2> <EOL> self . buf = [ ] <EOL> self . buf . append ( Buffer ( self , verts , tex_coords , idx , None , smooth ) ) <EOL> def dropOn ( self , px , pz ) : <EOL> """<STR_LIT>""" <EOL> px -= self . unif [ <NUM_LIT:0> ] <EOL> pz -= self . unif [ <NUM_LIT:2> ] <EOL> wh = self . width * <NUM_LIT:0.5> <EOL> hh = self . depth * <NUM_LIT:0.5> <EOL> ws = self . width / ( self . ix - <NUM_LIT:1.0> ) <EOL> hs = self . depth / ( self . iy - <NUM_LIT:1.0> ) <EOL> ht = self . height / <NUM_LIT> <EOL> if px > - wh and px < wh and pz > - hh and pz < hh : <EOL> pixht = self . pixels [ ( wh + px ) / ws , ( hh + pz ) / hs ] * ht <EOL> return pixht + self . unif [ <NUM_LIT:1> ] <EOL> def calcHeight ( self , px , pz , inc_normal = False ) : <EOL> """<STR_LIT>""" <EOL> px -= self . unif [ <NUM_LIT:0> ] <EOL> pz -= self . unif [ <NUM_LIT:2> ] <EOL> wh = self . width * <NUM_LIT:0.5> <EOL> hh = self . depth * <NUM_LIT:0.5> <EOL> ws = self . width / ( self . ix - <NUM_LIT:1.0> ) <EOL> hs = self . depth / ( self . iy - <NUM_LIT:1.0> ) <EOL> ht = self . height / <NUM_LIT> <EOL> x = math . floor ( ( wh + px ) / ws ) <EOL> z = math . floor ( ( hh + pz ) / hs ) <EOL> if x < <NUM_LIT:0> : <EOL> x = <NUM_LIT:0> <EOL> if x > ( self . ix - <NUM_LIT:2> ) : <EOL> x = self . ix - <NUM_LIT:2> <EOL> if z < <NUM_LIT:0> : <EOL> z = <NUM_LIT:0> <EOL> if z > ( self . iy - <NUM_LIT:2> ) : <EOL> z = self . iy - <NUM_LIT:2> <EOL> p0 = int ( z * self . ix + x ) <EOL> p1 = p0 + <NUM_LIT:1> <EOL> p2 = p0 + self . ix <EOL> p3 = p0 + self . ix + <NUM_LIT:1> <EOL> v0 = self . buf [ <NUM_LIT:0> ] . array_buffer [ p0 , <NUM_LIT:0> : <NUM_LIT:3> ] <EOL> v1 = self . buf [ <NUM_LIT:0> ] . array_buffer [ p1 , <NUM_LIT:0> : <NUM_LIT:3> ] <EOL> v2 = self . buf [ <NUM_LIT:0> ] . array_buffer [ p2 , <NUM_LIT:0> : <NUM_LIT:3> ] <EOL> v3 = self . buf [ <NUM_LIT:0> ] . array_buffer [ p3 , <NUM_LIT:0> : <NUM_LIT:3> ] <EOL> if pz > ( v0 [ <NUM_LIT:2> ] + hs / ws * ( px - v0 [ <NUM_LIT:0> ] ) ) : <EOL> y , n = _intersect_triangle ( v2 , v3 , v0 , ( px , <NUM_LIT:0> , pz ) ) <EOL> else : <EOL> y , n = _intersect_triangle ( v1 , v0 , v3 , ( px , <NUM_LIT:0> , pz ) ) <EOL> if inc_normal : <EOL> n /= ( ( n * n ) . sum ( ) ) ** <NUM_LIT:0.5> <EOL> return ( self . unif [ <NUM_LIT:1> ] + y , n ) <EOL> return self . unif [ <NUM_LIT:1> ] + y <EOL> def clashTest ( self , px , py , pz , rad ) : <EOL> """<STR_LIT>""" <EOL> radSq = rad ** <NUM_LIT:2> <EOL> px -= self . unif [ <NUM_LIT:0> ] <EOL> py -= self . unif [ <NUM_LIT:1> ] <EOL> pz -= self . unif [ <NUM_LIT:2> ] <EOL> ht = self . height / <NUM_LIT:255> <EOL> halfw = self . width / <NUM_LIT> <EOL> halfd = self . depth / <NUM_LIT> <EOL> dx = self . width / self . ix <EOL> dz = self . depth / self . iy <EOL> x0 = int ( math . floor ( ( halfw + px - rad ) / dx + <NUM_LIT:0.5> ) ) - <NUM_LIT:1> <EOL> if x0 < <NUM_LIT:0> : x0 = <NUM_LIT:0> <EOL> x1 = int ( math . floor ( ( halfw + px + rad ) / dx + <NUM_LIT:0.5> ) ) + <NUM_LIT:1> <EOL> if x1 > self . ix - <NUM_LIT:1> : x1 = self . ix - <NUM_LIT:1> <EOL> z0 = int ( math . floor ( ( halfd + pz - rad ) / dz + <NUM_LIT:0.5> ) ) - <NUM_LIT:1> <EOL> if z0 < <NUM_LIT:0> : z0 = <NUM_LIT:0> <EOL> z1 = int ( math . floor ( ( halfd + pz + rad ) / dz + <NUM_LIT:0.5> ) ) + <NUM_LIT:1> <EOL> if z1 > self . iy - <NUM_LIT:1> : z1 = self . iy - <NUM_LIT:1> <EOL> minDist , minLoc = <NUM_LIT> , ( <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> for i in range ( x0 + <NUM_LIT:1> , x1 ) : <EOL> for j in range ( z0 + <NUM_LIT:1> , z1 ) : <EOL> p = j * self . ix + i <EOL> p1 = j * self . ix + i - <NUM_LIT:1> <EOL> p2 = ( j - <NUM_LIT:1> ) * self . ix + i <EOL> vertp = self . buf [ <NUM_LIT:0> ] . array_buffer [ p , <NUM_LIT:0> : <NUM_LIT:3> ] <EOL> normp = self . buf [ <NUM_LIT:0> ] . array_buffer [ p , <NUM_LIT:3> : <NUM_LIT:6> ] <EOL> distSq = ( px - vertp [ <NUM_LIT:0> ] ) ** <NUM_LIT:2> + ( py - vertp [ <NUM_LIT:1> ] ) ** <NUM_LIT:2> + ( pz - vertp [ <NUM_LIT:2> ] ) ** <NUM_LIT:2> <EOL> if distSq < minDist : <EOL> minDist = distSq <EOL> minLoc = ( i , j ) <EOL> pDist = dot ( [ px - vertp [ <NUM_LIT:0> ] , py - vertp [ <NUM_LIT:1> ] , pz - vertp [ <NUM_LIT:2> ] ] , <EOL> [ - normp [ <NUM_LIT:0> ] , - normp [ <NUM_LIT:1> ] , - normp [ <NUM_LIT:2> ] ] ) <EOL> xIsect = px - normp [ <NUM_LIT:0> ] * pDist <EOL> zIsect = pz - normp [ <NUM_LIT:2> ] * pDist <EOL> if xIsect > self . buf [ <NUM_LIT:0> ] . array_buffer [ p1 , <NUM_LIT:0> ] and xIsect < self . buf [ <NUM_LIT:0> ] . array_buffer [ p , <NUM_LIT:0> ] and zIsect > self . buf [ <NUM_LIT:0> ] . array_buffer [ p2 , <NUM_LIT:2> ] and zIsect < self . buf [ <NUM_LIT:0> ] . array_buffer [ p , <NUM_LIT:2> ] : <EOL> pDistSq = pDist ** <NUM_LIT:2> <EOL> if pDistSq < minDist : <EOL> minDist = pDistSq <EOL> minLoc = ( i , j ) <EOL> gLevel = self . calcHeight ( px + self . unif [ <NUM_LIT:0> ] , pz + self . unif [ <NUM_LIT:1> ] ) <EOL> if gLevel > ( py - rad ) : <EOL> minDist = py - gLevel <EOL> minLoc = ( int ( ( x0 + x1 ) / <NUM_LIT:2> ) , int ( ( z0 + z1 ) / <NUM_LIT:2> ) ) <EOL> if minDist <= radSq : <EOL> p = minLoc [ <NUM_LIT:1> ] * self . ix + minLoc [ <NUM_LIT:0> ] <EOL> normp = self . buf [ <NUM_LIT:0> ] . array_buffer [ p , <NUM_LIT:3> : <NUM_LIT:6> ] <EOL> if minDist < <NUM_LIT:0> : <EOL> jump = rad - minDist <EOL> else : <EOL> jump = <NUM_LIT:0> <EOL> return ( True , normp [ <NUM_LIT:0> ] , normp [ <NUM_LIT:1> ] , normp [ <NUM_LIT:2> ] , jump ) <EOL> else : <EOL> return ( False , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> , <NUM_LIT:0> ) <EOL> def pitch_roll ( self , px , pz ) : <EOL> """<STR_LIT>""" <EOL> px -= self . unif [ <NUM_LIT:0> ] <EOL> pz -= self . unif [ <NUM_LIT:2> ] <EOL> halfw = self . width / <NUM_LIT> <EOL> halfd = self . depth / <NUM_LIT> <EOL> dx = self . width / self . ix <EOL> dz = self . depth / self . iy <EOL> x0 = int ( math . floor ( ( halfw + px ) / dx + <NUM_LIT:0.5> ) ) <EOL> if x0 < <NUM_LIT:0> : x0 = <NUM_LIT:0> <EOL> if x0 > self . ix - <NUM_LIT:1> : x0 = self . ix - <NUM_LIT:1> <EOL> z0 = int ( math . floor ( ( halfd + pz ) / dz + <NUM_LIT:0.5> ) ) <EOL> if z0 < <NUM_LIT:0> : z0 = <NUM_LIT:0> <EOL> if z0 > self . iy - <NUM_LIT:1> : z0 = self . iy - <NUM_LIT:1> <EOL> normp = array ( self . buf [ <NUM_LIT:0> ] . array_buffer [ z0 * self . ix + x0 , <NUM_LIT:3> : <NUM_LIT:6> ] ) <EOL> sidev = array ( [ normp [ <NUM_LIT:1> ] , - normp [ <NUM_LIT:0> ] , <NUM_LIT:0.0> ] ) <EOL> sidev = sidev / sqrt ( sidev . dot ( sidev ) ) <EOL> forwd = array ( [ - normp [ <NUM_LIT:2> ] * normp [ <NUM_LIT:0> ] , - normp [ <NUM_LIT:2> ] * normp [ <NUM_LIT:1> ] , <EOL> normp [ <NUM_LIT:0> ] * normp [ <NUM_LIT:0> ] + normp [ <NUM_LIT:1> ] * normp [ <NUM_LIT:1> ] ] ) <EOL> forwd = forwd / sqrt ( forwd . dot ( forwd ) ) <EOL> return ( degrees ( asin ( - forwd [ <NUM_LIT:1> ] ) ) , degrees ( atan2 ( sidev [ <NUM_LIT:1> ] , normp [ <NUM_LIT:1> ] ) ) ) <EOL> def __getstate__ ( self ) : <EOL> self . childModel = None <EOL> state = super ( ElevationMap , self ) . __getstate__ ( ) <EOL> state [ '<STR_LIT:width>' ] = self . width <EOL> state [ '<STR_LIT>' ] = self . height <EOL> state [ '<STR_LIT>' ] = self . depth <EOL> state [ '<STR_LIT>' ] = self . ix <EOL> state [ '<STR_LIT>' ] = self . iy <EOL> return state <EOL> def __setstate__ ( self , state ) : <EOL> super ( ElevationMap , self ) . __setstate__ ( state ) <EOL> self . width = state [ '<STR_LIT:width>' ] <EOL> self . height = state [ '<STR_LIT>' ] <EOL> self . depth = state [ '<STR_LIT>' ] <EOL> self . ix = state [ '<STR_LIT>' ] <EOL> self . iy = state [ '<STR_LIT>' ] <EOL> def _intersect_triangle ( v1 , v2 , v3 , pos ) : <EOL> """<STR_LIT>""" <EOL> nVec = cross ( ( v2 - v1 ) , ( v3 - v1 ) ) <EOL> kVal = dot ( nVec , v1 ) <EOL> return ( kVal - nVec [ <NUM_LIT:0> ] * pos [ <NUM_LIT:0> ] - nVec [ <NUM_LIT:2> ] * pos [ <NUM_LIT:2> ] ) / nVec [ <NUM_LIT:1> ] , nVec </s>
