示例#1
0
 def __init__ ( self, meshName, planeSize, complexity ):
     self.dirty = True # need to refo calcs
     self.meshName = meshName  
     self.complexity =  complexity  
     self.numFaces = 2 * complexity * complexity 
     self.numVertices = (complexity + 1) * (complexity + 1)  
     self.lastTimeStamp = 0  
     self.lastAnimationTimeStamp = 0 
     self.lastFrameTime = 0  
 
     ## initialize algorithm parameters
     self.PARAM_C = 0.3   ## ripple speed
     self.PARAM_D = 0.4   ## distance
     self.PARAM_U = 0.05   ## viscosity
     self.PARAM_T = 0.13   ## time
     self.useFakeNormals = False  
 
     ## allocate space for normal calculation
     self.vNormals=[]
     for x in range ( self.numVertices * 3 ):
         self.vNormals.append(0)
 
     ## create mesh and submesh
     self.mesh = ogre.MeshManager.getSingleton().createManual(meshName,
             ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME) 
     self.subMesh = self.mesh.createSubMesh() 
     self.subMesh.useSharedVertices=False 
 
     ## Vertex buffers
     ##self.subMesh.vertexData = ogre.VertexData() 
     self.subMesh.vertexData = ogre.createVertexData() 
     self.subMesh.vertexData.vertexStart = 0 
     self.subMesh.vertexData.vertexCount = self.numVertices 
 
     vdecl = self.subMesh.vertexData.vertexDeclaration 
     vbind = self.subMesh.vertexData.vertexBufferBinding 
 
 
     vdecl.addElement(0, 0, ogre.VertexElementType.VET_FLOAT3, ogre.VertexElementSemantic.VES_POSITION) 
     vdecl.addElement(1, 0, ogre.VertexElementType.VET_FLOAT3, ogre.VertexElementSemantic.VES_NORMAL) 
     vdecl.addElement(2, 0, ogre.VertexElementType.VET_FLOAT2, ogre.VertexElementSemantic.VES_TEXTURE_COORDINATES) 
 
     ## Prepare buffer for positions - todo: first attempt, slow
     self.posVertexBuffer = \
          ogre.HardwareBufferManager.getSingleton().createVertexBuffer(
             3 * ctypes.sizeof(ctypes.c_float),
             self.numVertices,
             ogre.HardwareBuffer.HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE) 
     vbind.setBinding(0, self.posVertexBuffer) 
 
     
     ## Prepare buffer for normals - write only
     self.normVertexBuffer = \
          ogre.HardwareBufferManager.getSingleton().createVertexBuffer(
             3*ctypes.sizeof(ctypes.c_float), 
             self.numVertices,
             ogre.HardwareBuffer.HBU_DYNAMIC_WRITE_ONLY_DISCARDABLE) 
     vbind.setBinding(1, self.normVertexBuffer) 
 
     ## Prepare texture coords buffer - static one
     ## todo: optimize to write directly into buffer
     texcoordsBufData=array.array('f')
     for x in range (self.numVertices*2):
         texcoordsBufData.append(0)
     
     for y in range (complexity) :
         for x in range(complexity) :
             texcoordsBufData[2*(y*(complexity+1)+x)+0] = float(x) / complexity  
             texcoordsBufData[2*(y*(complexity+1)+x)+1] = 1.0 - (float(y) / (complexity))  
 
 
     texcoordsVertexBuffer = \
          ogre.HardwareBufferManager.getSingleton().createVertexBuffer(
             2*ctypes.sizeof(ctypes.c_float),
             self.numVertices,
             ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY) 
     texcoordsVertexBuffer.writeData(0,
         texcoordsVertexBuffer.getSizeInBytes(),
         texcoordsBufData.buffer_info()[0],
         True)  ## true?
     vbind.setBinding(2, texcoordsVertexBuffer) 
 
     ## Prepare buffer for indices
     self.indexBuffer = \
         ogre.HardwareBufferManager.getSingleton().createIndexBuffer(
             ogre.HardwareIndexBuffer.IT_16BIT,
             3*self.numFaces,
             ogre.HardwareBuffer.HBU_STATIC, True) 
            
     # using a helper object to handle the ctypes implement
     # Create a buffer object and then lock it
     faceVertexIndices = buffer ( self.indexBuffer )
     faceVertexIndices.lock (0, self.numFaces*3*2, ogre.HardwareBuffer.HBL_DISCARD) 
     
     for y in range (complexity) :
         for  x in range (complexity ) :
             twoface = (y*complexity+x)*2*3 # index into buffer
             p0 = y*(complexity+1) + x  
             p1 = y*(complexity+1) + x + 1  
             p2 = (y+1)*(complexity+1) + x  
             p3 = (y+1)*(complexity+1) + x + 1 
             # write a series of bytes
             faceVertexIndices [ twoface + 0]= p2
             faceVertexIndices [ twoface + 1]= p1
             faceVertexIndices [ twoface + 2]= p0
             faceVertexIndices [ twoface + 3]= p2
             faceVertexIndices [ twoface + 4]= p3
             faceVertexIndices [ twoface + 5]= p1
             
     self.indexBuffer.unlock() 
     ## Set index buffer for self submesh
     self.subMesh.indexData.indexBuffer = self.indexBuffer 
     self.subMesh.indexData.indexStart = 0 
     self.subMesh.indexData.indexCount = 3*self.numFaces 
 
 #  prepare vertex positions
 #  note - we use 3 vertex buffers, since algorighm uses two last phases
 #  to calculate the next one
 
 # we need 2 floats, and are going through the loop three times 
     floatStorage = ctypes.c_float * (self.numVertices * 3 )
     #self.vertexBuffers = storageclass2 (1.1)
     #
     # Change here to use an 'array' for the buffers
     self.vertexBuffers = []
     for x in range (3):
         if USE_ARRAY:
             self.vertexBuffers.append( array.array('f') )
             for y in range (self.numVertices *3):
                 self.vertexBuffers[x].append(0)
         else:
             self.vertexBuffers.append( floatStorage(1.1) )
         
     
     ## Note that in the C++ code self.vertexBuffers is a float * array[3], whcih indexes into float*numverticies*3
     ## we have made a single array bige nough to cope
     #self.vertexIndexSize = self.numVertices*3
     
     for b in range(3) :
         for y in range(complexity) :
             for x in range (complexity) :
                 numPoint = y*(complexity+1) + x  
                 VertexPos = 3 * numPoint
                 self.vertexBuffers[b][VertexPos + 0] = float(x) / float(complexity) * float(planeSize)
                 self.vertexBuffers[b][VertexPos + 1] = 0
                 self.vertexBuffers[b][VertexPos + 2] = float(y) / float(complexity) * float(planeSize) 
                     
     meshBounds = ogre.AxisAlignedBox(0,0,0, planeSize,0, planeSize) 
     self.mesh._setBounds(meshBounds) 
 
     self.currentBufNumber = 0 
     if USE_ARRAY:
         self.posVertexBuffer.writeData(0,
             self.posVertexBuffer.getSizeInBytes(), ## size
             self.vertexBuffers[0].buffer_info()[0], 
             True)  ## discard?
     else:
         self.posVertexBuffer.writeData(0,
             self.posVertexBuffer.getSizeInBytes(), ## size
             ctypes.addressof(self.vertexBuffers[0]), 
             True)  ## discard?
     self.mesh.load() 
     self.mesh.touch() 
