#-------------------------------------------------------------
#   Primitive tsxPython sample script for trueSpace series
#                   Collision detection 1
# 
# $Id: light1e.py 46 2019-03-20 16:47:52Z 3DfromNULL $
#-------------------------------------------------------------

import ptsxpy as p
from math import *

pi_half = pi / 2.
x_axis = Vec3f( 1., 0., 0. )
y_axis = Vec3f( 0., 1., 0. )
z_axis = Vec3f( 0., 0., 1. )


wk1 = ptsxgp.alloc_long( 100 )

p.SceneGetShaderName( tsxSHCLASS_FOREGROUND, wk1 )
s1 = String_p( wk1 ).get()
print( "s1=", s1 )
if s1 == "none":
    ptsxgp.msgbox_excl( "error", "Select \"Simple Volumetric\" from \"Foreground Effect Shader\" before start this script." )
    exit()

nparam = p.SceneGetShaderParametersNumber( tsxSHCLASS_FOREGROUND )
print( "nparam=", nparam )

fgcls = tsxSHCLASS_FOREGROUND
wk1 = ptsxgp.alloc_long( 100 )
for i in range( nparam ):
    p.SceneGetShaderParameterName( fgcls, i, wk1 )
    s1 = String_p( wk1 ).get()
    ty1 = p.SceneGetShaderParameterType( fgcls, i )
    p.SceneGetShaderParameterTypedValue( fgcls, i, ty1, wk1 )
    if   ty1 == tsxSHPARAM_FLOAT:
        val = ptsxgp.loadfloat( wk1 )
    elif ty1 == tsxSHPARAM_LONG  or \
         ty1 == tsxSHPARAM_BOOL:
        val = ptsxgp.loadlong( wk1 )
    elif ty1 == tsxSHPARAM_STRING:
        val = ptsxgp.loadstr( wk1 )
    else:
        ptsxgp.msgbox_excl( "error", "This script doen not support the parameter type" + str( ty1 ) )
        exit()
    print( "i=%2d, ty1=%2d, s1=[%s], val=[%s]" % ( i, ty1, s1, str( val ) ) )
    if s1 == "fog density":
        ptsxgp.storefloat( wk1, 0.25 )
        p.SceneSetShaderParameterValue( fgcls, i, wk1 )
    if s1 == "samples":
        ptsxgp.storelong( wk1, 47 )
        p.SceneSetShaderParameterValue( fgcls, i, wk1 )
    if s1 == "noise amplitude":
        ptsxgp.storefloat( wk1, 12.82 )
        p.SceneSetShaderParameterValue( fgcls, i, wk1 )
    if s1 == "noise scale":
        ptsxgp.storefloat( wk1, 0.04 )
        p.SceneSetShaderParameterValue( fgcls, i, wk1 )
    if s1 == "noise gain":
        ptsxgp.storefloat( wk1, 0.9 )
        p.SceneSetShaderParameterValue( fgcls, i, wk1 )
    if s1 == "source attenuation":
        ptsxgp.storefloat( wk1, 0.0 )
        p.SceneSetShaderParameterValue( fgcls, i, wk1 )
    if s1 == "surface attenuation":
        ptsxgp.storefloat( wk1, 0.24 )
        p.SceneSetShaderParameterValue( fgcls, i, wk1 )
    if s1 == "volume attenuation":
        ptsxgp.storefloat( wk1, 4.0 )
        p.SceneSetShaderParameterValue( fgcls, i, wk1 )


#------------
# Create a keyframe
tm = 0.0
p.AnimSetActiveTime( tm )

# Create a spot light
print( "e_tsxLT_SPOT=", e_tsxLT_SPOT )
p.LightCreateInScene( e_tsxLT_SPOT )
lt1 = p.GetCurrentSelection()
print( "lt1=", lt1 )
p.SceneAddObject( lt1, e_tsxFALSE )
# Set name of the light for later use because GNodeCopy() for group object does not copy the parameters of light.
p.GNodeSetName( lt1, "lt" )
foff = p.LightSetFalloff( lt1, e_tsxLF_SQUARED )
print( "foff=", foff )
p.LightSetShadType( lt1, e_tsxLS_RAYTRACE )
foc = p.LightGetFalloffCoeff( lt1 )
print( "foc=", foc )
p.LightSetVolumetric( lt1, e_tsxTRUE )
# Set location and rotation
org = Vec3f( 0., 0., 0. )
loc1 = Vec3f( 0., -0.6, 0. )
p.GNodeSetLocation( lt1, loc1.p )
p.GNodeRotate( lt1, org.p, x_axis.p, 3 * pi_half, e_tsxModelFrame )
# Add an object and group with the light
loc2 = Vec3f( 0., 0., 0. )
print( "loc2=", loc2.prt() )
cb1 = p.CreateCube( 1, 1., 1., 1. )
p.SceneAddObject( cb1, e_tsxFALSE )
# Group them
p.GNodeSetLocation( cb1, loc2.p )
p.SelectSobj( cb1, e_tsxSELECT, e_tsxTRUE )
g1 = p.GroupNewWithCurrobj( lt1 )

