Browse Source

TorqueScript always uses degrees. Polar coordinates use the standard with 0 degrees along the postive X-axis and 90 degrees along the positive Y-axis.

William Lee Sims 12 years ago
parent
commit
4de7c816af

+ 2 - 2
engine/source/2d/core/Vector2.h

@@ -86,8 +86,8 @@ struct Vector2 : b2Vec2
     inline Vector2 operator = (const b2Vec2 &p)                         { x = p.x; y = p.y; return *this; }
     inline Vector2 operator = (const b2Vec2 &p)                         { x = p.x; y = p.y; return *this; }
 
 
     /// Utility.
     /// Utility.
-    inline void setAngle(const F32 radians)                             { x = mSin(radians); y = mCos(radians); }
-    inline void setPolar(const F32 radians,F32 length)                  { x = mSin(radians)*length; y = mCos(radians)*length; }
+    inline void setAngle(const F32 radians)                             { x = mCos(radians); y = mSin(radians); }
+    inline void setPolar(const F32 radians,F32 length)                  { x = mCos(radians)*length; y = mSin(radians)*length; }
     inline void setString(const char* pString )
     inline void setString(const char* pString )
     {
     {
         const U32 elementCount = Utility::mGetStringElementCount(pString);
         const U32 elementCount = Utility::mGetStringElementCount(pString);

+ 1 - 1
engine/source/2d/core/Vector2_ScriptBinding.h

@@ -237,7 +237,7 @@ ConsoleFunction( Vector2AngleToPoint, F32, 3, 3, "(Vector2 p1, Vector2 p1) - Ret
     Vector2 p2( argv[2] );
     Vector2 p2( argv[2] );
 
 
     // Do Operation.
     // Do Operation.
-    return mRadToDeg( mAtan((p2.x - p1.x), (p1.y - p2.y)) );
+    return mRadToDeg( mAtan((p2.x - p1.x), (p2.y - p1.y)) );
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------

+ 1 - 1
engine/source/2d/sceneobject/ParticlePlayer.cc

@@ -1432,7 +1432,7 @@ void ParticlePlayer::integrateParticle( EmitterNode* pEmitterNode, ParticleSyste
     if ( pParticleAssetEmitter->getKeepAligned() && pParticleAssetEmitter->getOrientationType() == ParticleAssetEmitter::ALIGNED_ORIENTATION )
     if ( pParticleAssetEmitter->getKeepAligned() && pParticleAssetEmitter->getOrientationType() == ParticleAssetEmitter::ALIGNED_ORIENTATION )
     {
     {
         // Yes, so calculate last movement direction.
         // Yes, so calculate last movement direction.
-        F32 movementAngle = mRadToDeg( mAtan( pParticleNode->mVelocity.x, -pParticleNode->mVelocity.y ) );
+        F32 movementAngle = mRadToDeg( mAtan( pParticleNode->mVelocity.x, pParticleNode->mVelocity.y ) );
 
 
         // Adjust for negative ArcTan quadrants.
         // Adjust for negative ArcTan quadrants.
         if ( movementAngle < 0.0f )
         if ( movementAngle < 0.0f )

+ 1 - 1
engine/source/2d/sceneobject/SceneObject.cc

@@ -1656,7 +1656,7 @@ bool SceneObject::rotateTo( const F32 targetAngle, const F32 speed, const bool a
     const F32 relativeAngle = targetAngle - getAngle();
     const F32 relativeAngle = targetAngle - getAngle();
 
 
     // Calculate delta angle.
     // Calculate delta angle.
-    const F32 deltaAngle = mAtan( mSin( relativeAngle ), mCos( relativeAngle ) );
+    const F32 deltaAngle = mAtan( mCos( relativeAngle ), mSin( relativeAngle ) );
 
 
     // Set angular velocity.
     // Set angular velocity.
     setAngularVelocity( deltaAngle > 0.0f ? speed : -speed );
     setAngularVelocity( deltaAngle > 0.0f ? speed : -speed );

+ 2 - 2
engine/source/2d/sceneobject/SceneObject_ScriptBinding.h

@@ -1469,7 +1469,7 @@ ConsoleMethod(SceneObject, setLinearVelocityPolar, void, 4, 4,   "(float angle,
     mSinCos( angle, sin, cos );
     mSinCos( angle, sin, cos );
 
 
     // Set Gross Linear Velocity.
     // Set Gross Linear Velocity.
-    object->setLinearVelocity( Vector2( sin*speed, -cos*speed ) );
+    object->setLinearVelocity( Vector2( cos*speed, -sin*speed ) );
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
@@ -1484,7 +1484,7 @@ ConsoleMethod(SceneObject, getLinearVelocityPolar, const char*, 2, 2, "() - Gets
     char* pBuffer = Con::getReturnBuffer(32);
     char* pBuffer = Con::getReturnBuffer(32);
 
 
     // Format Buffer.
     // Format Buffer.
-    dSprintf(pBuffer, 32, "%g %g", mRadToDeg(mAtan(linearVelocity.x, -linearVelocity.y)), linearVelocity.Length() );
+    dSprintf(pBuffer, 32, "%g %g", mRadToDeg(mAtan(linearVelocity.x, linearVelocity.y)), linearVelocity.Length() );
 
 
     // Return Velocity.
     // Return Velocity.
     return pBuffer;
     return pBuffer;

+ 1 - 1
engine/source/2d/sceneobject/Scroller_ScriptBinding.h

@@ -197,7 +197,7 @@ ConsoleMethod(Scroller, setScrollPolar, void, 4, 4, "(angle, scrollSpeed) Sets A
     F32 scrollSpeed = dAtof(argv[3]);
     F32 scrollSpeed = dAtof(argv[3]);
 
 
     // Set Scroll.
     // Set Scroll.
-    object->setScroll( mSin(mDegToRad(angle))*scrollSpeed, -mCos(mDegToRad(angle))*scrollSpeed );
+    object->setScroll( mCos(mDegToRad(angle))*scrollSpeed, mSin(mDegToRad(angle))*scrollSpeed );
 }
 }
 
 
 //------------------------------------------------------------------------------
 //------------------------------------------------------------------------------

+ 30 - 12
engine/source/math/mConsoleFunctions.cc

@@ -149,7 +149,7 @@ ConsoleFunction( mSin, F32, 2, 2, "( val ) Use the mSin function to get the sine
                                                                 "@return Returns the sine of val. This value will be in the range [ -1.0 , 1.0 ].\n"
                                                                 "@return Returns the sine of val. This value will be in the range [ -1.0 , 1.0 ].\n"
                                                                 "@sa mAsin")
                                                                 "@sa mAsin")
 {
 {
-   return(mSin(dAtof(argv[1])));
+   return(mSin(mDegToRad(dAtof(argv[1]))));
 }
 }
 
 
 ConsoleFunction( mCos, F32, 2, 2, "( val ) Use the mCos function to get the cosine of the radian angle val.\n"
 ConsoleFunction( mCos, F32, 2, 2, "( val ) Use the mCos function to get the cosine of the radian angle val.\n"
@@ -157,7 +157,7 @@ ConsoleFunction( mCos, F32, 2, 2, "( val ) Use the mCos function to get the cosi
                                                                 "@return Returns the cosine of val. This value will be in the range [ -1.0 , 1.0 ].\n"
                                                                 "@return Returns the cosine of val. This value will be in the range [ -1.0 , 1.0 ].\n"
                                                                 "@sa mAcos")
                                                                 "@sa mAcos")
 {
 {
-   return(mCos(dAtof(argv[1])));
+   return(mCos(mDegToRad(dAtof(argv[1]))));
 }
 }
 
 
 ConsoleFunction( mTan, F32, 2, 2, "( val ) Use the mTan function to get the tangent of the radian angle val.\n"
 ConsoleFunction( mTan, F32, 2, 2, "( val ) Use the mTan function to get the tangent of the radian angle val.\n"
@@ -165,32 +165,50 @@ ConsoleFunction( mTan, F32, 2, 2, "( val ) Use the mTan function to get the tang
                                                                 "@return Returns the tangent of val. This value will be in the range [ -inf.0 , inf.0 ].\n"
                                                                 "@return Returns the tangent of val. This value will be in the range [ -inf.0 , inf.0 ].\n"
                                                                 "@sa mAtan")
                                                                 "@sa mAtan")
 {
 {
-   return(mTan(dAtof(argv[1])));
+   return(mTan(mDegToRad(dAtof(argv[1]))));
 }
 }
 
 
 ConsoleFunction( mAsin, F32, 2, 2, "( val ) Use the mAsin function to get the inverse sine of val in radians.\n"
 ConsoleFunction( mAsin, F32, 2, 2, "( val ) Use the mAsin function to get the inverse sine of val in radians.\n"
                                                                 "@param val A value between -1.0 and 1.0 equal to the sine of some angle theta.\n"
                                                                 "@param val A value between -1.0 and 1.0 equal to the sine of some angle theta.\n"
-                                                                "@return Returns the inverse sine of val in radians. This value will be in the range [ - 3.14159/2 , 3.14159/2 ].\n"
+                                                                "@return Returns the inverse sine of val in degrees. This value will be in the range [ -90,90 ].\n"
                                                                 "@sa mSin")
                                                                 "@sa mSin")
 {
 {
-   return(mAsin(dAtof(argv[1])));
+   return(mRadToDeg(mAsin(dAtof(argv[1]))));
 }
 }
 
 
 ConsoleFunction( mAcos, F32, 2, 2, "( val ) Use the mAcos function to get the inverse cosine of val in radians.\n"
 ConsoleFunction( mAcos, F32, 2, 2, "( val ) Use the mAcos function to get the inverse cosine of val in radians.\n"
                                                                 "@param val A value between -1.0 and 1.0 equal to the cosine of some angle theta.\n"
                                                                 "@param val A value between -1.0 and 1.0 equal to the cosine of some angle theta.\n"
-                                                                "@return Returns the inverse cosine of val in radians. This value will be in the range [ 0 , 3.14159 ].\n"
+                                                                "@return Returns the inverse cosine of val in degrees. This value will be in the range [ 0 , 180 ].\n"
                                                                 "@sa mCos")
                                                                 "@sa mCos")
 {
 {
-   return(mAcos(dAtof(argv[1])));
+   return(mRadToDeg(mAcos(dAtof(argv[1]))));
 }
 }
 
 
-ConsoleFunction( mAtan, F32, 3, 3, "( val ) Use the mAtan function to get the inverse tangent of rise/run in radians.\n"
-                                                                "@param rise Vertical component of a line.\n"
-                                                                "@param run Horizontal component of a line.\n"
-                                                                "@return Returns the slope in radians (the arc-tangent) of a line with the given rise and run.\n"
+ConsoleFunction( mAtan, F32, 2, 3, "( [x-run y-rise] ) Use the mAtan function to get the inverse tangent of rise/run in radians.\n"
+                                                                "@param x-run Horizontal component of a line.\n"
+                                                                "@param y-rise Vertical component of a line.\n"
+                                                                "May be called as mAtan( 1, 1 ) or mAtan( \"1 1\" ).\n"
+                                                                "@return Returns the inverse tangent in degrees of a line with the given rise and run.\n"
                                                                 "@sa mTan")
                                                                 "@sa mTan")
 {
 {
-   return(mAtan(dAtof(argv[1]), dAtof(argv[2])));
+   F32 xRun, yRise;
+
+   if( argc == 3 )
+   {
+     xRun = dAtof( argv[1] );
+     yRise = dAtof( argv[2] );
+   }
+   else if( StringUnit::getUnitCount( argv[1], " " ) == 2 )
+   {
+     dSscanf( argv[1], "%g %g", &xRun, &yRise );
+   }
+   else
+   {
+     Con::warnf( "mAtan - Invalid parameters" );
+     return 0;
+   }
+
+   return(mRadToDeg(mAtan(xRun,yRise)));
 }
 }
 
 
 ConsoleFunction( mRadToDeg, F32, 2, 2, "( val ) Use the mRadToDeg function to convert radians to degrees.\n"
 ConsoleFunction( mRadToDeg, F32, 2, 2, "( val ) Use the mRadToDeg function to convert radians to degrees.\n"

+ 2 - 14
engine/source/math/mMathFn.h

@@ -408,7 +408,7 @@ inline F32 mAcos(const F32 val)
 
 
 inline F32 mAtan(const F32 x, const F32 y)
 inline F32 mAtan(const F32 x, const F32 y)
 {
 {
-   return (F32) atan2(x, y);
+   return (F32) atan2(y, x);
 }
 }
 
 
 inline void mSinCos(const F32 angle, F32 &s, F32 &c)
 inline void mSinCos(const F32 angle, F32 &s, F32 &c)
@@ -465,7 +465,7 @@ inline F64 mAcos(const F64 val)
 
 
 inline F64 mAtan(const F64 x, const F64 y)
 inline F64 mAtan(const F64 x, const F64 y)
 {
 {
-   return (F64) atan2(x, y);
+   return (F64) atan2(y, x);
 }
 }
 
 
 inline void mSinCos(const F64 angle, F64 &sin, F64 &cos)
 inline void mSinCos(const F64 angle, F64 &sin, F64 &cos)
@@ -610,18 +610,6 @@ inline F64 mRadToDeg(F64 r)
    return (r * 180.0) / M_PI;
    return (r * 180.0) / M_PI;
 }
 }
 
 
-/// Get an angle flipping the Y (along the X axis).
-inline F32 mGetFlippedXAngle( const F32 radians )
-{
-    return mAtan(-mSin(radians), mCos(radians));
-}
-
-/// Get an angle flipping the Y (along the X axis).
-inline F32 mGetFlippedYAngle( const F32 radians )
-{
-    return mAtan(mSin(radians), -mCos(radians));
-}
-
 /// Precision Rounding.
 /// Precision Rounding.
 inline F32 mRound(const F32& value, const F32 epsilon = 0.5f) { return value > 0.0f ? mFloor(value + epsilon) : mCeil(value - epsilon); }
 inline F32 mRound(const F32& value, const F32 epsilon = 0.5f) { return value > 0.0f ? mFloor(value + epsilon) : mCeil(value - epsilon); }
 
 

+ 269 - 0
modules/AngleToy/1/main.cs

@@ -0,0 +1,269 @@
+//-----------------------------------------------------------------------------
+// Copyright (c) 2013 GarageGames, LLC
+//
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to
+// deal in the Software without restriction, including without limitation the
+// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+// sell copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+//
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+//
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+// IN THE SOFTWARE.
+//-----------------------------------------------------------------------------
+
+function AngleToy::create( %this )
+{        
+    // Creating this toy runs its unit tests.
+    AngleToy.unitTestScriptFunctions();    
+    
+    // Reset the toy initially.
+    AngleToy.reset();      
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::unitTestScriptFunctions()
+{
+}
+
+function AngleToy::printVectorTestResult( %this, %test, %actual, %expected )
+{
+  if( Vector2Compare( %actual, %expected ) )
+    echo( %test @ " [SUCCESS] " @ %actual @ " == " @ %expected @ "." );
+  else
+    error( %test @ " [FAILURE] " @ %actual @ " != " @ %expected @ "." );
+}
+
+function AngleToy::printValueTestResult( %this, %actual, %expected )
+{
+  if( mAbs( %actual - %expected ) < 0.000001 )
+    echo( %test @ " [SUCCESS] " @ %actual @ " == " @ %expected @ "." );
+  else
+    error( %test @ " [FAILURE] " @ %actual @ " != " @ %expected @ "." );
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::destroy( %this )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::reset( %this )
+{
+    // Clear the scene.
+    SandboxScene.clear();
+    
+    // Create background.
+    %this.createBackground();
+    
+    // Create the target.
+    %this.createTargets();
+    
+    // Create Mathematical Objects/Labels
+    %this.createMathematicalObjects();
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::createBackground( %this )
+{    
+    // Create the Polar Coordinate Background
+    %axisColor = "0.4 0.4 0.4";
+    %circleColor = "0.2 0.2 0.2";
+    %textColor = "1 1 0";
+    
+    // X-Axis
+    %object = new ShapeVector();
+    %object.setBodyType( static );
+    %object.Position = "0 0";
+    %object.Size = "100 0";
+    %object.SceneLayer = 31;
+    %object.LineColor = %axisColor;
+    %object.FillMode = false;
+    %object.setPolyCustom( 2, "-1 0 1 0" );
+    SandboxScene.add( %object );    
+  
+    // Y-Axis
+    %object = new ShapeVector();
+    %object.setBodyType( static );
+    %object.Position = "0 0";
+    %object.Size = "0 25";
+    %object.SceneLayer = 31;
+    %object.LineColor = %axisColor;
+    %object.FillMode = false;
+    %object.setPolyCustom( 2, "0 -1 0 1" );
+    SandboxScene.add( %object );
+    
+    // Radius Circles
+    for( %i = 1; %i <= 2; %i++ )
+    {
+        %object = new ShapeVector();
+        %object.setBodyType( static );
+        %object.Position = "0 0";
+        %object.Size = "20 20";
+        %object.SceneLayer = 31;
+        %object.LineColor = %circleColor;
+        %object.FillMode = false;
+        %object.IsCircle = true;
+        %object.CircleRadius = %i * 10;
+        SandboxScene.add( %object );
+    }
+    
+    // Angle Labels
+    for( %i = -165; %i <= 180; %i += 15 )
+    {
+        %object = new ImageFont();
+        %object.Image = "ToyAssets:Font";
+        %object.Position = Vector2Direction( %i, 30 ); // Polar ( 30, %i° )
+        %object.Angle = %i - 90;
+        %object.FontSize = "1.5 2";
+        %object.TextAlignment = "Center";
+        %object.BlendColor = %textColor;
+        %object.Text = %i;
+        SandboxScene.add( %object );    
+    }
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::createTargets( %this )
+{
+    // Create the sprite.
+    %object = new Sprite();
+    AngleToy.TargetObject = %object;
+    %object.Image = "ToyAssets:hollowArrow";
+    %object.Size = 5;
+    %object.setBodyType( static );
+    SandboxScene.add( %object );    
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::createMathematicalObjects( %this )
+{
+    %lineSegmentColor = "0.25 0.25 0.75";
+  
+    %object = new Sprite() { class = "LineSegment"; };
+    AngleToy.SinLineSegment = %object;
+    %object.Image = "ToyAssets:Blank";
+    %object.setBodyType( static );
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+    
+    %object = new Sprite() { class = "LineSegment"; };
+    AngleToy.CosLineSegment = %object;
+    %object.Image = "ToyAssets:Blank";
+    %object.setBodyType( static );
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );    
+    
+    %object = new Sprite() { class = "LineSegment"; };
+    AngleToy.TanLineSegment = %object;
+    %object.Image = "ToyAssets:Blank";
+    %object.setBodyType( static );
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+    
+    %object = new ImageFont();
+    AngleToy.SinLabel = %object;
+    %object.Image = "ToyAssets:Font";
+    %object.FontSize = "1.5 1.5";
+    %object.TextAlignment = "Center";
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+    
+    %object = new ImageFont();
+    AngleToy.CosLabel = %object;
+    %object.Image = "ToyAssets:Font";
+    %object.FontSize = "1.5 1.5";
+    %object.TextAlignment = "Center";
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+    
+    %object = new ImageFont();
+    AngleToy.TanLabel = %object;
+    %object.Image = "ToyAssets:Font";
+    %object.FontSize = "1.5 1.5";
+    %object.TextAlignment = "Center";
+    %object.BlendColor = %lineSegmentColor;
+    SandboxScene.add( %object );
+}
+
+//-----------------------------------------------------------------------------
+
+function AngleToy::onTouchMoved(%this, %touchID, %worldPosition)
+{
+    // Calculate the angle to the mouse.
+    %origin = AngleToy.TargetObject.getPosition();
+    %angle = mAtan( %worldPosition );
+    
+    //Rotate to the touched angle.
+    AngleToy.TargetObject.SetAngle( %angle - 90 ); // Image points at 90 degrees, so we need to subtract that off.
+    
+    // Show Sin, Cos, Tan
+    %sin = mSin( %angle );
+    %cos = mCos( %angle );
+    %tan = mTan( %angle );
+
+    // Fix %worldPosition at 20 units from the center.
+    // There are many ways to do this... For example, we could do this:
+    // %worldPositionAtRadius20 = Vector2Direction( %angle, 20 );
+    // or
+    %worldPositionAtRadius20 = Vector2Scale( Vector2Normalize( %worldPosition ), 20 );
+    // which will first shrink the %worldPosition vector to have a length of 1
+    // and then will scale it back to 20 units.
+    
+    %onYAxis = setWord( %worldPositionAtRadius20, 0, 0 ); // Set the X-component to 0
+    AngleToy.SinLineSegment.draw( %worldPositionAtRadius20, %onYAxis );
+    AngleToy.SinLabel.setPosition( %onYAxis );
+    AngleToy.SinLabel.setText( %sin );
+    
+    %onXAxis = setWord( %worldPositionAtRadius20, 1, 0 ); // Set the Y-component to 0
+    AngleToy.CosLineSegment.draw( %worldPositionAtRadius20, %onXAxis );
+    AngleToy.CosLabel.setPosition( %onXAxis );
+    AngleToy.CosLabel.setText( %cos );
+    
+    AngleToy.TanLineSegment.drawTangent( %worldPositionAtRadius20, %tan, %angle );
+    AngleToy.TanLabel.setPosition( %worldPosition );
+    AngleToy.TanLabel.setText( %tan );
+}
+
+//-----------------------------------------------------------------------------
+
+function LineSegment::draw( %this, %from, %to )
+{
+    %length = Vector2Distance( %from, %to );
+    %width = 0.25;
+    %mid = Vector2Scale( Vector2Add( %from, %to ), 0.5 ); // Mid-Point
+    %angle = Vector2AngleToPoint( %from, %to );
+    
+    %this.setPosition( %mid );
+    %this.setSize( %length, %width );
+    %this.setAngle( %angle );
+}
+
+function LineSegment::drawTangent( %this, %from, %tan, %angleOnCircle )
+{
+    // One of the many, many definitions of tangent is that the line that
+    // is tangent to the circle will intersect the X-axis with a length of
+    // %tangent.  It's fun, so we'll use it for this example.
+
+    %tangentAngle = %angleOnCircle - 90;
+    
+    %length = %tan * 20; // Sin/Cos/Tan assume a unit circle.  Scaling...
+    
+    %tangentEnd = Vector2Add( %from, Vector2Direction( %tangentAngle, %length ) );
+    
+    %this.draw( %from, %tangentEnd );
+}

+ 10 - 0
modules/AngleToy/1/module.taml

@@ -0,0 +1,10 @@
+<ModuleDefinition
+	ModuleId="AngleToy"
+	VersionId="1"
+	Description="Demonstrates how to use most angle functions."
+	Dependencies="ToyAssets=1"
+	Type="toy"
+	ToyCategoryIndex="3"
+	ScriptFile="main.cs"
+	CreateFunction="create"
+	DestroyFunction="destroy"/>

+ 1 - 1
modules/CompositeSpriteToy/1/scripts/customLayout.cs

@@ -82,7 +82,7 @@ function CompositeSprite::onCustomLayout( %this, %args )
     %inputX = %args._0;
     %inputX = %args._0;
     
     
     // Calculate an angle from the first argument.
     // Calculate an angle from the first argument.
-    %angle = mDegToRad( %inputX * 10 );
+    %angle = %inputX * 10;
     
     
     // Calculate an interesting output position.
     // Calculate an interesting output position.
     %outputX = %inputX - (CompositeSpriteToy.SpriteCount * 0.5);
     %outputX = %inputX - (CompositeSpriteToy.SpriteCount * 0.5);

+ 3 - 4
modules/CompoundObjectsToy/1/main.cs

@@ -140,14 +140,13 @@ function CompoundObjectsToy::createCompoundObject( %this, %worldPosition )
     // Create compound ring.    
     // Create compound ring.    
     for( %angle = 0; %angle < 360; %angle += %angleStride )
     for( %angle = 0; %angle < 360; %angle += %angleStride )
     {
     {
-        %radianAngle = mDegToRad( %angle );
-        %spriteX = mSin( %radianAngle ) * %radius;
-        %spriteY = mCos( %radianAngle ) * %radius;
+        %spriteX = mCos( %angle ) * %radius;
+        %spriteY = mSin( %angle ) * %radius;
         
         
         %composite.addSprite();
         %composite.addSprite();
         %composite.setSpriteLocalPosition( %spriteX, %spriteY );
         %composite.setSpriteLocalPosition( %spriteX, %spriteY );
         %composite.setSpriteSize( %blockSize );
         %composite.setSpriteSize( %blockSize );
-        %composite.setSpriteAngle( -%angle );
+        %composite.setSpriteAngle( %angle );
         %composite.setSpriteImage( "ToyAssets:Blocks" );
         %composite.setSpriteImage( "ToyAssets:Blocks" );
         %composite.setSpriteImageFrame( getRandom(0,55) );
         %composite.setSpriteImageFrame( getRandom(0,55) );
     }
     }

+ 3 - 3
modules/DeathBallToy/1/main.cs

@@ -450,7 +450,7 @@ function DeathBallToy::cancelPendingEvents()
 function DeathBallToy::onTouchDown(%this, %touchID, %worldPosition)
 function DeathBallToy::onTouchDown(%this, %touchID, %worldPosition)
 {
 {
     %origin = Deathball.getPosition();
     %origin = Deathball.getPosition();
-    %angle = -mRadToDeg( mAtan( getWord(%worldPosition,0)-getWord(%origin,0), getWord(%worldPosition,1)-getWord(%origin,1) ) );
+    %angle = mAtan( Vector2Sub( %worldPosition, %origin ) ) - 90;
 
 
     Deathball.RotateTo( %angle, DeathBallToy.rotateSpeed );
     Deathball.RotateTo( %angle, DeathBallToy.rotateSpeed );
 
 
@@ -468,7 +468,7 @@ function DeathBallToy::onTouchDown(%this, %touchID, %worldPosition)
 function DeathBallToy::onTouchUp(%this, %touchID, %worldPosition)
 function DeathBallToy::onTouchUp(%this, %touchID, %worldPosition)
 {
 {
     %origin = Deathball.getPosition();
     %origin = Deathball.getPosition();
-    %angle = -mRadToDeg( mAtan( getWord(%worldPosition,0)-getWord(%origin,0), getWord(%worldPosition,1)-getWord(%origin,1) ) );
+    %angle = mAtan( Vector2Sub( %worldPosition, %origin ) );
     
     
     // Since the speed is used instead of time, we can use the current velocity to set it's speed.
     // Since the speed is used instead of time, we can use the current velocity to set it's speed.
     %adjustedSpeed = VectorLen(DeathBall.getLinearVelocity());// (DeathBallToy.ballSpeed / DeathBallToy.maxBallSpeed) * 3000;
     %adjustedSpeed = VectorLen(DeathBall.getLinearVelocity());// (DeathBallToy.ballSpeed / DeathBallToy.maxBallSpeed) * 3000;
@@ -481,7 +481,7 @@ function DeathBallToy::onTouchUp(%this, %touchID, %worldPosition)
 function DeathBallToy::onTouchDragged(%this, %touchID, %worldPosition)
 function DeathBallToy::onTouchDragged(%this, %touchID, %worldPosition)
 {    
 {    
     %origin = Deathball.getPosition();
     %origin = Deathball.getPosition();
-    %angle = -mRadToDeg( mAtan( getWord(%worldPosition,0)-getWord(%origin,0), getWord(%worldPosition,1)-getWord(%origin,1) ) );
+    %angle = mAtan( Vector2Sub( %worldPosition, %origin ) ) - 90;
 
 
     Deathball.RotateTo( %angle, DeathBallToy.rotateSpeed );
     Deathball.RotateTo( %angle, DeathBallToy.rotateSpeed );
 
 

+ 1 - 1
modules/DeathBallToy/1/scripts/faceObjectBehavior.cs

@@ -42,7 +42,7 @@ function FaceObjectBehavior::updateFace(%this)
         return;
         return;
    
    
     %origin = %this.owner.getPosition();
     %origin = %this.owner.getPosition();
-    %angle = -mRadToDeg( mAtan( getWord(%this.target.getPosition(),0)-getWord(%origin,0), getWord(%this.target.getPosition(),1)-getWord(%origin,1) ) );
+    %angle = mAtan( Vector2Sub( %this.target.getPosition(), %origin ) );
     
     
     if ( %this.turnSpeed > 0.0 )
     if ( %this.turnSpeed > 0.0 )
     {
     {

+ 1 - 1
modules/PointForceControllerToy/1/main.cs

@@ -165,7 +165,7 @@ function Planetoid::onCollision( %this, %object, %collisionDetails )
     {
     {
         // Yes, so calculate position angle.
         // Yes, so calculate position angle.
         %positionDelta = Vector2Sub( %object.Position, %this.Position );
         %positionDelta = Vector2Sub( %object.Position, %this.Position );
-        %angle = -mRadToDeg( mAtan( %positionDelta._0, %positionDelta._1 ) );
+        %angle = mAtan( %positionDelta ) - 90;
         
         
         // Fetch contact position.
         // Fetch contact position.
         %contactPosition = %collisionDetails._4 SPC %collisionDetails._5;
         %contactPosition = %collisionDetails._4 SPC %collisionDetails._5;

+ 18 - 7
modules/RotateToToy/1/main.cs

@@ -125,17 +125,23 @@ function RotateToToy::setTrackMouse( %this, %value )
 
 
 function RotateToToy::onTouchDown(%this, %touchID, %worldPosition)
 function RotateToToy::onTouchDown(%this, %touchID, %worldPosition)
 {
 {
-    // Calculate the angle to the mouse.
-    %origin = RotateToToy.TargetObject.getPosition();
-    %angle = -mRadToDeg( mAtan( %worldPosition.x-%origin.x, %worldPosition.y-%origin.y ) );
-    
-    //Rotate to the touched angle.
-    RotateToToy.TargetObject.RotateTo( %angle, RotateToToy.rotateSpeed );
+    %this.rotateTargetObject( %worldPosition );
 }
 }
 
 
 //-----------------------------------------------------------------------------
 //-----------------------------------------------------------------------------
 
 
 function RotateToToy::onTouchMoved(%this, %touchID, %worldPosition)
 function RotateToToy::onTouchMoved(%this, %touchID, %worldPosition)
+{
+    // Finish if not tracking the mouse.
+    if ( !RotateToToy.trackMouse )
+        return;
+        
+    %this.rotateTargetObject( %worldPosition );
+}
+
+//-----------------------------------------------------------------------------
+
+function RotateToToy::rotateTargetObject(%this, %worldPosition)
 {
 {
     // Finish if not tracking the mouse.
     // Finish if not tracking the mouse.
     if ( !RotateToToy.trackMouse )
     if ( !RotateToToy.trackMouse )
@@ -143,7 +149,12 @@ function RotateToToy::onTouchMoved(%this, %touchID, %worldPosition)
         
         
     // Calculate the angle to the mouse.
     // Calculate the angle to the mouse.
     %origin = RotateToToy.TargetObject.getPosition();
     %origin = RotateToToy.TargetObject.getPosition();
-    %angle = -mRadToDeg( mAtan( %worldPosition.x-%origin.x, %worldPosition.y-%origin.y ) );
+    %angle = mAtan( Vector2Sub( %worldPosition, %origin ) );
+    
+    // The target object points up (the 90-degree point in polar coordinates).
+    // We can simply subtract 90 from the calculate angle to make the
+    // object point to the mouse.
+    %angle -= 90;
     
     
     //Rotate to the touched angle.
     //Rotate to the touched angle.
     RotateToToy.TargetObject.RotateTo( %angle, RotateToToy.rotateSpeed );        
     RotateToToy.TargetObject.RotateTo( %angle, RotateToToy.rotateSpeed );