this is a try at a VR world
whitout opengl
but whit OOP
error :
- i get only a black screen
sugestions or improvement are welkom to
basic3d.py
cColor.py
cVector3.py
main
whitout opengl
but whit OOP
error :
- i get only a black screen
sugestions or improvement are welkom to
basic3d.py
import pygame from pygame.locals import * import sys from cVector3 import * import math from cColor import * pygame.init() winx , winy = 640 , 480 screen = pygame.display.set_mode( ( winx , winy ) , 0 , 32 ) class Matrix( object ) : def __init__( self ) : self.m = [ [ 1. , 0. , 0. , 0. ] , [ 0. , 1. , 0. , 0. ] , [ 0. , 0. , 1. , 0. ] , [ 0. , 0. , 0. , 1. ] ] def __mul__( self , r ) : uit = Matrix() for i in xrange( 3 ) : for j in xrange( 3 ) : uit.m[ i ][ j ] = 0 for k in xrange( 3 ) : uit.m[ i ][ j ] += self.m[ i ][ k ] * r.m[ k ][ j ] return uit lv = [] for i in xrange( 64 ) : lv.append( Matrix() ) lsk = [] for i in xrange( 64 ) : lsk.append( Vector3() ) number = 0 def rad( x ) : return x * math.pi / 180. XYZ , XZY , YXZ , YZX , ZXY , ZYX = 1 , 2 , 3 , 4 , 5 , 6 def link( no , x , y , z , xz , yz , xy , ax , p ) : if no < 1 or no > len( lv ) - 1 : return if p < 0 or p > len( lv ) - 1 : return if no == p : return rotx = Matrix() roty = Matrix() rotz = Matrix() trans = Matrix() m = lv[ p ] rotx.m[ 0 ][ 0 ] = math.cos( rad( yz ) ) rotx.m[ 0 ][ 1 ] = -math.sin( rad( yz ) ) rotx.m[ 1 ][ 0 ] = math.sin( rad( yz ) ) rotx.m[ 1 ][ 1 ] = math.cos( rad( yz ) ) roty.m[ 0 ][ 0 ] = math.cos( rad( xz ) ) roty.m[ 0 ][ 2 ] = -math.sin( rad( xz ) ) roty.m[ 2 ][ 0 ] = math.sin( rad( xz ) ) roty.m[ 2 ][ 2 ] = math.cos( rad( xz ) ) rotz.m[ 1 ][ 1 ] = math.cos( rad( xy ) ) rotz.m[ 1 ][ 2 ] = -math.sin( rad( xy ) ) rotz.m[ 2 ][ 1 ] = math.sin( rad( xy ) ) rotz.m[ 2 ][ 2 ] = math.cos( rad( xy ) ) trans.m[ 3 ][ 0 ] = x trans.m[ 3 ][ 1 ] = y trans.m[ 3 ][ 2 ] = z if ax == XYZ : lv[ no ] = m * rotx * roty * rotz * trans elif ax == XZY : lv[ no ] = m * rotx * rotz * roty * trans elif ax == YXZ : lv[ no ] = m * roty * rotx * rotz * trans elif ax == YZX : lv[ no ] = m * roty * rotz * rotx * trans elif ax == ZXY : lv[ no ] = m * rotz * rotz * roty * trans elif ax == ZYX : lv[ no ] = m * rotz * roty * rotx * trans else : lv[ no ] = m number = no def child( no , x , y , z , lim , ax , p ) : if lim < 0 or lim > len( lsk ) - 1 : return link( no , x , y , z , lsk[ lim ].y , lsk[ lim ].x , lsk[ lim ].z , ax , p ) def skelet( lim , x , y , z ) : if lim < 0 or lim > len( lsk ) - 1 : return lsk[ lim ].x = x lsk[ lim ].y = y lsk[ lim ].z = z def spot( x , y , z ) : m = lv[ number ] hx = x * m.m[ 0 ][ 0 ] + y * m.m[ 1 ][ 0 ] + z * m.m[ 2 ][ 0 ] + m.m[ 3 ][ 0 ] hy = x * m.m[ 0 ][ 1 ] + y * m.m[ 1 ][ 1 ] + z * m.m[ 2 ][ 1 ] + m.m[ 3 ][ 1 ] hz = x * m.m[ 0 ][ 2 ] + y * m.m[ 1 ][ 2 ] + z * m.m[ 2 ][ 2 ] + m.m[ 3 ][ 2 ] return ( hx , hy , hz )
cColor.py
import math # primary colors black = ( 0 , 0 , 0 ) red = ( 255 , 0 , 0 ) green = ( 0 , 255 , 0 ) yellow = ( 255 , 255 , 0 ) blue = ( 0 , 0 , 255 ) magenta = ( 255 , 0 , 255 ) cyan = ( 0 , 255 , 255 ) white = ( 255 , 255 , 255 ) # mixed colors orange = ( 255 , 127 , 0 ) pink = ( 255 , 127 , 127 ) gray = ( 127 , 127 , 127 ) purple = ( 127 , 0 , 127 ) def mix( kla , f , klb ) : r1 , g1 , b1 = kla r2 , g2 , b2 = klb r = r1 + ( r2 - r1 ) * f g = g1 + ( g2 - g1 ) * f b = b1 + ( b2 - b1 ) * f return int( r ) , int( g ) , int( b ) def rainbow( deg ) : r = math.sin( deg * math.pi / 180 ) * 127 + 128 g = math.sin( ( deg - 120 ) * math.pi / 180 ) * 127 + 128 b = math.sin( ( deg + 120 ) * math.pi / 180 ) * 127 + 128 return int( r ) , int( g ) , int( b )
cVector3.py
import math class Vector3 : def __init__( self , x = 0.0 , y = 0.0 , z = 0.0 ) : self.x = x self.y = y self.z = z @classmethod def from_points( self , p1 , p2 ) : return Vector3( p2[ 0 ] - p1[ 0 ] , p2[ 1 ] - p1[ 1 ] , p2[ 2 ] - p1[ 2 ] ) def lenght( self ) : return math.sqrt( self.x**2 + self.y**2 + self.z**2 ) def normalize( self ) : self.x /= self.lenght() + 1e-7 self.y /= self.lenght() + 1e-7 self.z /= self.lenght() + 1e-7 def __add__( self , r ) : return Vector3( self.x + r.x , self.y + r.y , self.z + r.z ) def __sub__( self , r ) : return Vector3( self.x - r.x , self.y - r.y , self.z - r.z ) def __neg__( self ) : return Vector3( -self.x , -self.y , -self.z ) def __mul__( self , f ) : return Vector3( self.x * f , self.y * f , self.z * f ) def __div__( self , f ) : return Vector3( self.x / f , self.y / f , self.x / f ) def angle( self , v ) : return math.acos( ( self.lenght() * v.lenght() ) / dot( self , v ) ) def cross( a , b ) : return Vector3( a.y * b.z - a.z * b.y , a.z * b.x - a.x * b.z , a.x * b.y - a.y * b.x ) def dot( a , b ) : return a.x * b.x + a.y * b.y + a.z * b.z + 1e-7
main
from basic3d import * class Triangle( object ) : def __init__( self , p1 , p2 , p3 , clr ) : p1.x , p1.y , p1.z = spot( p1.x , p1.y , p1.z ) p2.x , p2.y , p2.z = spot( p2.x , p2.y , p2.z ) p3.x , p3.y , p3.z = spot( p3.x , p3.y , p3.z ) self.p1 = p1 self.p2 = p2 self.p3 = p3 self.led = ( self.p1 + self.p2 + self.p3 ) / 3 self.normal = self.led + cross( self.p2 - self.p1 , self.p3 - self.p1 ) self.clr = clr def draw( self , light ) : points = [] points.append( ( winx / 2 + self.p1.x / ( self.p1.z + 1000 ) * 1000 , winy / 2 - self.p1.y / ( self.p1.z + 1000 ) * 1000 ) ) points.append( ( winx / 2 + self.p2.x / ( self.p2.z + 1000 ) * 1000 , winy / 2 - self.p2.y / ( self.p2.z + 1000 ) * 1000 ) ) points.append( ( winx / 2 + self.p3.x / ( self.p3.z + 1000 ) * 1000 , winy / 2 - self.p3.y / ( self.p3.z + 1000 ) * 1000 ) ) # normal = self.normal - self.led # normal.normalize() # light.normalize() # angle = normal.angle( light ) # self.clr = mix( self.clr , math.cos( angle ) / 2 + .5 , black ) pygame.draw.polygon( screen , self.clr , points ) class World( object ) : def __init__( self ) : self.tri = [] self.pnt = [] for i in xrange( 256 ) : self.pnt.append( Vector3() ) def point( self , no , x , y , z ) : if no < 0 or no > len( self.pnt ) - 1 : return self.pnt[ no ].x = x self.pnt[ no ].y = y self.pnt[ no ].z = z def tri( self , p1 , p2 , p3 , clr ) : self.tri.append( Triangle( self.pnt[ p1 ] , self.pnt[ p2 ] , self.pnt[ p3 ] , clr ) ) def quad( self , p1 , p2 , p3 , p4 , clr ) : self.tri.append( Triangle( self.pnt[ p1 ] , self.pnt[ p2 ] , self.pnt[ p3 ] , clr ) ) self.tri.append( Triangle( self.pnt[ p4 ] , self.pnt[ p2 ] , self.pnt[ p3 ] , clr ) ) def draw( self , light ) : # sort trianlges for h in range( 1 , len( self.tri ) - 1 ) : for l in range( 0 , h - 1) : if self.tri[ h ].led.z < self.tri[ l ].led.z : htri = self.tri[ h ] self.tri[ h ] = self.tri[ l ] self.tri[ l ] = htri for i in xrange( len( self.tri ) - 1 ) : self.tri[ i ].draw( light ) def color_cube( self , m , d ) : self.point( 0 , m.x + d.x , m.y + d.y , m.z + d.z ) self.point( 1 , m.x + d.x , m.y + d.y , m.z - d.z ) self.point( 2 , m.x + d.x , m.y - d.y , m.z + d.z ) self.point( 3 , m.x + d.x , m.y - d.y , m.z - d.z ) self.point( 4 , m.x - d.x , m.y + d.y , m.z + d.z ) self.point( 5 , m.x - d.x , m.y + d.y , m.z - d.z ) self.point( 6 , m.x - d.x , m.y - d.y , m.z + d.z ) self.point( 7 , m.x - d.x , m.y - d.y , m.z - d.z ) self.quad( 0 , 1 , 3 , 2 , red ) self.quad( 7 , 6 , 4 , 5 , cyan ) self.quad( 0 , 1 , 5 , 4 , green ) self.quad( 7 , 6 , 3 , 2 , magenta ) self.quad( 0 , 2 , 6 , 4 , blue ) self.quad( 7 , 5 , 1 , 3 , yellow ) def clear( self ) : self.tri[ : ] = [] world = World() angle = 0. angle_speed = 180. / 25. clock = pygame.time.Clock() pygame.display.set_caption( "VR 3D 1.0" ) while True : for event in pygame.event.get() : if event.type == QUIT : sys.exit() elif event.type == KEYDOWN : if event.key == K_ESCAPE : sys.exit() screen.fill( black ) world.clear() link( 1 , 0 , 0 , 0 , angle , angle , 0 , XYZ , 0 ) world.color_cube( Vector3( 0 , 0 , 0 ) , Vector3( 100 , 100 , 100 ) ) world.draw( Vector3( 0 , 200 , 0 ) ) clock.tick( 25 ) angle += angle_speed pygame.display.update()