Author: JonNeal
Date: 2008-07-14 21:51:02 -0400 (Mon, 14 Jul 2008)
New Revision: 1308

Modified:
   trunk/pysoy/config.py
   trunk/pysoy/examples/LandScape.py
   trunk/pysoy/include/soy.scenes.pxd
   trunk/pysoy/setup.py
   trunk/pysoy/src/scenes/Landscape.pym
Log:
Ticket #929: changed around Landscape.pym and Landscape.py a whole lot. 
Got it half working! Renders landscape esque thing, lots of work to be 
done though.


Modified: trunk/pysoy/config.py
===================================================================
--- trunk/pysoy/config.py       2008-07-12 21:08:42 UTC (rev 1307)
+++ trunk/pysoy/config.py       2008-07-15 01:51:02 UTC (rev 1308)
@@ -61,7 +61,7 @@
   'materials'        : ['gl', 'glew'],
   'models'           : ['glew', 'gl', 'glu', 'ode'],
   'textures'         : ['glew', 'gl', 'theora', 'ogg', 'cairo'],
-  'scenes'           : ['gl', 'ode'],
+  'scenes'           : ['glew', 'gl', 'ode'],
   'shapes'           : ['ode'],
   'transports'       : ['ogg'],
   'widgets'          : ['glew', 'gl', 'glu'], 

Modified: trunk/pysoy/examples/LandScape.py
===================================================================
--- trunk/pysoy/examples/LandScape.py   2008-07-12 21:08:42 UTC (rev 1307)
+++ trunk/pysoy/examples/LandScape.py   2008-07-15 01:51:02 UTC (rev 1308)
@@ -3,47 +3,66 @@
 import soy
 from time import sleep
 
-
 ### Start Heightmap Code
-heightTex = soy.transports.File('media/white.soy')['gimp']
+heightTex = soy.transports.File('media/Heightmap.soy')['gimp']
 sleep(2) # HACK: this will wait while transportloop does his stuff
-heightScene = soy.scenes.Landscape(heightTex,soy.materials.Material())
-#sce = soy.scenes.Scene()
+heightScene = 
soy.scenes.Landscape(heightTex,soy.materials.Material(),height=100)
 #heightScene = soy.scenes.Scene();# with normal scene, everything is peachy
 ### Start PySoy Code (Excerpt from pysoy-primer.py)
 # Initialize a window 
-
 scr = soy.Screen()
-win = soy.Window(scr, "A Spinning Cube")
+win = soy.Window(scr, "A cube and landscape")
 
 # Create a cube with a shape, material and a body.
 cube = soy.shapes.Box(1, 1, 1) # Step 1: Shape
 mat = soy.materials.Material() # Step 2: Material
 mat.shininess = 5 # (Optional) Looks nicer (modifies the applied specular 
lighting; play with this setting to see how it affects appearance)
-body = soy.bodies.Body(scene=heightScene, model=soy.models.Shape(mat), 
shape=cube, position=(0,-2,0)) # Step 3: Body
-
+body = soy.bodies.Body(scene=heightScene, model=soy.models.Shape(mat), 
shape=cube, position=(0,5,0)) # Step 3: Body
+global camera
 # Put a light and camera into the initialized screen
 light = soy.bodies.Light(heightScene)
 camera = soy.bodies.Camera(heightScene)
-#stx = soy.widgets.StackX(win)
-#pro = soy.widgets.Projector(stx, camera=camera)
-#cam2 = soy.bodies.Camera(sce)
-#cam2.position = (-0.3, 0.0, 15.0)
-#pro2 = soy.widgets.Projector(stx, camera=cam2)
-
 pro = soy.widgets.Projector(win, camera=camera)
 
-#lig = soy.bodies.Light(sce)
-#lig.position = (-10.0,10.0,2.0)
 
-camera.position = (0, -2, 5.0) #50?
+camera.position = (0, 1, 250.0) #50?
 light.position = (0.5, 1.0, 5.0)
-#heightScene.gravity = (0,-1,0)
-#mat=soy.materials.Material()
-#a=soy.bodies.Body(scene=sce,model=soy.models.Shape(mat),shape=soy.shapes.Box(2,1,2),position=(0,-1.2,-1))
+heightScene.gravity = (0,-1,0)
 
