#!BPY

"""
Name: 'SaltShaker'
Blender: 248
Group: 'Add'
Tooltip: 'Create Random Location/Scale/Rotation'
"""

__author__ = "Rednuht "
__url__ = ("http://wiki.blender.org/index.php/Extensions:Py/Scripts/Manual/Add/Saltshaker")
__version__ = "248"

__bpydoc__ = """\
This script creates random movement or shaking of objects
Usage:

Select one or many objects to shake.

You can set Ipo keys after each shake for animations.

Open it from Add Menu
"""
# ***** BEGIN GPL LICENSE BLOCK ***** 
# Salt Shaker 1.4.1 Copyright Rednuht 2008
#
# 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. 
# 
# ***** END GPL LICENCE BLOCK ***** 
#
# -------------------------------------------------------------------------- 
##########################################################
#                                                        #
# Salt Shaker 1.4.1                                      #
#                                                        #
# Author : Rednuht                                       #
# Creation Date : Jan 2005                               #
# Home :                                                 #
#  http://saltshaker.sf.net                              #
#                                                        #
# Description : Takes all selected meshes and 'shakes'   #
# them, moving and tilting them a random amount.         #
# Mostly a bit of fun, usfull example for others.        #
#                                                        #
# 12/12/2006 removed reference to whrandom as it is not  #
# standard with blender (replaced with blender.noise)    #
#                  										 #
# 11/11/2007 force local variable pr to initialise to 0  #
# to avoid strict checking. Found by naruto canada       #
#                                      					 #
##########################################################
#GUI Created using RipSting's Blender-Python GUI designer#
#Download at Http://oregonstate.edu/~dennisa/Blender/BPG/#
##########################################################
#                                                        #
# WARNING BPG is Windows ONLY !! cry now for your soul   #
#                                                        #
# I also found that fair amount of tweaking was required #
# to get the result I required, but I can not complain,  #
# it got me this far !                                   #
#                                                        #
# Note: this script was mainly created in Linux, just the#
# GUI was born from windows.                             #
##########################################################

import Blender
from Blender.BGL import *
from Blender.Draw import *
from Blender.Noise import *


SlidermoveZ = Create(0)
SlidertiltZ = Create(0)
SlidermoveY = Create(0)
SlidertiltY = Create(0)
SlidermoveX = Create(0)
SlidertiltX = Create(0)
Menupreset = Create(1)

ss_ver='1.4.1'


def shakeit():
	objList = Blender.Object.GetSelected()
	#objBounds[]
	for obj in objList :
		mesh = obj.getData()
		#print mesh.name
		# check its a mesh before manipulating it.
		if obj.getType() == 'Mesh':
			# rotate in the three planes
			# note the 1.5 here as the first parameter is the equivilant to 90 degrees (it gets halfed to 45 degrees later)
			obj.RotX = obj.RotX + rotateit(1.5,SlidertiltX.val)
			obj.RotY = obj.RotY + rotateit(1.5,SlidertiltY.val)
			obj.RotZ = obj.RotZ + rotateit(1.5,SlidertiltZ.val)
			# move in the three planes (using mesh dimensions as reference)
			# get bounding box coords (list of eight items)
			objBounds = obj.getBoundBox()
			getDimensions(objBounds)
			dimX = (maxX-minX)
			dimY = (maxY-minY)
			dimZ = (maxZ-minZ)
			obj.LocX = obj.LocX + moveit(dimX,SlidermoveX.val)
			obj.LocY = obj.LocY + moveit(dimY,SlidermoveY.val)
			obj.LocZ = obj.LocZ + moveit(dimZ,SlidermoveZ.val)
	Blender.Redraw()


def moveit(overall,perc):
	pr=0
	if (overall > 0):
		singlepercent = (overall / 100)
		maxmove = (singlepercent * perc) / 2
		pr = (Blender.Noise.random()*maxmove)
	# 50% of the time make it negitive
	if (Blender.Noise.random()<=0.5):
		pr = pr-(pr*2)
	if (perc == 0) or (overall == 0):
		pr=0
	return(pr)
	
	
def getDimensions(vL):
	global minX,minY,minZ,maxX,maxY,maxZ
	pr=0
	# reset values, I missed this as I restarted the script so often, the min and max values became cumlative, very odd results, shows what sort of a bad programmer I am.
	minX = 0
	minY = 0
	minZ = 0
	maxX = 0 
	maxY = 0
	maxZ = 0
	for vect in vL :
		if (vect[0] < minX) or (minX == 0) :
			minX = vect[0]
		if (vect[1] < minY) or (minY == 0) :
			minY = vect[1]
		if (vect[2] < minZ) or (minZ == 0) :
			minZ = vect[2]
		if (vect[0] > maxX) or (maxX == 0) :
			maxX = vect[0]
		if (vect[1] > maxY) or (maxY == 0) :
			maxY = vect[1]
		if (vect[2] > maxZ) or (maxZ == 0) :
			maxZ = vect[2]


