--***************************************************
--* QUATERNION
--***************************************************
--*
--* \file Quaternion.ls
--* \brief Quaternion class, new data type.
--* \author Maltus
--* \version 1.1
--* \date 05/05/2009
--* \email --
--* \todo comment...
--*
--***************************************************
--* CONSTRUCTOR
--***************************************************
--*
--* <Quaternion> = script( <String> ).new() -- default
--* <Quaternion> = script( <String> ).new( <List> ) -- <List> = <LinearList> / <PropList> / <AxisAngle>
--* <Quaternion> = script( <String> ).new( <Transform> )
--* <Quaternion> = script( <String> ).new( <Vector> )
--* <Quaternion> = script( <String> ).new( <Quaternion> ) -- copy
--*
--***************************************************
--* PUBLIC METHODS
--***************************************************
--*
--* <Symbol> = <Quaternion>.ilk() / ilk( <Quaternion> )
--* <Boolean> = ilk( <Quaternion>, <Symbol> )
--*
--* Predicate:
--* <Boolean> = quaternionP( <Quaternion> )
--*
--* Operator: direct access (.x, .y, .z, .w) and bracket access ([])
--* <Float> = getAt( <Integer> / <Symbol> / <String> )
--* <Float> = setAt( <Integer> / <Symbol> / <String>, <Number> )
--*
--* <Void> = invert()
--* <Void> = oppose()
--* <Void> = normalize()
--* <Void> = identity()
--*
--* <Quaternion> = duplicate()
--* <Quaternion> = getInversed()
--* <Quaternion> = getOpposed()
--* <Quaternion> = getNormalized()
--*
--* <Quaternion> = multiply( <Quaternion> / <Transform> / <List> / <Vector> / <Number> )
--* <Quaternion> = add( <Quaternion> / <Transform> / <List> / <Vector> / <Number> )
--* <Quaternion> = subtract( <Quaternion> / <Transform> / <List> / <Vector> / <Number> )
--*
--* <Boolean> = isEqualTo( <Quaternion> )
--* <Boolean> = isIdentity()
--* <Boolean> = isNormalized()
--*
--* <Float> = dotProduct( <Quaternion> )
--* <Float> = magnitude()
--*
--* <Transform> = toTransform()
--* <Vector> = toVector()
--* <AxisAngle> = toAxisAngle()
--* <PropList> = toPropList()
--* <LinearList> = toLineList()
--* <String> = toString()
--*
--*
--***************************************************
--* PRIVATE METHODS
--***************************************************
--*
--* <Void> = __setQuaternion()
--* <Void> = __setQuatFromTransform( <Transform> )
--* <Void> = __setQuatFromVector( <Vector> )
--* <Void> = __setQuatFromUndefList( <PropList> / <LinearList> / <AxisAngle> )
--*
--* <Void> = __setPropListFromAxisAngle( <AxisAngle> )
--* <Void> = __listNormalize( <PropList> ) 'Optionnal'
--*
--* <Boolean> = __isAxisAngle( <AxisAngle> )
--* <Boolean> = __isLineList( <LinearList> )
--* <Boolean> = __isPropList( <PropList> )
--*
--* <Float> = __arcCos( <Number> )
--*
--* <Void> = __throwError( <PropList> )
--* <Void> = __throwPrivate()
--*
--*
--***************************************************
-- Constant
property DEGTORAD
property RADTODEG
property EPSILON
-- Public property
property quaternionP
-- Private properties
property ancestor
property p_sScriptName
--***************************************************
--* CONSTRUCTOR
--***************************************************
--*
--***************************************************
on new( me, aValue )
DEGTORAD = PI / float(180)
RADTODEG = float(180) / PI
EPSILON = 0.0001
--
__setQuaternion( VOID, me )
--
case ilk( aValue ) of
#Void : nothing
#Transform : __setQuatFromTransform( VOID, me, aValue )
#Vector : __setQuatFromVector( VOID, me, aValue )
#List : __setQuatFromUndefList( VOID, me, aValue )
#Quaternion: me.duplicate( aValue )
otherwise : __throwError( VOID, me, [#Error: "Value type mismatch !", #ID: "10505200901"] )
end case
--
return( me )
end
--***************************************************
--* GETAT
--***************************************************
--*
--***************************************************
on getAt( me, aProp )
--
case ilk( aProp ) of
#Symbol : iPos = ([#x, #y, #z, #w]).getPos( aProp )
#String : iPos = ([#x, #y, #z, #w]).getPos( symbol( aProp ) )
#Integer : iPos = aProp
otherwise: iPos = 0
end case
--
if ( (iPos <= 0) OR (iPos > 4) ) then __throwError( VOID, me, [#Error: "Argument out of range !", #ID: "10505200902"] )
--
return( (me.ancestor)[iPos] )
end
--***************************************************
--* SETAT
--***************************************************
--*
--***************************************************
on setAt( me, aProp, aValue )
--
case ilk( aProp ) of
#Symbol : iPos = ([#x, #y, #z, #w]).getPos( aProp )
#String : iPos = ([#x, #y, #z, #w]).getPos( symbol( aProp ) )
#Integer : iPos = aProp
otherwise: iPos = 0
end case
--
if ( (iPos <= 0) OR (iPos > 4) ) then __throwError( VOID, me, [#Error: "Argument out of range !", #ID: "10505200903"] )
if not( ilk( aValue, #Number ) ) then __throwError( VOID, me, [#Error: "Number expected !", #ID: "10505200904"] )
(me.ancestor)[iPos] = float( aValue )
--
return( (me.ancestor)[iPos] )
end
--***************************************************
--* ILK
--***************************************************
--*
--***************************************************
on ilk( me )
--
iCnt = _movie.paramCount()
if (iCnt > 2) then __throwError( VOID, me, [#Error: "Wrong number of argument !", #ID: "10505200905"] )
--
if (iCnt = 1) then
if integerP( me ) then return( #Integer )
if floatP( me ) then return( #Float )
if stringP( me ) then return( #String )
if symbolP( me ) then return( #Symbol )
if voidP( me ) then return( #Void )
if quaternionP( me ) then return( #Quaternion )
if (objectP( me ) AND not(listP( me ))) then return( #Object ) -- << must be after your own predicate !
__throwError( VOID, me, [#Error: "Unknown type !", #ID: "10505200906"] )
else
case( _movie.param(iCnt) ) of
#Integer : return( integerP( me ) )
#Float : return( floatP( me ) )
#Number : return( integerP( me ) OR floatP( me ) )
#String : return( stringP( me ) )
#Symbol : return( symbolP( me ) )
#Void : return( voidP( me ) )
#Quaternion: return( quaternionP( me ) )
#Object : return( (objectP( me ) AND not(listP( me ))) )
otherwise : return( FALSE )
end case
end if
--
end
--***************************************************
--* QUATERNIONP
--***************************************************
--*
--***************************************************
on quaternionP( me )
--
if ( objectP( me ) AND not(listP( me )) ) then
if not( voidP(me.getaProp(#p_sScriptName)) ) then
if ( string( me ) contains (me.p_sScriptName) ) then
return( TRUE )
end if
end if
end if
--
return( FALSE )
end
--***************************************************
--* INVERT
--***************************************************
--*
--***************************************************
on invert( me )
--
(me.ancestor)[1] = - (me.ancestor)[1]
(me.ancestor)[2] = - (me.ancestor)[2]
(me.ancestor)[3] = - (me.ancestor)[3]
--
return
end
--***************************************************
--* OPPOSE
--***************************************************
--*
--***************************************************
on oppose( me )
--
me.ancestor = (me.ancestor) * float(-1)
--
return
end
--***************************************************
--* NORMALIZE
--***************************************************
--*
--***************************************************
on normalize( me )
--
__listNormalize( VOID, me )
--
return
end
--***************************************************
--* IDENTITY
--***************************************************
--*
--***************************************************
on identity( me )
me.ancestor = [#x: float(0), #y: float(0), #z: float(0), #w: float(1)]
return
end
--***************************************************
--* DUPLICATE
--***************************************************
--*
--***************************************************
on duplicate( me )
return( _movie.script( (me.p_sScriptName) ).new( me ) )
end
--***************************************************
--* GETINVERSE
--***************************************************
--*
--***************************************************
on getInversed( me )
lInversed = ( (me.ancestor).duplicate() ) * float(-1)
lInversed[4] = - lInversed[4]
return( _movie.script( (me.p_sScriptName) ).new( lInversed ) )
end
--***************************************************
--* GETOPPOSED
--***************************************************
--*
--***************************************************
on getOpposed( me )
lOpposed = ( (me.ancestor).duplicate() ) * float(-1)
return( _movie.script( (me.p_sScriptName) ).new( lOpposed ) )
end
--***************************************************
--* GETNORMALIZED
--***************************************************
--*
--***************************************************
on getNormalized( me )
lNormalized = (me.ancestor).duplicate()
__listNormalize( VOID, me, lNormalized )
return( _movie.script( (me.p_sScriptName) ).new( lNormalized ) )
end
--***************************************************
--* MULTIPLY
--***************************************************
--*
--***************************************************
on multiply( me, aValue )
--
case ilk( aValue ) of
#Quaternion: lValue = (aValue.ancestor).duplicate()
#Number : lValue = [#x: float(aValue), #y: float(aValue), #z: float(aValue), #w: float(aValue)]
#Transform, #Vector, #List : lValue = (_movie.script( (me.p_sScriptName) ).new( aValue )).ancestor
otherwise : __throwError( VOID, me, [#Error: "Value type mismatch !", #ID: "10505200907"] )
end case
--
X1 = (me.ancestor)[1]
Y1 = (me.ancestor)[2]
Z1 = (me.ancestor)[3]
W1 = (me.ancestor)[4]
--
X2 = lValue[1]
Y2 = lValue[2]
Z2 = lValue[3]
W2 = lValue[4]
lValue = VOID
--
return( _movie.script( (me.p_sScriptName) ).new( [\
W1 * X2 + X1 * W2 + Y1 * Z2 - Z1 * Y2,\
W1 * Y2 + Y1 * W2 + Z1 * X2 - X1 * Z2,\
W1 * Z2 + Z1 * W2 + X1 * Y2 - Y1 * X2,\
W1 * W2 - X1 * X2 - Y1 * Y2 - Z1 * Z2] ) )
end
--***************************************************
--* ADD
--***************************************************
--*
--***************************************************
on add( me, aValue )
--
case ilk( aValue ) of
#Quaternion: lValue = (aValue.ancestor).duplicate()
#Number : lValue = [#x: float(aValue), #y: float(aValue), #z: float(aValue), #w: float(aValue)]
#Transform, #Vector, #List : lValue = (_movie.script( (me.p_sScriptName) ).new( aValue )).ancestor
otherwise : __throwError( VOID, me, [#Error: "Value type mismatch !", #ID: "10505200908"] )
end case
--
X = (me.ancestor)[1] + lValue[1]
Y = (me.ancestor)[2] + lValue[2]
Z = (me.ancestor)[3] + lValue[3]
W = (me.ancestor)[4] + lValue[4]
lValue = VOID
--
return( _movie.script( (me.p_sScriptName) ).new( [X, Y, Z, W] ) )
end
--***************************************************
--* SUBTRACT
--***************************************************
--*
--***************************************************
on subtract( me, aValue )
--
case ilk( aValue ) of
#Quaternion: lValue = (aValue.ancestor).duplicate()
#Number : lValue = [#x: float(aValue), #y: float(aValue), #z: float(aValue), #w: float(aValue)]
#Transform, #Vector, #List : lValue = (_movie.script( (me.p_sScriptName) ).new( aValue )).ancestor
otherwise : __throwError( VOID, me, [#Error: "Value type mismatch !", #ID: "10505200909"] )
end case
--
X = (me.ancestor)[1] - lValue[1]
Y = (me.ancestor)[2] - lValue[2]
Z = (me.ancestor)[3] - lValue[3]
W = (me.ancestor)[4] - lValue[4]
lValue = VOID
--
return( _movie.script( (me.p_sScriptName) ).new( [X, Y, Z, W] ) )
end
--***************************************************
--* ISEQUALTO
--***************************************************
--*
--***************************************************
on isEqualTo( me, aValue )
--
if not( ilk( aValue, #Quaternion ) ) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200910"] )
--
return(\
( abs( (me.ancestor)[1] - (aValue.ancestor)[1] ) <= EPSILON ) AND\
( abs( (me.ancestor)[2] - (aValue.ancestor)[2] ) <= EPSILON ) AND\
( abs( (me.ancestor)[3] - (aValue.ancestor)[3] ) <= EPSILON ) AND\
( abs( (me.ancestor)[4] - (aValue.ancestor)[4] ) <= EPSILON ) )
end
--***************************************************
--* ISIDENTITY
--***************************************************
--*
--***************************************************
on isIdentity( me )
--
if (\
( abs( (me.ancestor)[1] ) <= EPSILON ) AND\
( abs( (me.ancestor)[2] ) <= EPSILON ) AND\
( abs( (me.ancestor)[3] ) <= EPSILON ) AND\
( abs( (me.ancestor)[4] - float(1) ) <= EPSILON ) ) then return( TRUE )
--
return( FALSE )
end
--***************************************************
--* ISNORMALIZED
--***************************************************
--*
--***************************************************
on isNormalized( me )
--
if ( abs( me.magnitude() - float(1) ) <= EPSILON ) then return( TRUE )
--
return( FALSE )
end
--***************************************************
--* DOTPRODUCT
--***************************************************
--*
--***************************************************
on dotProduct( me, aValue )
--
if not( ilk( aValue, #Quaternion ) ) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200911"] )
--
return(\
( (me.ancestor)[1] * aValue[1] ) + ( (me.ancestor)[2] * aValue[2] ) +\
( (me.ancestor)[3] * aValue[3] ) + ( (me.ancestor)[4] * aValue[4] ) )
end
--***************************************************
--* MAGNITUDE
--***************************************************
--*
--***************************************************
on magnitude( me )
--
return( sqrt(\
(me.ancestor)[1] * (me.ancestor)[1] +\
(me.ancestor)[2] * (me.ancestor)[2] +\
(me.ancestor)[3] * (me.ancestor)[3] +\
(me.ancestor)[4] * (me.ancestor)[4] ) )
end
--***************************************************
--* TOTRANSFORM
--***************************************************
--*
--***************************************************
on toTransform( me )
--
__listNormalize( VOID, me )
--
X1 = (me.ancestor)[1]
Y1 = (me.ancestor)[2]
Z1 = (me.ancestor)[3]
W1 = (me.ancestor)[4]
--
X2 = X1 * X1
Y2 = Y1 * Y1
Z2 = Z1 * Z1
W2 = W1 * W1
--
XY = X1 * Y1
XZ = X1 * Z1
YZ = Y1 * Z1
--
WX = W1 * X1
WY = W1 * Y1
WZ = W1 * Z1
--
trsf = transform()
--
trsf[1] = float( 1.0 - 2.0 * (Y2 + Z2) )
trsf[2] = float( 2.0 * (XY + WZ) )
trsf[3] = float( 2.0 * (XZ - WY) )
--
trsf[5] = float( 2.0 * (XY - WZ) )
trsf[6] = float( 1.0 - 2.0 * (X2 + Z2) )
trsf[7] = float( 2.0 * (YZ + WX) )
--
trsf[9] = float( 2.0 * (XZ + WY) )
trsf[10] = float( 2.0 * (YZ - WX) )
trsf[11] = float( 1.0 - 2.0 * (X2 + Y2) )
--
return( trsf )
end
--***************************************************
--* TOVECTOR
--***************************************************
--*
--***************************************************
on toVector( me )
--
trsf = toTransform( me )
vEuler = trsf.rotation
--
return( vEuler )
end
--***************************************************
--* TOAXISANGLE
--***************************************************
--*
--***************************************************
on toAxisAngle( me )
--
__listNormalize( VOID, me )
--
X1 = (me.ancestor)[1]
Y1 = (me.ancestor)[2]
Z1 = (me.ancestor)[3]
W1 = (me.ancestor)[4]
--
fAngle = __arcCos( VOID, me, W1 )
fScale = me.magnitude()
--
if ((0 <= fAngle) OR (PI >= fAngle)) then __throwError( VOID, me, [#Error: "Angle must be between 0 and PI !", #ID: "10505200912"] )
lAxisAngle = []
--
if ( fScale <= EPSILON ) then
lAxisAngle.add( vector(1, 0, 0) )
lAxisAngle.add( float(0) )
else if ( (X1 = float(0)) AND (Y1 = float(0)) AND (Z1 = float(0)) ) then
lAxisAngle.add( vector(1, 0, 0) )
lAxisAngle.add( float(0) )
else
vEuler = vector( X1 / fScale, Y1 / fScale, Z1 / fScale )
vEuler.normalize()
lAxisAngle.add( vEuler )
lAxisAngle.add( fAngle * float(2) * RADTODEG )
end if
--
return( lAxisAngle )
end
--***************************************************
--* TOPROPLIST
--***************************************************
--*
--***************************************************
on toPropList( me )
--
return( (me.ancestor).duplicate() )
end
--***************************************************
--* TOLINELIST
--***************************************************
--*
--***************************************************
on toLineList( me )
--
return( [ (me.ancestor)[1], (me.ancestor)[2], (me.ancestor)[3], (me.ancestor)[4] ] )
end
--***************************************************
--* TOSTRING
--***************************************************
--*
--***************************************************
on toString( me )
--
return( "Quaternion("&&"#x:"&&(me.ancestor)[1]&", #y:"&&(me.ancestor)[2]&", #z:"&&(me.ancestor)[3]&", #w:"&&(me.ancestor)[4]&&")" )
end
--***************************************************
--* __SETQUATERNION
--***************************************************
--*
--***************************************************
on __setQuaternion( PRIVATE, me )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(objectP( me )) then __throwError( VOID, me, [#Error: "Object expected !", #ID: "10505200913"] )
--
sScript = string( me )
iWrdCnt = sScript.word.count
iStrLgth = (sScript.word[2..iWrdCnt-2]).length
me.p_sScriptName = (sScript.word[2..iWrdCnt]).char[2..(iStrLgth-1)]
--
me.ancestor = [ #x: float(0), #y: float(0), #z: float(0), #w: float(1) ]
QuaternionP = TRUE
--
return
end
--***************************************************
--* __SETQUATFROMTRANSFORM
--***************************************************
--*
--***************************************************
on __setQuatFromTransform( PRIVATE, me, aTransform )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(quaternionP( me )) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200914"] )
--
fTrace = 1 + aTransform[1] + aTransform[6] + aTransform[11]
--
if ( fTrace > EPSILON ) then
--
fRoot = sqrt( fTrace ) * float(2)
(me.ancestor)[1] = ( aTransform[10] - aTransform[7] ) / fRoot
(me.ancestor)[2] = ( aTransform[3] - aTransform[9] ) / fRoot
(me.ancestor)[3] = ( aTransform[5] - aTransform[2] ) / fRoot
(me.ancestor)[4] = 0.25 * fRoot
--
else if ( (aTransform[1] > aTransform[6]) AND (aTransform[1] > aTransform[11]) ) then
--
fRoot = sqrt( float(1) + aTransform[1] - aTransform[6] - aTransform[11] ) * float(2)
(me.ancestor)[1] = 0.25 * fRoot
(me.ancestor)[2] = ( aTransform[5] + aTransform[2] ) / fRoot
(me.ancestor)[3] = ( aTransform[3] + aTransform[9] ) / fRoot
(me.ancestor)[4] = ( aTransform[10] - aTransform[7] ) / fRoot
--
else if ( aTransform[6] > aTransform[11] ) then
--
fRoot = sqrt( float(1) + aTransform[6] - aTransform[1] - aTransform[11] ) * float(2)
(me.ancestor)[1] = ( aTransform[5] + aTransform[2] ) / fRoot
(me.ancestor)[2] = 0.25 * fRoot
(me.ancestor)[3] = ( aTransform[10] + aTransform[7] ) / fRoot
(me.ancestor)[4] = ( aTransform[3] - aTransform[9] ) / fRoot
--
else
--
fRoot = sqrt( float(1) + aTransform[11] - aTransform[1] - aTransform[6] ) * float(2)
(me.ancestor)[1] = ( aTransform[3] + aTransform[9] ) / fRoot
(me.ancestor)[2] = ( aTransform[10] + aTransform[7] ) / fRoot
(me.ancestor)[3] = 0.25 * fRoot
(me.ancestor)[4] = ( aTransform[5] - aTransform[2] ) / fRoot
--
end if
--
__listNormalize( VOID, me )
--
return
end
--***************************************************
--* __SETQUATFROMVECTOR
--***************************************************
--*
--***************************************************
on __setQuatFromVector( PRIVATE, me, aEuler )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(quaternionP( me )) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200915"] )
--
X = (aEuler.x * DEGTORAD) * 0.5
Y = (aEuler.y * DEGTORAD) * 0.5
Z = (aEuler.z * DEGTORAD) * 0.5
--
fCosRoll = cos( X )
fCosPitch = cos( Y )
fCosYaw = cos( Z )
--
fSinRoll = sin( X )
fSinPitch = sin( Y )
fSinYaw = sin( Z )
--
fCosPitchCosYaw = fCosPitch * fCosYaw
fSinPitchSinYaw = fSinPitch * fSinYaw
--
(me.ancestor)[1] = fSinRoll * fCosPitchCosYaw - fCosRoll * fSinPitchSinYaw
(me.ancestor)[2] = fCosRoll * fSinPitch * fCosYaw + fSinRoll * fCosPitch * fSinYaw
(me.ancestor)[3] = fCosRoll * fCosPitch * fSinYaw - fSinRoll * fSinPitch * fCosYaw
(me.ancestor)[4] = fCosRoll * fCosPitchCosYaw + fSinRoll * fSinPitchSinYaw
--
__listNormalize( VOID, me )
--
return
end
--***************************************************
--* __SETQUATFROMUNDEFLIST
--***************************************************
--*
--***************************************************
on __setQuatFromUndefList( PRIVATE, me, aUndefList )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(quaternionP( me )) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200916"] )
--
if ilk( aUndefList, #LinearList ) then
iListCnt = aUndefList.count()
iAxisAngle = 2
iLineList = 4
--
if ( iListCnt = iAxisAngle ) then
if not( __isAxisAngle( VOID, me, aUndefList ) ) then __throwError( VOID, me, [#Error: "Axis angle expected !", #ID: "10505200917"] )
me.ancestor = __setPropListFromAxisAngle( VOID, me, aUndefList )
else if ( iListCnt = iLineList ) then
if not( __isLineList( VOID, me, aUndefList ) ) then __throwError( VOID, me, [#Error: "Linear list expected !", #ID: "10505200918"] )
me.ancestor = [#x: float(aUndefList[1]), #y: float(aUndefList[2]), #z: float(aUndefList[3]), #w: float(aUndefList[4])]
else
__throwError( VOID, me, [#Error: "Undefined list !", #ID: "10505200919"] )
end if
--
else if ilk( aUndefList, #PropList ) then
if not( __isPropList( VOID, me, aUndefList ) ) then __throwError( VOID, me, [#Error: "Property list expected !", #ID: "10505200920"] )
me.ancestor = aUndefList.duplicate()
--
end if
--
aUndefList = VOID
--
return
end
--***************************************************
--* __SETPROPLISTFROMAXISANGLE
--***************************************************
--*
--***************************************************
on __setPropListFromAxisAngle( PRIVATE, me, aAxisAngle )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(quaternionP( me )) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200921"] )
--
vEuler = aAxisAngle[1].getNormalized()
fTheta = aAxisAngle[2] * DEGTORAD
fSin = sin( fTheta * 0.5 )
--
lProperty = [#x: float(0), #y: float(0), #z: float(0), #w: float(1)]
lProperty.x = vEuler.x * fSin
lProperty.y = vEuler.y * fSin
lProperty.z = vEuler.z * fSin
lProperty.w = cos( fTheta * 0.5 )
--
__listNormalize( VOID, me, lProperty )
--
return( lProperty )
end
--***************************************************
--* __LISTNORMALIZE
--***************************************************
--
--***************************************************
on __listNormalize( PRIVATE, me, aPropList )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(quaternionP( me )) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200922"] )
if (voidP(aPropList)) then aPropList = me.ancestor
--
fMagnitude = sqrt( aPropList[1] * aPropList[1] + aPropList[2] * aPropList[2] + aPropList[3] * aPropList[3] + aPropList[4] * aPropList[4] )
--
if ( fMagnitude < EPSILON ) then
aPropList[1] = float(0)
aPropList[2] = float(0)
aPropList[3] = float(0)
aPropList[4] = float(1)
else
fLength = float(1) / fMagnitude
aPropList[1] = aPropList[1] * fLength
aPropList[2] = aPropList[2] * fLength
aPropList[3] = aPropList[3] * fLength
aPropList[4] = aPropList[4] * fLength
end if
--
return
end
--***************************************************
--* __ISAXISANGLE
--***************************************************
--*
--***************************************************
on __isAxisAngle( PRIVATE, me, aAxisAngle )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(quaternionP( me )) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200923"] )
--
if (not(ilk( aAxisAngle, #LinearList ))) then return( FALSE )
if ( aAxisAngle.count() <> 2 ) then return( FALSE )
if (not(ilk( aAxisAngle[1], #Vector ))) then return( FALSE )
if (not(ilk( aAxisAngle[2], #Number ))) then return( FALSE )
--
return( TRUE )
end
--***************************************************
--* __ISLINELIST
--***************************************************
--*
--***************************************************
on __isLineList( PRIVATE, me, aLineList )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(quaternionP( me )) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200924"] )
--
if not(ilk( aLineList, #LinearList )) then return( FALSE )
if ( aLineList.count() <> 4 ) then return( FALSE )
if not(ilk( aLineList[1], #Number )) then return( FALSE )
if not(ilk( aLineList[2], #Number )) then return( FALSE )
if not(ilk( aLineList[3], #Number )) then return( FALSE )
if not(ilk( aLineList[4], #Number )) then return( FALSE )
--
return( TRUE )
end
--***************************************************
--* __ISPROPLIST
--***************************************************
--*
--***************************************************
on __isPropList( PRIVATE, me, aPropList )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(quaternionP( me )) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200925"] )
--
if not(ilk( aPropList, #PropList )) then return( FALSE )
if ( aPropList.count() <> 4 ) then return( FALSE )
if ilk( aPropList.getaProp(#x), #VOID ) then return( FALSE )
if ilk( aPropList.getaProp(#y), #VOID ) then return( FALSE )
if ilk( aPropList.getaProp(#z), #VOID ) then return( FALSE )
if ilk( aPropList.getaProp(#w), #VOID ) then return( FALSE )
if not(ilk( aPropList.x, #Float )) then return( FALSE )
if not(ilk( aPropList.y, #Float )) then return( FALSE )
if not(ilk( aPropList.z, #Float )) then return( FALSE )
if not(ilk( aPropList.w, #Float )) then return( FALSE )
--
return( TRUE )
end
--***************************************************
--* __ARCCOS
--***************************************************
--*
--***************************************************
on __arcCos( PRIVATE, me, x )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
if not(quaternionP( me )) then __throwError( VOID, me, [#Error: "Quaternion expected !", #ID: "10505200926"] )
--
x = float(x)
--
if (x < float(0)) then
return( PI + atan( sqrt( float(1) - (x * x) ) / x ) )
else if (x > 0) then
return( atan( sqrt( float(1) - (x * x) ) / x ) )
else
return( PI * 0.5 )
end if
--
end
--***************************************************
--* __THROWERROR
--***************************************************
--
--***************************************************
on __throwError( PRIVATE, me, aErrorList )
--
if not(voidP( PRIVATE )) then __throwPrivate( VOID, me )
--
if ( ilk(_player.alertHook, #Object) AND (_system.environmentPropList[#runMode] = "Author") ) then
-- _player.alert(...)
else
trace( "Error:"&&aErrorList.Error )
end if
--
HALT
--
return
end
--***************************************************
--* __THROWPRIVATE
--***************************************************
--
--***************************************************
on __throwPrivate( PRIVATE, me )
--
if ( ilk(_player.alertHook, #Object) AND (_system.environmentPropList[#runMode] = "Author") ) then
-- _player.alert(...)
else
trace( "Error: You couldn't access private method from your location !" )
end if
--
HALT
--
return
end