+def addx() :
+  global camera
+  camera.position[0] += 1
+def addy() :
+  global camera
+  camera.position[1] += 1
+def addz():
+  global camera
+  camera.position[2] += 1
+def subz():
+  global camera
+  camera.position[2] -= 1
+def subx() :
+  global camera
+  camera.position[0] -= 1
+def suby():
+  camera.position[1] -= 1
+def toggleWireframe():
+  camera.wireframe = not camera.wireframe
+
+key = soy.controllers.Keyboard(win)
+key['R'] = addy #up
+key['Q'] = subx #left
+key['T'] = suby #down
+key['S'] = addx #right
+key['V'] = addz #pgup
+key['U'] = subz #pgdwn
+key['w'] = toggleWireframe
+key['q'] = soy.actions.Quit()
+key[ 1 ] = soy.actions.Quit() # 9 = esc key
+wcn = soy.controllers.Window(win)
+wcn['close'] = soy.actions.Quit()
+
 if __name__ == "__main__":
   #mainloop goes here
   while 1:
-    sleep(1)
-    #print body.position #annoying
+    sleep(0.1)

Modified: trunk/pysoy/include/soy.scenes.pxd
===================================================================
--- trunk/pysoy/include/soy.scenes.pxd  2008-07-12 21:08:42 UTC (rev 1307)
+++ trunk/pysoy/include/soy.scenes.pxd  2008-07-15 01:51:02 UTC (rev 1308)
@@ -82,13 +82,15 @@
   cdef int                        _width
   cdef int                        _depth
   cdef int                        _height
+  cdef soy.textures.Texture       _heightmapTex
   cdef gl.GLuint                  _buffer
   cdef gl.GLuint                  _elementbuffer
-  cdef void                       _createBuffer   ( self )
+  cdef int                        _position[3]
   cdef int                        _verts
   cdef Vert*                      _vertArray
   cdef Face*                      _elementArray
-  cdef gl.GLfloat*                vertices[72]
+  cdef void                       _createBuffer   ( self )
+  cdef void                       _createArrays   ( self )
   
 cdef class Planar (Scene) :
   cdef ode.dGeomID                _planeID

Modified: trunk/pysoy/setup.py
===================================================================
--- trunk/pysoy/setup.py        2008-07-12 21:08:42 UTC (rev 1307)
+++ trunk/pysoy/setup.py        2008-07-15 01:51:02 UTC (rev 1308)
@@ -46,7 +46,7 @@
   'materials'        : ['GL','GLEW'],
   'models'           : ['GLEW','GL','GLU','ode'],
   'textures'         : ['GLEW','GL', 'theora', 'ogg', 'cairo'],
-  'scenes'           : ['GL', 'ode'],
+  'scenes'           : ['GLEW', 'GL', 'ode'],
   'shapes'           : ['ode'],
   'transports'       : ['ogg'],
   'widgets'          : ['GLEW','GL','GLU'], 

Modified: trunk/pysoy/src/scenes/Landscape.pym
===================================================================
--- trunk/pysoy/src/scenes/Landscape.pym        2008-07-12 21:08:42 UTC (rev 
1307)
+++ trunk/pysoy/src/scenes/Landscape.pym        2008-07-15 01:51:02 UTC (rev 
1308)
@@ -17,12 +17,12 @@
 #
 # $Id$
 
-
 cdef class Landscape (Scene) :
   ''' Landscape Scene
 
     This is a scene based on a heightmap.
-    Accepts a heightmap with the detail of it, the width, depth, and height of 
it.
+    Accepts a heightmap with the detail of it, the width, depth, and height, 
and
+    the position in the form of a dict (x, y, z)
   '''
 
   ############################################################################
@@ -30,111 +30,152 @@
   # Python functions
   #
 
