programmed camera motion

'''
This is a cool little demo with programmed camera motion and a bunch of triangles.

The camera stays pointed toward the center of the triangles, which span a cube.

The motion takes us to a random point in the vicinity.

Press 'R' to regenerate the triangles.

By castironpi 4/13/2010.  No warranties.
'''
import sys
from panda3d.core import loadPrcFileData
loadPrcFileData("", "show-frame-rate-meter 1")

import direct.directbase.DirectStart
from panda3d.core import *
from direct.interval.IntervalGlobal import *
import random as ran

render.setTwoSided( True )
geomformat= GeomVertexFormat.getV3c4( )
vdata= GeomVertexData( 'blank', geomformat, Geom.UHStatic )
prim= GeomTriangles( Geom.UHStatic ) #hint
geom= Geom( vdata )
geom.addPrimitive( prim )

node= GeomNode( 'gnode' )
node.addGeom( geom )
gpath= NodePath( node )
gpath.reparentTo( render )

num_triags= 500
for j in range( num_triags ):
    prim.addConsecutiveVertices( j* 3, 3 )
    prim.closePrimitive()

def regen_triags( ):
    vertex= GeomVertexWriter( vdata, 'vertex' )
    color= GeomVertexWriter( vdata, 'color' )
    for j in range( num_triags ):
        p1= ran.uniform( -5, 5 ), ran.uniform( -5, 5 ), ran.uniform( -5, 5 )
        p2= [ x+ ran.uniform( 0, 1 ) for x in p1 ]
        p3= [ x+ ran.uniform( 0, 1 ) for x in p1 ]
        vertex.addData3f( *p1 )
        vertex.addData3f( *p2 )
        vertex.addData3f( *p3 )
        for _ in range( 3 ):
            r, g= ran.uniform( .5, 1 ), ran.uniform( .5, 1 )
            b= 2- r- g
            color.addData3f( r, g, b )

regen_triags( )

base.accept( 'escape', sys.exit )
base.accept( 'r', regen_triags )
base.accept( 'r-repeat', regen_triags )

base.cam.setPos( 0, -40, 0 )

def face( _ ):
    base.cam.lookAt( 0, 0, 0 )

def next( ):
    if ran.random( )< .2: # take us inside the cube 20% of the time
        p1= ran.uniform( -4, 4 ), ran.uniform( -4, 4 ), ran.uniform( -4, 4 )
    else:
        p1= ran.uniform( -20, 20 ), ran.uniform( -20, 20 ), ran.uniform( -20, 20 )
    i= LerpPosInterval( base.cam, ran.uniform( 3, 7 ), p1, blendType= 'easeInOut' )
    j= Func( next )
    k= Sequence( i, j )
    m= LerpFunc( face, duration= i.getDuration( ) )
    n= Parallel( k, m )
    n.start( ) # run 'face' at the same time as a ( LerpPos & Start-Next ) sequence.
next( )

run( )

nice snip - simple but effective

Patch 1!

Insert before ‘run( )’.

Adds a PointLight that wanders around the cube, with adjustment of parameters. I didn’t expect to need to reiterate the ambient light.

ambientLight = AmbientLight('ambientLight')
ambientLight.setColor(Vec4(0.8, 0.8, 0.8, 1))
ambientLightNP = render.attachNewNode(ambientLight)
render.setLight(ambientLightNP)

lightN= PointLight( 'pointLight' )
light= render.attachNewNode( lightN )
render.setLight( light )
lightN.setAttenuation( Point3( .1, .1, .1 ) )
def nextlight( ):
    p1= ran.uniform( -4, 4 ), ran.uniform( -4, 4 ), ran.uniform( -4, 4 )
    i= LerpPosInterval( light, ran.uniform( 1, 2 ), p1, blendType= 'easeInOut' )
    j= Func( nextlight )
    k= Sequence( i, j )
    k.start( )
nextlight( )

Here’s a variant on the camera motion. It just spins in place, at the center. I’m not happy with it; it’s not clever enough; and it can make the viewer dizzy.

base.cam.setPos( 0, 0, 0 )

def camnext( ):
	p1= ran.uniform( 0, 360 ), ran.uniform( 0, 360 ), ran.uniform( 0, 360 )
	i= LerpHprInterval( base.cam, ran.uniform( 20, 30 ), p1, blendType= 'easeInOut' )
	j= Func( camnext )
	k= Sequence( i, j )
	k.start( )
camnext( )

I’m not entirely satisfied with the original while I’m at it; it’s not clever enough.

Also, how does rotational interpolation work? Does it take the shortest distance or stay within the 0-360 range, and stay away from the Dedekind cut?

(While I’ve brought up the topic, how would you interpolate HSL coordinates, since H is circular/modular?)

As I suggested in:

discourse.panda3d.org/viewtopic … highlight=

I want the camera to have uniform velocity along the surface of the sphere. That is, the arclength between the lookAt vector at unit distance between any two pairs of frames should be equal; or especially under my control. I will want other constraints such as random waypoints capped by a maximum curvature.

I’d also like the camera position to follow a 3-D spline such as a Bezier curve, also with the curvature constraint but only with rectangular bounds instead of spherical. It should also be an indefinitely long curve / spline.

Lastly, I’d like to avoid the camera facing outwards in the cube when its position is near the edge, but it should not be limited to always facing inward; at least there should be some variability in the view ray such that it doesn’t always pass through the direct center, but does keep many or most of the volume of the cube in view (in frustum).