示例#2
0
    def _prepareMesh(self):
        
        self.mesh = ogre.MeshManager.getSingleton().createManual(self.name,
            ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME) 
        self.subMesh = self.mesh.createSubMesh()
        self.subMesh.useSharedVertices=False

        numVertices = 4

        if (WaterCircle._first) : # first Circle, create some static common data
            WaterCircle._first = False

            #static buffer for position and normals
            WaterCircle._posnormVertexBuffer =\
                ogre.HardwareBufferManager.getSingleton().createVertexBuffer(
                6*ctypes.sizeof(ctypes.c_float), #size of one vertex data
                4, # number of vertices
                ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, # usage
                False) # no shadow buffer
                    
            posnormBufData = buffer ( WaterCircle._posnormVertexBuffer )
            posnormBufData.lock(ogre.HardwareBuffer.HBL_DISCARD)
            
            for i in range (numVertices):
                posnormBufData[6*i+0]=(float(i%2)-0.5)*WaterCircle.CIRCLE_SIZE; # pos X
                posnormBufData[6*i+1]=0; # pos Y
                posnormBufData[6*i+2]=(float(i/2)-0.5)*WaterCircle.CIRCLE_SIZE; # pos Z
                posnormBufData[6*i+3]=0 ; # normal X
                posnormBufData[6*i+4]=1 ; # normal Y
                posnormBufData[6*i+5]=0 ; # normal Z
                
            posnormBufData.unlock()

            #static buffers for 16 sets of texture coordinates
            for lvl in range ( 16 ):
                WaterCircle._texcoordsVertexBuffers.append(
                    ogre.HardwareBufferManager.getSingleton().createVertexBuffer(
                    2*ctypes.sizeof(ctypes.c_float), # size of one vertex data
                    numVertices, # number of vertices
                    ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY, # usage
                    False)) # no shadow buffer
                texcoordsBufData = buffer( WaterCircle._texcoordsVertexBuffers[lvl])
                texcoordsBufData.lock(ogre.HardwareBuffer.HBL_DISCARD)
                x0 = float(lvl % 4) * 0.25 
                y0 = float(lvl / 4) * 0.25
                y0 = 0.75-y0  # upside down
                for i in range (4):
                    texcoordsBufData[i*2 + 0]=x0 + 0.25 * float(i%2)
                    texcoordsBufData[i*2 + 1]=y0 + 0.25 * float(i/2)
                texcoordsBufData.unlock()