-  def __cinit__(self, soy.textures.Texture heightmap,soy.materials.Material 
mat, detail = 1, width=1024, depth=1024, height=1024, *args, **kw) :
-    cdef int _i, _j
-    cdef double _value
-    if not isinstance(heightmap, soy.textures.Texture) or heightmap._chans != 
1 :
-      raise TypeError('Heightmap must be of type soy.textures.Texture and 1 
channel, not '+str(heightmap._chans))
+  def __cinit__(self, soy.textures.Texture heightmap,soy.materials.Material 
mat, \
+  detail = 1, width=1024, depth=1024, height=1024, position=(0, 0, 0), *args, 
**kw) :
+    assert isinstance(heightmap, soy.textures.Texture) or heightmap._chans != 
1, \
+      "Heightmap must be of type soy.textures.Texture and 1 channel, not 
"+str(heightmap._chans)
+    assert type(position[0]) == int or type(position[1]) == int or \
+      type(position[2]) == int, "The heightmap position must be an int"
     #We need to make an array on the heap, and put the verts there
-    stdio.printf("Cinit Start!\n");
-    # Now we need to define the vars somehow (like px py pz, tx ty ...)
-    self._verts  = 0
+    self._buffer = 0
+    self._elementbuffer = 0
     self._width  = width
     self._depth  = depth
     self._height = height
+    self.position = position
     self._heightmapID = ode.dGeomHeightfieldDataCreate()
-    self._vertArray = <Vert *> 
py.PyMem_Malloc((heightmap._width*heightmap._height/detail)*16*4) 
-    self._elementArray =  <Face *> 
py.PyMem_Malloc(sizeof(Face)*((heightmap._width*heightmap._height/detail))/3) 
#21k*Face
-    #for _i from 0 < _i < 72:
+    self._vertArray = <Vert *> 
py.PyMem_Malloc(heightmap._width*heightmap._height*16*4) 
+    self._elementArray =  <Face *> 
py.PyMem_Malloc(sizeof(Face)*((heightmap._width-1)*(heightmap._height-1)*2)) 
     ode.dGeomHeightfieldDataBuildByte(self._heightmapID,
                                       <unsigned char*> heightmap._texels, 0,
                                       heightmap._width, heightmap._depth,
                                       self._width/heightmap._width,
                                       self._depth/heightmap._depth, 
                                       1, 0, 1, 0)
-    self._heightmap = ode.dCreateHeightfield(self._spaceID, self._heightmapID, 
1)
-    ##Setup Arrays Here
-    for _i from 1 <= _i < heightmap._width :
-      for _j from 1 <= _j < heightmap._height : 
-        self._verts +=1
-        # Get the y value here
-        _value = heightmap._texels[heightmap._width*(_i-1)+_j]
-        #stdio.printf("%d\n",value)
-        #yea, so now value*scale got 
-        _value = _value/255.0 #255 is max, so if the value == 255(white) then 
its a 1 for high, thats mul'ed by height
-        self._vertArray[heightmap._width*(_i-1)+_j].px = _i
-        self._vertArray[heightmap._width*(_i-1)+_j].pz = _j
-        self._vertArray[heightmap._width*(_i-1)+_j].py = _value
-        self._vertArray[heightmap._width*(_i-1)+_j].tx = 0
-        self._vertArray[heightmap._width*(_i-1)+_j].ty = 1
-        self._vertArray[heightmap._width*(_i-1)+_j].tz = 0
-        self._vertArray[heightmap._width*(_i-1)+_j].nx = 0
-        self._vertArray[heightmap._width*(_i-1)+_j].ny = 1
-        self._vertArray[heightmap._width*(_i-1)+_j].nz = 0
-        #stdio.printf("%f\n", _value);
-       #Make a Step for the above loops, or make a loop for making the faces
-       #I think we need to make the element array generation code here
-    _i = 0
-    for _i from 1 <= _i < ((heightmap._width*heightmap._height/detail))/3:
-        
-        self._elementArray[_i].a = (_i*3)-2
-        self._elementArray[_i].b = (_i*3)-1
-        self._elementArray[_i].c = (_i*3)
-        #stdio.printf("index :%d, A: %d, B: %d, C: 
%d\n",_i,self._elementArray[_i].a,self._elementArray[_i].b,self._elementArray[_i].c);
-    stdio.printf("Cinit Done!\n");
+    self._heightmap = ode.dCreateHeightfield(self._spaceID, self._heightmapID, 
1) #the ode heightmap
+    self._heightmapTex = heightmap
+    self._createArrays()
     
   def __dealloc__(self) :
-    ode.dGeomHeightfieldDataDestroy(self._heightmapID)
+    pass
+    #ode.dGeomHeightfieldDataDestroy(self._heightmapID)
     #gl.glDeleteBuffersARB(1, &self._buffer);
 
 
   ############################################################################
   #
+  # Properties
+  #
+
+  property position :
+    '''Landscape's Position
+    '''
+    def __get__(self) :
+      return (self._position[0], self._position[1], self._position[2])
+    def __set__(self, value) :
+      assert type(value) != tuple or type(value) != list, \
+        "Must provide a tuple or list for landscape position!"
+      assert len(value) == 3, "Must provide (x,y,z)"
+      self._position[0] = value[0]
+      self._position[1] = value[1]
+      self._position[2] = value[2]
+
+  ############################################################################
+  #
   # General C functions
   #
 
+  cdef void _createArrays(self) :
+    cdef int _i, _j, _currentLoop
+    cdef double _x, _y, _z
+    # set up the vert array
+    for _i from 0 <= _i < self._heightmapTex._height :
+      for _j from 0 <= _j < self._heightmapTex._width :
+        # Get the y value here
+        _y = self._heightmapTex._texels[self._heightmapTex._width*_i+_j]
+        #divide by width to get what percentage it is of width, then multiply 
by width wanted
+        _x = _j / 1.0 / self._heightmapTex._width * self._width + 
self._position[0]
+        _y = _y / 255.0 * self._height + self._position[1]
+        _z = _i / 1.0 / self._heightmapTex._height * self._depth + 
self._position[2]
+        self._vertArray[self._heightmapTex._width*_i+_j].px = _x
+        self._vertArray[self._heightmapTex._width*_i+_j].pz = _z
+        self._vertArray[self._heightmapTex._width*_i+_j].py = _y
+        #all below need to be calculated CORRECTLY!
+        self._vertArray[self._heightmapTex._width*_i+_j].tx = 0
+        self._vertArray[self._heightmapTex._width*_i+_j].ty = 1
+        self._vertArray[self._heightmapTex._width*_i+_j].tz = 0
+        self._vertArray[self._heightmapTex._width*_i+_j].ux = 0
+        self._vertArray[self._heightmapTex._width*_i+_j].uy = 1
+        self._vertArray[self._heightmapTex._width*_i+_j].uz = 0
+        self._vertArray[self._heightmapTex._width*_i+_j].nx = 0
+        self._vertArray[self._heightmapTex._width*_i+_j].ny = 1 # Up
+        self._vertArray[self._heightmapTex._width*_i+_j].nz = 0
+     #clear vars for next loops!
+    _i = 0
+    _j = 0
+    _currentLoop = 0
+    #loop through all of the quads in the grid
+    for _i from 0 <= _i < self._heightmapTex._height-1 :
+      for _j from 0 <= _j < self._heightmapTex._width-1 :
+        #create the upper left tri in the quad
+        #verts are in counter clockwise direction
+        self._elementArray[_currentLoop*2].a = _j + 1 + _i * 
self._heightmapTex._width
+        self._elementArray[_currentLoop*2].b = _j + _i * 
self._heightmapTex._width
+        self._elementArray[_currentLoop*2].c = _j + (_i+1) * 
self._heightmapTex._width
+        #now the bottom right!
+        self._elementArray[_currentLoop*2+1].a = _j + 1 + _i * 
self._heightmapTex._width
+        self._elementArray[_currentLoop*2+1].b =  _j + (_i+1) * 
self._heightmapTex._width
+        self._elementArray[_currentLoop*2+1].c =  _j + 1 + (_i+1) * 
self._heightmapTex._width
+        _currentLoop = _currentLoop + 1
+
+
   cdef void _createBuffer(self) :
-    stdio.printf("createBuffer Start!\n");    
-
-  cdef void _render(self) :
-    stdio.printf("%s","_render\n")
-    gl.glGenBuffersARB(1, <gl.GLuint*> &self._buffer) # Create the vertex 
buffers?
+    gl.glGenBuffersARB(1, <gl.GLuint*> &self._buffer) # Create the vertex 
buffers
     gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, <gl.GLuint> self._buffer)
