| | """Selection-buffer handling code |
| | |
| | This code is resonsible for turning gluint * |
| | arrays into structured representations for use |
| | by Python-level code. |
| | """ |
| | from OpenGL._bytes import integer_types |
| |
|
| | def uintToLong( value ): |
| | if value < 0: |
| | |
| | value = (value & 0x7fffffff) + 0x80000000 |
| | return value |
| |
|
| | class GLSelectRecord( object ): |
| | """Minimalist object for storing an OpenGL selection-buffer record |
| | |
| | Provides near and far as *float* values by dividing by |
| | self.DISTANCE_DIVISOR (2**32-1) |
| | From the spec: |
| | Depth values (which are in the range [0,1]) are multiplied by |
| | 2^32 - 1, before being placed in the hit record. |
| | |
| | Names are unmodified, so normally are slices of the array passed in |
| | to GLSelectRecord.fromArray( array ) |
| | """ |
| | DISTANCE_DIVISOR = float((2**32)-1) |
| | __slots__ = ('near','far','names') |
| | def fromArray( cls, array, total ): |
| | """Produce list with all records from the array""" |
| | result = [] |
| | index = 0 |
| | arrayLength = len(array) |
| | for item in range( total ): |
| | if index + 2 >= arrayLength: |
| | break |
| | count = array[index] |
| | near = array[index+1] |
| | far = array[index+2] |
| | names = [ uintToLong(v) for v in array[index+3:index+3+count]] |
| | result.append( cls( near, far, names ) ) |
| | index += 3+count |
| | return result |
| | fromArray = classmethod( fromArray ) |
| | |
| | def __init__( self, near, far, names ): |
| | """Initialise/store the values""" |
| | self.near = self.convertDistance( near ) |
| | self.far = self.convertDistance( far ) |
| | self.names = names |
| | def convertDistance( self, value ): |
| | """Convert a distance value from array uint to 0.0-1.0 range float""" |
| | return uintToLong( value ) / self.DISTANCE_DIVISOR |
| | def __getitem__( self, key ): |
| | """Allow for treating the record as a three-tuple""" |
| | if isinstance( key, integer_types): |
| | return (self.near,self.far,self.names)[key] |
| | elif key in self.__slots__: |
| | try: |
| | return getattr( self, key ) |
| | except AttributeError as err: |
| | raise KeyError( """Don't have an index/key %r for %s instant"""%( |
| | key, self.__class__, |
| | )) |
| |
|