p.SceneDraw()

cols = (
  #Color( 0xff, 0x00, 0x00, 100 ),  # red
  #Color( 0xff, 0xff, 0x00, 100 ),  # yellow
  #Color( 0x00, 0xff, 0x00, 100 ),  # green
  #Color( 0x00, 0xff, 0xff, 100 ),  # light brue
  #Color( 0x00, 0x00, 0xff, 100 ),  # blue
  #Color( 0xff, 0x00, 0xff, 100 )   # purple
  #Color( 0x00, 0xff, 0x00, 100 ),  # green
  #Color( 0x00, 0xee, 0x11, 100 ),
  #Color( 0x00, 0xdd, 0x22, 100 ),
  #Color( 0x00, 0xcc, 0x33, 100 ),
  #Color( 0x00, 0xbb, 0x44, 100 ),
  #Color( 0x00, 0xaa, 0x55, 100 ),
  #Color( 0x00, 0x99, 0x66, 100 ),
  #Color( 0x00, 0x88, 0x77, 100 ),
  #Color( 0x00, 0x77, 0x88, 100 ),
  #Color( 0x00, 0x66, 0x99, 100 ),
  #Color( 0x00, 0x55, 0xaa, 100 ),
  #Color( 0x00, 0x44, 0xbb, 100 ),
  #Color( 0x00, 0x33, 0xcc, 100 ),
  #Color( 0x00, 0x22, 0xdd, 100 ),
  #Color( 0x00, 0x11, 0xee, 100 ),
  #Color( 0x00, 0x00, 0xff, 100 ),  # blue
  Color( 0xff, 0x00, 0x00, 100 ),  # red
  Color( 0xff, 0x55, 0x00, 100 ),  #
  Color( 0xff, 0xaa, 0x00, 100 ),  #
  Color( 0xff, 0xff, 0x00, 100 ),  # yellow
  Color( 0xaa, 0xff, 0x00, 100 ),  #
  Color( 0x55, 0xff, 0x00, 100 ),  #
  Color( 0x00, 0xff, 0x00, 100 ),  # green
  Color( 0x00, 0xff, 0x55, 100 ),  #
  Color( 0x00, 0xff, 0xaa, 100 ),  #
  Color( 0x00, 0xff, 0xff, 100 ),  # light brue
  Color( 0x00, 0xaa, 0xff, 100 ),  #
  Color( 0x00, 0x55, 0xff, 100 ),  #
  Color( 0x00, 0x00, 0xff, 100 ),  # blue
  Color( 0x55, 0x00, 0xff, 100 ),  #
  Color( 0xaa, 0x00, 0xff, 100 ),  #
  Color( 0xff, 0x00, 0xff, 100 ),  # purple
  Color( 0xff, 0x00, 0xaa, 100 ),  #
  Color( 0xff, 0x00, 0x55, 100 ),  #
)
n = len( cols )
col2 = Color( 0xff, 0x66, 0x00, 100 )  # orange

objs = [ g1 ]
wkp = LongArray( 1 )
for i in range( n - 1 ):
    p.GNodeCopy( g1, wkp.p )
    g2 = ptsxgp.loadptr( wkp.p )
    p.SceneAddObject( g2, e_tsxFALSE )
    objs.append( g2 )

# Set parameters of the light in each group object because GNodeCopy() does not copy them.
wk1 = ptsxgp.alloc_long( 1 )
lts = []
for i in range( n ):
    lt = p.GNodeFindByName( wk1, objs[ i ], "lt" )
    lt1 = ptsxgp.loadptr( wk1 ) 
    p.LightSetSpotAngle( lt1, pi / 12. )
    p.LightSetColor( lt1, cols[ i ].p )
    lts.append( lt1 )
p.Free( wk1 )

for i in range( n ):
    p.SobjSetFrame( objs[ i ], e_tsxKFT_MOVE )
    p.SobjSetFrame( objs[ i ], e_tsxKFT_ROTATE )
    p.SobjSetFrame( lts[ i ], e_tsxKFT_LCOLOR )
    p.SobjSetFrame( lts[ i ], e_tsxKFT_SCALE )