-    gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, (sizeof(Vert)*self._verts),
-                       self._vertArray, gl.GL_STATIC_DRAW_ARB)
+    gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, (sizeof(Vert)*
+          self._heightmapTex._width*self._heightmapTex._height), 
self._vertArray,
+          gl.GL_STATIC_DRAW_ARB)
     gl.glGenBuffersARB(1, &self._elementbuffer)
     gl.glBindBufferARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._elementbuffer)  # 
Create the elements buffers
-    gl.glBufferDataARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._verts/3,
-                       self._elementArray, gl.GL_STATIC_DRAW_ARB)
-    #gl.glGenBuffersARB(1, &self._buffer);
-    #gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, self._buffer);
-    #gl.glBufferDataARB(gl.GL_ARRAY_BUFFER_ARB, sizeof(vertices), 
<gl.GLvoid*>0, gl.GL_STATIC_DRAW_ARB);
-    #gl.glBufferSubDataARB(gl.GL_ARRAY_BUFFER_ARB, 0, sizeof(vertices), 
vertices);
-    #gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, _buffer)
-    gl.glVertexPointer  (3,  gl.GL_FLOAT, sizeof(Vert), <float*>  0)
-    gl.glNormalPointer  (    gl.GL_FLOAT, sizeof(Vert), <float*> 12)
-    #gl.glNormalPointer(gl.GL_FLOAT, 0, <gl.GLvoid *>0);
-    gl.glTexCoordPointer(3, gl.GL_FLOAT, sizeof(Vert), <float*> 24)
-    #gl.glDrawArrays(gl.GL_QUADS, 0, 24);
-    stdio.printf("%s","glDrawElements\n")
-    gl.glDrawElements (gl.GL_TRIANGLES, 20,
-                    gl.GL_UNSIGNED_SHORT, <Face*> 0)#self._elementArray)
+    gl.glBufferDataARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, 
sizeof(Face)*(self._heightmapTex._width-1)*(self._heightmapTex._height-1)*2, 
self._elementArray, gl.GL_STATIC_DRAW_ARB)
+
+
+  cdef void _render(self) :
+    if self._buffer:
+      py.PyMem_Free(self._elementArray) # The arrays are in Vram so lets free 
it in system mem
+      py.PyMem_Free(self._vertArray)
+      self._elementArray = NULL; # Make the pointer NULL so UB doesn't occur 
in free()
+      self._vertArray = NULL;
+      gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, <gl.GLuint> self._buffer) # 
Bind to buffer for rendering below
+      gl.glBindBufferARB(gl.GL_ELEMENT_ARRAY_BUFFER_ARB, self._elementbuffer) 
+    else:
+      self._createBuffer()
+    gl.glVertexPointer  (3,  gl.GL_FLOAT, sizeof(Vert), <float*>  0) #px py pz
+    gl.glNormalPointer  (    gl.GL_FLOAT, sizeof(Vert), <float*> 12)  # nx ny 
nz
+    gl.glTexCoordPointer(3, gl.GL_FLOAT, sizeof(Vert), <float*> 24) # tx ty tz
+    #gl.glDrawArrays(gl.GL_TRIANGLES, 0, self._verts);
+    #stdio.printf("%s","glDrawElements\n")
+    gl.glDrawElements (gl.GL_TRIANGLES, 
(self._heightmapTex._width-1)*(self._heightmapTex._height-1)*2,
+                    gl.GL_UNSIGNED_SHORT, <Face*> 3)
     gl.glBindBufferARB(gl.GL_ARRAY_BUFFER_ARB, 0);