#			Index buffer for 2 faces
            faces = array.array('H',[2,1,0,2,3,1]) # unsigned short array
            WaterCircle._indexBuffer =\
				ogre.HardwareBufferManager.getSingleton().createIndexBuffer(
					ogre.HardwareIndexBuffer.IT_16BIT,
					6,
					ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY)
            WaterCircle._indexBuffer.writeData(0,
				WaterCircle._indexBuffer.getSizeInBytes(),
				faces.buffer_info()[0],
				True); # true?

#		Initialize vertex data
        self.subMesh.vertexData = ogre.createVertexData()
        self.subMesh.vertexData.vertexStart = 0
        self.subMesh.vertexData.vertexCount = 4
        #first, set vertex buffer bindings
        vbind = self.subMesh.vertexData.vertexBufferBinding 
        vbind.setBinding(0, WaterCircle._posnormVertexBuffer)
        vbind.setBinding(1, WaterCircle._texcoordsVertexBuffers[0])
        #now, set vertex buffer declaration
        vdecl = self.subMesh.vertexData.vertexDeclaration
        vdecl.addElement(0, 0, ogre.VertexElementType.VET_FLOAT3, ogre.VertexElementSemantic.VES_POSITION);
        vdecl.addElement(0, 3*ctypes.sizeof(ctypes.c_float), ogre.VertexElementType.VET_FLOAT3, ogre.VertexElementSemantic.VES_NORMAL);
        vdecl.addElement(1, 0, ogre.VertexElementType.VET_FLOAT2, ogre.VertexElementSemantic.VES_TEXTURE_COORDINATES);

        #		Initialize index data
        self.subMesh.indexData.indexBuffer = WaterCircle._indexBuffer
        self.subMesh.indexData.indexStart = 0
        self.subMesh.indexData.indexCount = 6

        #		set mesh bounds
        circleBounds = ogre.AxisAlignedBox (-WaterCircle.CIRCLE_SIZE/2.0, 0, -WaterCircle.CIRCLE_SIZE/2.0,
            WaterCircle.CIRCLE_SIZE/2.0, 0, WaterCircle.CIRCLE_SIZE/2.0)
        self.mesh._setBounds(circleBounds)
        self.mesh.load()
        self.mesh.touch()