#------------
# Create a keyframe
tm = tm + 60
p.AnimSetActiveTime( tm )
# Move
for i in range( n ):
    loc1 = Vec3f( 4 * ( ( n - 1 ) / 2. - i ), 0., 0. )
    p.GNodeSetLocation( objs[ i ], loc1.p )
    p.SobjSetFrame( objs[ i ], e_tsxKFT_MOVE )
    p.SobjSetFrame( objs[ i ], e_tsxKFT_ROTATE )
    p.SobjSetFrame( lts[ i ], e_tsxKFT_LCOLOR )
    p.SobjSetFrame( lts[ i ], e_tsxKFT_SCALE )

for k in range( -1, 3, 2 ):
    for j in range( n ):
        #------------
        # Create a keyframe
        tm = tm + 5
        p.AnimSetActiveTime( tm )
        # Change color
        for i in range( n ):
            p.LightSetColor( lts[ i ], cols[ ( i + k * ( j + 1 ) ) % n ].p )
            p.SobjSetFrame( objs[ i ], e_tsxKFT_MOVE )
            p.SobjSetFrame( objs[ i ], e_tsxKFT_ROTATE )
            p.SobjSetFrame( lts[ i ], e_tsxKFT_LCOLOR )
            p.SobjSetFrame( lts[ i ], e_tsxKFT_SCALE )

for j in range( 2 ):
    #------------
    # Create a keyframe
    tm = tm + 15
    p.AnimSetActiveTime( tm )
    # Move
    loc1 = Vec3f( 0., 0., 0. )
    for i in range( n ):
        loc1.set_y( 5. if ( j + i ) % 2 == 0 else -5. )
        p.GNodeTranslate( objs[ i ], loc1.p, e_tsxWorldFrame )
        p.SobjSetFrame( objs[ i ], e_tsxKFT_MOVE )
        p.SobjSetFrame( objs[ i ], e_tsxKFT_ROTATE )
        p.SobjSetFrame( lts[ i ], e_tsxKFT_LCOLOR )
        p.SobjSetFrame( lts[ i ], e_tsxKFT_SCALE )

#------------
# Create a keyframe
tm = tm + 120
p.AnimSetActiveTime( tm )
# Rotate
loc1 = Vec3f()
for i in range( int( n / 2 ) ):
    p.GNodeGetLocation( objs[ i ], loc1.p )
    p.GNodeRotate( objs[ i ], loc1.p, z_axis.p, -pi_half, e_tsxModelFrame )
    loc1 = Vec3f( 5., -4. * ( i + 1 ), 0. )
    p.GNodeSetLocation( objs[ i ], loc1.p )

loc1 = Vec3f( 5., 0., 0, )
for i in range( int( n / 2 ), n ):
    p.GNodeTranslate( objs[ i ], loc1.p, e_tsxWorldFrame )

for i in range( n ):
    p.SobjSetFrame( objs[ i ], e_tsxKFT_MOVE )
    p.SobjSetFrame( objs[ i ], e_tsxKFT_ROTATE )
    p.SobjSetFrame( lts[ i ], e_tsxKFT_LCOLOR )
    p.SobjSetFrame( lts[ i ], e_tsxKFT_SCALE )

#------------
# Create a keyframe
tm = tm + 30
p.AnimSetActiveTime( tm )
# Change color
for i in range( n ):
    p.LightSetColor( lts[ i ], col2.p )
    p.SobjSetFrame( lts[ i ], e_tsxKFT_LCOLOR )
    p.SobjSetFrame( lts[ i ], e_tsxKFT_SCALE )

#------------
# Create a keyframe
tm = tm + 30
p.AnimSetActiveTime( tm )
# Change color
for i in range( n ):
    p.SobjSetFrame( lts[ i ], e_tsxKFT_LCOLOR )
    p.SobjSetFrame( lts[ i ], e_tsxKFT_SCALE )


#------------
# Create a keyframe
tm = tm + 60
p.AnimSetActiveTime( tm )
# Move
loc1 = Vec3f( 40., 0., 0. )
for i in range( int( n / 2 ) ):
    p.GNodeTranslate( objs[ i ], loc1.p, e_tsxWorldFrame )

loc1 = Vec3f( 0., 40., 0. )
for i in range( int( n / 2 ), n ):
    p.GNodeTranslate( objs[ i ], loc1.p, e_tsxWorldFrame )

for i in range( n ):
    p.SobjSetFrame( objs[ i ], e_tsxKFT_MOVE )
    p.SobjSetFrame( objs[ i ], e_tsxKFT_ROTATE )

p.SceneDraw()

