#-
# ==========================================================================
# Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All 
# rights reserved.
#
# The coded instructions, statements, computer programs, and/or related 
# material (collectively the "Data") in these files contain unpublished 
# information proprietary to Autodesk, Inc. ("Autodesk") and/or its 
# licensors, which is protected by U.S. and Canadian federal copyright 
# law and by international treaties.
#
# The Data is provided for use exclusively by You. You have the right 
# to use, modify, and incorporate this Data into other products for 
# purposes authorized by the Autodesk software license agreement, 
# without fee.
#
# The copyright notices in the Software and this entire statement, 
# including the above license grant, this restriction and the 
# following disclaimer, must be included in all copies of the 
# Software, in whole or in part, and all derivative works of 
# the Software, unless such copies or derivative works are solely 
# in the form of machine-executable object code generated by a 
# source language processor.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. 
# AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED 
# WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF 
# NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 
# PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR 
# TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS 
# BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, 
# DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK 
# AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY 
# OR PROBABILITY OF SUCH DAMAGES.
#
# ==========================================================================
#+

import maya.OpenMaya as OpenMaya

# 
# simple plane math class
#
class planeMath:
	a = None
	b = None
	c = None
	d = None

	def __init__(self):
		a = 0
		b = 0
		c = 0
		d = 0

	def setPlane(self,pointOnPlane,normalToPlane):
		_normalToPlane = normalToPlane
		_normalToPlane.normalize()

		# Calculate a,b,c,d based on input
		self.a = _normalToPlane.x
		self.b = _normalToPlane.y
		self.c = _normalToPlane.z
		self.d = -(self.a*pointOnPlane.x + self.b*pointOnPlane.y + self.c*pointOnPlane.z)

	def intersect(self,linePoint,lineDirection):
		intersectionPoint = OpenMaya.MPoint()
		denominator = self.a*lineDirection.x + self.b*lineDirection.y + self.c*lineDirection.z
		# Verify that the vector and the plane are not parallel.
		if denominator < .00001:
			return (False,intersectionPoint)

		t = -(self.d + self.a*linePoint.x + self.b*linePoint.y + self.c*linePoint.z) / denominator

		# Calculate the intersection point.
		scaledLineDirection = OpenMaya.MVector(lineDirection.x*t,lineDirection.y*t,lineDirection.z*t)
		intersectionPoint = linePoint + scaledLineDirection

		return (True,intersectionPoint)


#
# simple line math class
#
class lineMath:

	point = None
	direction = None

	def setLine(self,linePoint,lineDirection):
		self.point = linePoint
		self.direction = lineDirection
		self.direction.normalize()
			
	def closestPoint(self,toPoint):
		t = self.direction * ( toPoint - self.point )
		closest = self.point + ( self.direction * t )
		return (True,closest)
		

#
# simple degree radian converted
class degreeRadianConverter:
	M_PI = 3.14159265358979323846
	def degreesToRadians(self,degrees):
		return degrees * ( self.M_PI / 180.0 )
	def radiansToDegrees(self,radians):
		return radians * ( 180.0  / self.M_PI)

#
# utility function to return the
# value which has the max abs
# -10,3,4 returns -10
def maxOfAbsThree(a,b,c):
	aa = abs(a)
	ab = abs(b)
	ac = abs(c)
	if aa > ab and aa > ac:
		return a
	if ab > aa and ab > ac:
		return b
	return c

#
# tests for the math classes
#
def testModule():
	# degreeRadianConverter
	drc = degreeRadianConverter()
	r = drc.degreesToRadians( 45 )
	print r, " ", r*4

	d = drc.radiansToDegrees( drc.M_PI/4.0 )
	print d

	# lineMath
	lm = lineMath()
	point = OpenMaya.MPoint(0,1,0)
	direction = OpenMaya.MVector( 1,1,0)
	lm.setLine( point, direction )
	toPoint = OpenMaya.MPoint(3,0,0)
	(worked,closestPoint) = lm.closestPoint(toPoint)
	if worked:
		print "closest point to line: %g %g %g" % (closestPoint.x,closestPoint.y,closestPoint.z)
	else:
		print "Failed to find closest point to line"

#
# invoke test if  run from the 
# command line
#
if __name__ == "__main__":
	testModule()