+    
     Scene._render(self)
-    stdio.printf("Render Done!\n");
 """
 
-TODO :
-- First Get it to render
-- Divide data in to sectors
-- get Sectors middle point
+TODO : LOD
+- First Get it to render        | 3/4 there :P
+- Divide data in to sectors     |
+- get Sectors middle point      |
 - Relative to the sector distance to camera, calculate LOD value
 - Apply LOD algo using value
+  -elementsArray has to be reduced using LOD value
+  -verticies will still be in VRAM, but we're not gonna draw them, so its 
still optimized.
+IRC excerpt, LOD algo basis
 yea
- the size of the number of triangles times three
+ the size of the number of triangles times three 
 its one big block to you since a landscape will have *one* material
- Z texcoord can be used to change the terrain type 
-this means that you can use the face array for LOD more easily
+ Z texcoord can be used to change the terrain type (3d texture)
+this means that you can use the face array for LOD more easily(elementsArray.. 
after this i get confused) 
  see basically you can "shift up" the array, adding one to both the offset and 
length, such that the "base" face array is the lowest resolution and each time 
you shift up one it removes one triangle and replaces it with two
  is, if your array has four triangles in the low resolution, ABCD
  and the second step is A split = EF, B=GH, C=IJ, D=KL, then it's arranged as:
@@ -145,4 +186,4 @@
  if you try to do this on a one polygon basis you'll end up rendering too 
many. its easier to group them
  in each group give the most radical angles the highest priority - so a steep 
angled triangle would be D in the above example
  er, sorry, the steepest would be A
-"""
\ No newline at end of file
+"""

_______________________________________________
PySoy-SVN mailing list
PySoy-SVN@pysoy.org
http://www.pysoy.org/mailman/listinfo/pysoy-svn

Reply via email to