# Soya 3D tutorial, made into a bouncing ball demo. 
# Copyright (C) 2004, 2005 Jean-Baptiste LAMY, Piotr Mitros
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA


import sys, os, os.path, random, soya, soya.sphere, random

soya.init()
soya.path.append(os.path.join(os.path.dirname(sys.argv[0]), "data"))

scene = soya.World()


class Head(soya.Volume):
  def __init__(self, parent, ispeed):
    material = soya.Material()
    material.shininess = random.random()*128
    material.diffuse = (random.random(), random.random(),
                        random.random(), random.random())
    material.specular  = (random.random(), random.random(),
                          random.random(), random.random())
    material.separate_specular = 1

    ball_world=soya.sphere.Sphere(material=material)
    soya.Volume.__init__(self, parent,ball_world.shapify())
                         #soya.Shape.get("caterpillar_head"))
                         
    self.maxspeed=ispeed
    self.speed = soya.Vector(self, 0.0, 0.0, ispeed)

# We intentionally simulate the physics, instead of having a parabola with
# time, and so accumulate floating point errors. 
  def begin_round(self):
    soya.Volume.begin_round(self)
    self.speed.z=self.speed.z+.01;
    if self.speed.z>-self.maxspeed:
      self.speed.z=self.maxspeed
  
  def advance_time(self, proportion):
    soya.Volume.advance_time(self, proportion)
    self.add_mul_vector(proportion, self.speed)


# Creates a Head in the scene.

head1 = Head(scene, -0.5)
head1.set_xyz(0,0,0)

for i in range(1,10):
  head2 = Head(scene, -random.random()*.5-.1)
  head2.set_xyz((random.random()-0.5)*10,i,5)

for i in range(1,10):
  head2 = Head(scene, -random.random()*.5-.1)
  head2.set_xyz((random.random()-0.5)*10,i,5)



# Creates a light.

light = soya.Light(scene)
light.set_xyz(2.0, 5.0, 0.0)

# Creates a camera.

camera = soya.Camera(scene)
soya.set_root_widget(camera)
camera.set_xyz(0.0, 15.0, 15.0)

# Makes the camera looking at the head's initial position.
# The look_at method is another rotation method ; it makes any 3D object looking toward
# the given position (a 3D object or a Point), or in the given direction (if the argument
# is a Vector).

camera.set_xyz(0,20,5)
camera.look_at(head1)

soya.Idler(scene).idle()