示例#3
0
    def createGrassMesh(self):
        global GRASS_MESH_NAME
        self.SetToNone = []
        ## Each grass section is 3 planes at 60 degrees to each other
        ## Normals point straight up to simulate correct lighting
        msh = ogre.MeshManager.getSingleton().createManual(GRASS_MESH_NAME, 
            ogre.ResourceGroupManager.DEFAULT_RESOURCE_GROUP_NAME) 
        self.msh = msh
        self.hw = ogre.HardwareBufferManager.getSingleton()
        sm = msh.createSubMesh() 
        
        sm.useSharedVertices = False 

           
        self.vertexdata = ogre.createVertexData() ## Create the VertexData Object
        
        ## NOTE the submesh will delete the vertexData when it is destroyed which is BAD -- ie we have C++ specifically
        ## deleting a Python object which makes everything confused..  The fix is to set the submesh vertexData to 
        ## 'None' before exiting -- see the __del__ function
        sm.vertexData = self.vertexdata     
        
        sm.vertexData.vertexStart = 0 
        sm.vertexData.vertexCount = 12 
        dcl = sm.vertexData.vertexDeclaration 
        offset = 0 
        dcl.addElement(0, offset, ogre.VertexElementType.VET_FLOAT3, ogre.VertexElementSemantic.VES_POSITION) 
        offset += ogre.VertexElement.getTypeSize(ogre.VertexElementType.VET_FLOAT3) 
        dcl.addElement(0, offset, ogre.VertexElementType.VET_FLOAT3, ogre.VertexElementSemantic.VES_NORMAL) 
        offset += ogre.VertexElement.getTypeSize(ogre.VertexElementType.VET_FLOAT3) 
        dcl.addElement(0, offset, ogre.VertexElementType.VET_FLOAT2, ogre.VertexElementSemantic.VES_TEXTURE_COORDINATES) 
        offset += ogre.VertexElement.getTypeSize(ogre.VertexElementType.VET_FLOAT2) 

        vbuf = ogre.HardwareBufferManager.getSingleton().createVertexBuffer(
                offset, 12, ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY) 

        #lock the buffer and get a pointer to the data      
        pointer = vbuf.lock(ogre.HardwareBuffer.HBL_DISCARD)
         
        baseVec = ogre.Vector3(GRASS_WIDTH/2, 0, 0) 
        vec = baseVec 
        rot = ogre.Quaternion () 
        rot.FromAngleAxis(ogre.Degree(d=60), ogre.Vector3().UNIT_Y) 
        
        # change from the C++ demo - we build a buffer and then write it in one go
        buffer=[]
        for i in range ( 3 ) :
            ## position
            buffer.append( -vec.x )
            buffer.append( GRASS_HEIGHT )
            buffer.append( -vec.z )
            ## normal
            buffer.append( 0 )
            buffer.append( 1 )
            buffer.append( 0 )
            ## uv
            buffer.append( 0 )
            buffer.append( 0 )
            
            ## position
            buffer.append( vec.x )
            buffer.append( GRASS_HEIGHT )
            buffer.append( vec.z )
            ## normal
            buffer.append( 0 )
            buffer.append( 1 )
            buffer.append( 0 )
            ## uv
            buffer.append( 1 )
            buffer.append( 0 )
            
            ## position
            buffer.append( -vec.x )
            buffer.append( 0 )
            buffer.append( -vec.z )
            ## normal
            buffer.append( 0 )
            buffer.append( 1 )
            buffer.append( 0 )
            ## uv
            buffer.append( 0 )
            buffer.append( 1 )
            
            ## position
            buffer.append( vec.x )
            buffer.append( 0 )
            buffer.append( vec.z )
            ## normal
            buffer.append( 0 )
            buffer.append( 1 )
            buffer.append( 0 )
            ## uv
            buffer.append( 1 )
            buffer.append( 1 )
            
            vec = rot * vec 
            
        ## Python-Ogre extension function to write a list of floats to a buffer
        ogre.setFloat( pointer, buffer )
        vbuf.unlock() 
              
        sm.vertexData.vertexBufferBinding.setBinding(0, vbuf) 
          
        sm.indexData.indexCount = 6*3 
        
        sm.indexData.indexBuffer = ogre.HardwareBufferManager.getSingleton().createIndexBuffer(
                ogre.HardwareIndexBuffer.IT_16BIT, sm.indexData.indexCount,
                ogre.HardwareBuffer.HBU_STATIC_WRITE_ONLY) 
        
        pointer = sm.indexData.indexBuffer.lock(ogre.HardwareBuffer.HBL_DISCARD)

        ## here is one way to do this using a Python-Ogre helper function        
# #         buff=[]
# #         for i in range ( 3 ):
# #             off = i*4 
# #             buff.append( 0 + off )
# #             buff.append( 3 + off ) 
# #             buff.append( 1 + off )
# #             
# #             buff.append( 0 + off )
# #             buff.append( 2 + off )
# #             buff.append( 3 + off )
# #             
# #         # another Python-Ogre helper function to write unsigned ints to a buffer
# #         ogre.setUint16( pointer, buff )   

        ## Here is a way to do it with ctypes....
        pVert= ( ctypes.c_uint16 * (sm.indexData.indexCount)).from_address ( ogre.castAsInt ( pointer ) ) 
        index = 0
        for i in range ( 3 ):
            off = i*4
            pVert[ index ] = 0 + off
            index +=1
            pVert[ index ] = 3 + off
            index +=1
            pVert[ index ] = 1 + off
            index +=1
            pVert[ index ] = 0 + off
            index +=1
            pVert[ index ] = 2 + off
            index +=1
            pVert[ index ] = 3 + off
            index +=1
        sm.indexData.indexBuffer.unlock() 
        
        
        sm.setMaterialName(GRASS_MATERIAL) 
        msh.load()
        ## we need to keep access to the submesh so we can set .vertexData to None at exit (see __del__ )
        self.sm = sm