#!/usr/bin/env python
##This is my testbed. Accordingly it imports everything but kitchensink.py. Method 'ouch'  
##works (sort of) : it gets an array of pixels from the center of the frame, either rgb values or a
##value from the depth buffer, so that they can be examined. (One depth value is enough). The 
##idea is that by examining this value, we can determine if something is "in the way", right in
##front of the camera. Then we can constrain the camera to not move forward if something is 
##in the way. I say "sort of" works because if the camera moves fast enough it will "tunnel"
##through an opaque object when there is no frame rendered right 'in front of' it. If you move  
##REALLY SLOWLY you can see the camera bounce off an opaque object instead of going 
##through it. Zmove and Xmove are redefined here to include this functionality. Note that 
##'ouch' just looks for a pixel at (200,125), so the results will be goofy if the window is resized. 
##Thanks go out to Mr. M. C., who first suggested this (essentially Gibsonian) notion. By the 
##way, the world is still waiting for more people to read  "The Ecological Approach to 
##Visual Perception."   
##Keyboard "1" is bound to method "ADD" -- for "attention deficit disorder" -- which
##randomly selects an object of attention from the list of first level objects (children of 'world',
##the zeroth-level object). "2" randomly switches attention to a child of the present object of
##attention, which only works on a heirarchical object like a tree. "c" is for "cut": it doesn't 
##really work because PyOpenGL doesn't implement glLoadMatrix yet. Just keep hitting "1"
##to look at different objects and use the mouse to move. The camera only moves along 
##axis-aligned straight lines. To improve the framerate, comment out most of the lines which 
##read "self.world.addchild(. . .)", leaving only those objects which want. For unrenderable 
##complexity, try a Tree(n,5,60), where n is larger than it should be. Thanks to the miracle of 
##recursion, it's easy to bite off more than you can render! All the objects are subclassed 
##from Att_Obj. 

import sys
from renderer import *
from whrandom import *
from Numeric import *
import RandomArray
import oglpm
import objex
import ogltex
import trees
import cursor
import room
from compass import *
from OpenGL.GL import * #mcfletch 2000/09/24 -- used to import openglutil, which is actually hidden in the shared/platform directory in the latest builds
	
class rx(Renderer):
    def start(self):
        self.r_back = self.g_back = self.b_back = 1.0
        self.r_back = .7
        self.fovy = 40
        n = 20
        m = 2  
        self.world =Att_Obj()
        self.world.addchild(objex.Mesh(RandomArray.random((10,10)),(-5,-5,3)))
        self.world.addchild(objex.Mesh(RandomArray.random((10,10)),(-5,-5,0)))
        self.world.addchild(objex.Tree(6,5,60))
        self.world.addchild(objex.Tree(2,1,90,(0,1,3)))
        self.world.addchild(objex.Tree(2,1,90,(2,1,3)))
        self.world.addchild(objex.Tree(2,1,90,(3,1,3)))
        self.world.addchild(objex.Tree(2,1,90,(-1,4,3)))
        self.world.addchild(room.Camroom())
        self.world.addchild(ogltex.Texicosa('Images/textile.ppm',(5,-5,1.5)))
        self.world.addchild(objex.Qcyl(7,1,1,(0,2,0),'(0.0,1.0,1.0)'))
        self.world.children[-1].scale = (.5,.5,.5)
        self.world.addchild(objex.Urchin(10,(2,2,2)))
        self.world.addchild(objex.Pcircle(100,1,(-1,0,0)))
        self.object_of_attention = self.world
        self.keydict = {'c':'cut','s':'save','Return':'go','1':'ADD','2':'childADD','Up':'north','Down':'south','Left':'west','Right':'east'}

    def Zmove(self, event):
        self.camera_z = self.camera_z + .1*(event.x - self.xmouse)
        self.tkRedraw()
        if self.ouch(): 
            self.camera_z = self.camera_z - .1*(event.x - self.xmouse)
            self.tkRedraw()
        self.tkRecordMouse(event)

    def Xmove(self, event):
        self.camera_x = self.camera_x + .1*(event.x - self.xmouse)
        self.tkRedraw()
        if self.ouch(): 
            self.camera_x = self.camera_x - .1*(event.x - self.xmouse)
            self.camera_y = self.camera_y+.1*(event.x - self.xmouse)
            self.tkRedraw()
        self.tkRecordMouse(event)
            
    def draw(self):
        glDisable(GL_LIGHTING)
        glMaterialfv(GL_FRONT, GL_DIFFUSE, [1.,0.0 ,1.0, 1.0])
        self.world.att_draw()
        
    def ouch(self):
        glReadBuffer(GL_FRONT_LEFT)
        zb = fromstring(glReadPixels(200,125,1,1,GL_DEPTH_COMPONENT,GL_FLOAT),Float32) 
        print zb
##        zb = fromstring(glReadPixels(200,125,4,4,GL_RGB,GL_FLOAT),Float32)
        print "Z =",zb
        if zb[0] < 0.5:
            return(1)
        else:
            return(0)  

    def go(self):
        cyn = Att_Obj((0,0,0))
        self.object_of_attention =cyn
        for i in range(1000):
            cyn.z = cyn.z+.5
            self.camera_x = self.camera_x - .5
            self.camera_z = self.camera_z + .5
            self.tkRedraw()
	
    def ADD(self):
        self.object_of_attention = self.world.children[randint(0,len(self.world.children)-1)]
        print self.object_of_attention
        self.tkRedraw()

    def  childADD(self):
        l = len(self.object_of_attention.children)
        if l > 0:
            self.object_of_attention = self.object_of_attention.children[randint(0,l-1)]
            self.tkRedraw()

    def cut(self):
        try:
            self.object_of_attention.cut()
            for i in range(100):
                self.tkRedraw()
        except:
            pass  
            	
    def north(self):
        self.object_of_attention = self.compass_north
        self.tkRedraw()
        
    def south(self):
        self.object_of_attention = self.compass_south
        self.tkRedraw()
        
    def east(self):
        self.object_of_attention = self.compass_east
        self.tkRedraw()
        
    def west(self):
        self.object_of_attention = self.compass_west
        self.tkRedraw()
        
    def save(self):
        gl_SavePPM(self,'pix',100,100)

glLight(GL_LIGHT0, GL_AMBIENT, [0.0, 1.0, 0.0, 1.0])
glLight(GL_LIGHT0, GL_DIFFUSE, [1.0, 1.0, 1.0, 1.0])
glLight(GL_LIGHT0, GL_SPECULAR, [1.0, 1.0, 1.0, 1.0])
glLight(GL_LIGHT0, GL_POSITION, [1.0, 1.0, 1.0, 0.0]);   
glLightModel(GL_LIGHT_MODEL_AMBIENT, [0.2, 0.2, 0.2, 1.0])
glDisable(GL_LIGHTING)
glEnable(GL_LIGHT0)
glDepthFunc(GL_LESS)
glEnable(GL_DEPTH_TEST)
glShadeModel(GL_SMOOTH)
glMatrixMode(GL_MODELVIEW)
glEnable(GL_POINT_SMOOTH)
r = rx(width =400, height = 250, double = 1,depth=1)
r.pack(side = 'top', expand = 1, fill = 'both')
glPointSize(5.0)
r.start()
r.mainloop()
