#-----------------------------------------------------------------------
#                   Primitive tsxPython sample script
#                            Animate a roulette
# 
# $Id: 030_roulette_anim1b.py 79 2019-04-24 20:12:52Z 3DfromNULL $
#-----------------------------------------------------------------------
import ptsxpy as p
import ptsxgp
import math

#org = Vec3f( 0., 0., 0. )
#z_axis = Vec3f( 0., 0., 1. )
wk1 = ptsxgp.alloc_long( 1 )
cogwk1 = ptsxgp.alloc_float( 3 )

ret = p.GNodeFindByName( wk1, 0, "Roulette" )
print( "ret=", ret )
if ret == 0:
    whole = ptsxgp.loadptr( wk1 )
else:
    whole = 0

#----------
# Get the bowl
#----------
ret = p.GNodeFindByName( wk1, whole, "Stationary" )
print( "ret=", ret )
ob2 = ptsxgp.loadptr( wk1 )
ret = p.GNodeFindByName( wk1, ob2, "Bowl" )
print( "ret=", ret )
bowl = ptsxgp.loadptr( wk1 )

#----------
# Initialize ball
#----------
sz1 = Vec3f()
p.GNodeGetSize( bowl, sz1.p )
r_bowl = sz1.x() / 2.
h_bowl = sz1.z()
r_ball = 0.025 * r_bowl
print( "r_bowl=", r_bowl, ", h_bowl=", h_bowl, ", r_ball=", r_ball )
# Check whether a ball exists or not
ret = p.GNodeFindByName( wk1, 0, "Ball" )
# if ball already exists
if ret == 0:
    ball = ptsxgp.loadptr( wk1 )
else:
    ball = p.CreateSphere( 64, 64, r_ball )
    p.SceneAddObject( ball, false )
    p.GNodeSetName( ball, "Ball" )
loc1 = Vec3f( 0., 0.999 * ( r_bowl - r_ball ), h_bowl + r_ball )
p.GNodeSetLocation( ball, loc1.p )


# Unglue the rotor from the whole
ret = p.GNodeFindByName( wk1, whole, "Rotor" )
print( "ret=", ret )
rotor = ptsxgp.loadptr( wk1 )
p.SelectSobj( rotor, e_tsxSELECT, false )
p.GroupRemoveCurrobj()
p.PhysSimAddDefaultProperties( rotor )
# PhysSimSetFixationPoints() can be used for tS6.0 or later.
if tscode >= 65:
    loc1 = Vec3f( 0., 0.,  5. )
    loc2 = Vec3f( 0., 0., -2. )
    loc3 = Vec3f( 0., 0.,  0. ) # this is ignored when 5th parameter is 2 but needed because 12 bytes of memory area pointed by this is passed to the function.
    ret = p.PhysSimSetFixationPoints( rotor, loc1.p, loc2.p, loc3.p, 2 )
    print( "ret=", ret )
else:
    ptsxgp.msgbox_excl( "Note 1", "You should manually add two fixation points to the rotor for older tS than 6.5. Each of two points should be on the z-axis (of the rotor)." )

# Rotor's property
org1 = Vec3f( 0., 1., 0. )
vec1 = Vec3f( -6., 0., 0. )
p.PhysSimSetInitialRotationVector( rotor, org1.p, vec1.p )

p.PhysSimSetWeight( rotor, PHYSSIM_WEIGHT_IRON )
wt = p.PhysSimGetWeight( rotor )
vol = wt / PHYSSIM_WEIGHT_IRON
print( "wt=", wt )
print( "vol=", vol )
p.PhysSimSetWeight( rotor, 1000. / vol ) # must specify density
wt = p.PhysSimGetWeight( rotor )
print( "wt=", wt )

p.PhysSimSetFriction( rotor, 0.001 )
el = p.PhysSimGetElasticity( rotor )
print( "el=", el )
p.PhysSimSetElasticity( rotor, 0.05 )

el = p.PhysSimGetResistance( rotor )
print( "re=", el )
p.PhysSimSetResistance( rotor, 0.1 )
el = p.PhysSimGetResistance( rotor )
print( "re=", el )


# Ball's property
vec1 = Vec3f( 20., -0.01, 0. )
p.PhysSimSetInitialMotionVector( ball, vec1.p )

p.PhysSimSetWeight( ball, PHYSSIM_WEIGHT_IRON )
wt = p.PhysSimGetWeight( ball )
vol = wt / PHYSSIM_WEIGHT_IRON
print( "wt=", wt )
p.PhysSimSetWeight( ball, 30. / vol )
wt = p.PhysSimGetWeight( ball )
print( "wt=", wt )

p.PhysSimSetFriction( ball, 0.3 )
el = p.PhysSimGetElasticity( ball )
print( "el=", el )
p.PhysSimSetElasticity( ball, 0.05 )
el = p.PhysSimGetElasticity( ball )
print( "el=", el )

if tscode >= 65:
    co = p.PhysSimGetCoarseness( ball )
    print( "co=", co )
    p.PhysSimSetCoarseness( ball, 0.088 )
    print( "co=", co )
else:
    ptsxgp.msgbox_excl( "Note 2", "This script automatically changes coarseness of the created ball for tS6.5 or higher." )


######
#cb1 = p.CreateCube( 1, 2., 2., 2. )
#p.SceneAddObject( cb1, false )
#loc1 = Vec3f( 7., 7., 0. )
#p.GNodeSetLocation( cb1, loc1.p )
#p.PhysSimSetWeight( cb1, PHYSSIM_WEIGHT_IRON )
#wt = p.PhysSimGetWeight( cb1 )
#print( "wt=", wt )
#vol = wt / PHYSSIM_WEIGHT_IRON
#print( "vol=", vol )
#p.PhysSimSetWeight( cb1, 10. / vol )
#wt = p.PhysSimGetWeight( cb1 )
#print( "wt=", wt )
#####

#----------
# Ending
#----------
p.Free( wk1 )
p.Free( cogwk1 )
p.SceneDraw()

print( "Tips: You can click \"Start simulation\" button. It will take very long time, compute and make a physical simulation. Before click it, you should adjust the simulation time, the number of simulation steps for one frame, the gravitational acceleration, the properties of the rotor and a created ball. To get results you want, you may adjust initial rotation/linear speeds of rotor and ball. You don't have to redo the physical simulation after you changed these speeds, and can get the result by \"Play\" button. But please note that you should rewind animation (using \"Return to start\" button) before you change these values, colors, locations, rotations, sizes. Otherwise (i.e. changing values at time non-zero) you will get a property-changing-animation." )