def rotateit(overall,perc):
	pr=0
	# I might upgrade this
	singlepercent = (overall / 100)
	maxrotate = (singlepercent * perc) / 2
	pr = (Blender.Noise.random()*maxrotate)
	# 50% of the time make it negitive
	if (Blender.Noise.random()<=0.5):
		pr = pr-(pr*2)
	if (perc == 0):
		pr=0
	return(pr)


def draw():
	global Button3, Button2, Button1, SlidermoveZ, SlidertiltZ, SlidermoveY, SlidertiltY, SlidermoveX, SlidertiltX, Menupreset, ypos, sliderwidth

	glClearColor(0.753, 0.753, 0.753, 0.0)
	glClear(GL_COLOR_BUFFER_BIT)

	ypos=5;
	glColor3f(0.000, 0.000, 0.000)
	glRasterPos2i(0, ypos)
	Text('GUI Created using RipStings BPG Http://oregonstate.edu/~dennisa/Blender/BPG/')
	ypos=ypos+20
	glColor3f(0.000, 0.000, 1.000)
	glRasterPos2i(0, ypos)
	Text('Script homed at http://www.jumpstation.co.uk/blend/scripts/saltshaker/')
	ypos=ypos+20
	glColor3f(0.000, 0.000, 1.000)
	glRasterPos2i(0, ypos)
	Text('Shake all the selected meshes, try it you might like it !')
	ypos=ypos+20


	Button('Exit', 1, 106, ypos, 39, 15, 'Exit script')
	Button('Undo', 2, 58, ypos, 39, 15, 'Reset mesh objects if shake performed')
	Button('Shake', 3, 0, ypos, 49, 15, 'Shake it Baby')
	ypos=ypos+20

	sliderwidth=170

	SlidermoveZ = Slider('Move Z% ', 5, sliderwidth+5, ypos, sliderwidth, 15, SlidermoveZ.val, 0, 100, 0, 'Movement percentage')
	SlidertiltZ = Slider('Tilt Z% ', 6, 0, ypos, sliderwidth, 15, SlidertiltZ.val, 0, 100, 0, 'Tilt Percentage')
	ypos=ypos+20
	SlidermoveY = Slider('Move Y% ', 7, sliderwidth+5, ypos, sliderwidth, 15, SlidermoveY.val, 0, 100, 0, 'Movement percentage')
	SlidertiltY = Slider('Tilt Y% ', 8, 0, ypos, sliderwidth, 15, SlidertiltY.val, 0, 100, 0, 'Tilt Percentage')
	ypos=ypos+20
	SlidermoveX = Slider('Move X% ', 9, sliderwidth+5, ypos, sliderwidth, 15, SlidermoveX.val, 0, 100, 0, 'Movement percentage')
	SlidertiltX = Slider('Tilt X% ', 10, 0, ypos, sliderwidth, 15, SlidertiltX.val, 0, 100, 0, 'Tilt Percentage')
	ypos=ypos+20

	Menupreset = Menu('Pesets%t|None %x1|Minor Tremor %x2|Tremor %x3|Earth Quake %x4|End of the World %x5', 4, 0, ypos, 131, 15, Menupreset.val, 'Preset settings')

	ypos=ypos+20
	glColor3f(0.000, 0.000, 0.000)
	glRasterPos2i(0, ypos)
	Text('Salt Shaker v'+ss_ver)

def event(evt, val):
	if (evt== QKEY and not val): Exit()
def bevent(evt):
	if evt == 1: #Button1
		Exit()

	elif evt == 2: #Button2
		InsertCodeHere = 1

	elif evt == 3: #Button3
		shakeit()

	elif evt == 4: #Menupreset
		if Menupreset.val == 2: #Minor Tremor
			SlidertiltX.val=10
			SlidertiltY.val=10
			SlidertiltZ.val=10
			SlidermoveX.val=10
			SlidermoveY.val=10
			SlidermoveZ.val=10
		elif Menupreset.val == 3: #Tremor
			SlidertiltX.val=30
			SlidertiltY.val=30
			SlidertiltZ.val=30
			SlidermoveX.val=30
			SlidermoveY.val=30
			SlidermoveZ.val=30
		elif Menupreset.val == 4: #Earth quake
			SlidertiltX.val=60
			SlidertiltY.val=60
			SlidertiltZ.val=60
			SlidermoveX.val=60
			SlidermoveY.val=60
			SlidermoveZ.val=60
		elif Menupreset.val == 5: #End of the World
			SlidertiltX.val=100
			SlidertiltY.val=100
			SlidertiltZ.val=100
			SlidermoveX.val=100
			SlidermoveY.val=100
			SlidermoveZ.val=100
		elif Menupreset.val == 1: #None
			SlidertiltX.val=0
			SlidertiltY.val=0
			SlidertiltZ.val=0
			SlidermoveX.val=0
			SlidermoveY.val=0
			SlidermoveZ.val=0


	Blender.Redraw()
	Blender.Noise.setRandomSeed(0)

Register(draw, event, bevent)
