Browse Source

Merge remote-tracking branch 'refs/remotes/origin/development'

MelvMay-GG 12 years ago
parent
commit
cf2c6a9

+ 68 - 10
engine/source/2d/controllers/PointForceController.cc

@@ -39,6 +39,9 @@ PointForceController::PointForceController()
     mPosition.SetZero();
     mRadius = 1.0f;
     mForce = 0.0f;
+    mNonLinear = true;
+    mLinearDrag = 0.0f;
+    mAngularDrag = 0.0f;
 }
 
 //------------------------------------------------------------------------------
@@ -56,9 +59,12 @@ void PointForceController::initPersistFields()
     Parent::initPersistFields();
 
     // Force.
-    addProtectedField("Position", TypeVector2, Offset( mPosition, PointForceController), &defaultProtectedSetFn, &defaultProtectedGetFn, "The position of the attractor controller.");
-    addProtectedField("Radius", TypeF32, Offset( mRadius, PointForceController), &defaultProtectedSetFn, &defaultProtectedGetFn, "The radius of the attractor circle centered on the attractors position.");
-    addProtectedField("Force", TypeF32, Offset( mForce, PointForceController), &defaultProtectedSetFn, &defaultProtectedGetFn, "The force to apply to attact to the controller position.");
+    addField( "Position", TypeVector2, Offset( mPosition, PointForceController), "The position of the attractor controller.");
+    addField( "Radius", TypeF32, Offset( mRadius, PointForceController), "The radius of the attractor circle centered on the attractors position.");
+    addField( "Force", TypeF32, Offset( mForce, PointForceController), "The force to apply to attact to the controller position.");
+    addField( "NonLinear", TypeBool, Offset( mNonLinear, PointForceController), "Whether to apply the force non-linearly (using the inverse square law) or linearly.");
+    addField( "LinearDrag", TypeF32, Offset(mLinearDrag, PointForceController), "The linear drag co-efficient for the fluid." );
+    addField( "AngularDrag", TypeF32, Offset(mAngularDrag, PointForceController), "The angular drag co-efficient for the fluid." );
 }
 
 //------------------------------------------------------------------------------
@@ -100,8 +106,25 @@ void PointForceController::integrate( Scene* pScene, const F32 totalTime, const
     // Fetch results.
     typeWorldQueryResultVector& queryResults = pWorldQuery->getQueryResults();
 
+    // Fetch result count.
+    const U32 resultCount = (U32)queryResults.size();
+
+    // Finish if nothing to process.
+    if ( resultCount == 0 )
+        return;
+
+    // Calculate the radius squared.
+    const F32 radiusSqr = mRadius * mRadius;
+
+    // Calculate the force squared in-case we need it.
+    const F32 forceSqr = mForce * mForce * (( mForce < 0.0f ) ? -1.0f : 1.0f);
+
+    // Calculate drag coefficients (time-integrated).
+    const F32 linearDrag = mClampF( mLinearDrag, 0.0f, 1.0f ) * elapsedTime;
+    const F32 angularDrag = mClampF( mAngularDrag, 0.0f, 1.0f ) * elapsedTime;
+
     // Iterate the results.
-    for ( U32 n = 0; n < (U32)queryResults.size(); n++ )
+    for ( U32 n = 0; n < resultCount; n++ )
     {
         // Fetch the scene object.
         SceneObject* pSceneObject = queryResults[n].mpSceneObject;
@@ -110,18 +133,53 @@ void PointForceController::integrate( Scene* pScene, const F32 totalTime, const
         if ( pSceneObject->getBodyType() == b2_staticBody )
             continue;
 
-        // Calculate the force direction to the controllers position.
-        Vector2 forceDirection = mPosition - pSceneObject->getPosition();
+        // Calculate the force distance to the controllers position.
+        Vector2 distanceForce = mPosition - pSceneObject->getPosition();
 
         // Skip if the position is outside the radius.
-        if ( forceDirection.Length() > mRadius )
+        if ( distanceForce.LengthSquared() > radiusSqr )
             continue;
 
-        // Normalize to the specified force.
-        forceDirection.Normalize( mForce );
+        // Non-Linear force?
+        if ( mNonLinear )
+        {
+            // Yes, so use an approximation of the inverse-square law.
+            distanceForce *= (1.0f / distanceForce.LengthSquared()) * forceSqr;
+        }
+        else
+        {
+            // No, so normalize to the specified force (linear).
+            distanceForce.Normalize( mForce );
+        }
 
         // Apply the force.
-        pSceneObject->applyForce( forceDirection, true );
+        pSceneObject->applyForce( distanceForce, true );
+
+        // Linear drag?
+        if ( linearDrag > 0.0f )
+        {
+            // Yes, so fetch linear velocity.
+            Vector2 linearVelocity = pSceneObject->getLinearVelocity();
+
+            // Calculate linear velocity change.
+            const Vector2 linearVelocityDelta = linearVelocity * linearDrag;
+
+            // Set linear velocity.
+            pSceneObject->setLinearVelocity( linearVelocity - linearVelocityDelta );
+        }
+
+        // Angular drag?
+        if ( angularDrag > 0.0f )
+        {
+            // Yes, so fetch angular velocity.
+            F32 angularVelocity = pSceneObject->getAngularVelocity();
+
+            // Calculate angular velocity change.
+            const F32 angularVelocityDelta = angularVelocity * angularDrag;
+
+            // Set angular velocity.
+            pSceneObject->setAngularVelocity( angularVelocity - angularVelocityDelta );
+        }
     }
 }
 

+ 20 - 0
engine/source/2d/controllers/PointForceController.h

@@ -38,10 +38,24 @@ class PointForceController : public PickingSceneController
 private:
     typedef PickingSceneController Parent;
 
+    /// Controller position.
     Vector2 mPosition;
+
+    /// Controller radius.
     F32 mRadius;
+
+    /// Controller force.
     F32 mForce;
 
+    /// Whether to apply the force non-linearly (using the inverse square law) or linearly.
+    bool mNonLinear;
+
+	/// Linear drag co-efficient.
+	F32 mLinearDrag;
+
+	/// Linear drag co-efficient.
+	F32 mAngularDrag;
+
 public:
     PointForceController();
     virtual ~PointForceController();
@@ -55,6 +69,12 @@ public:
     inline F32 getRadius( void ) const { return mRadius; }
     inline void setForce( const F32 force ) { mForce = force; }
     inline F32 getForce( void ) const { return mForce; }
+    inline void setNonLinear( const bool nonLinear ) { mNonLinear = nonLinear; }
+    inline bool getNonLinear( void ) const { return mNonLinear; }
+    inline void setLinearDrag( const F32 linearDrag ) { mLinearDrag = linearDrag; }
+    inline F32 getLinearDrag( void ) const { return mLinearDrag; }
+    inline void setAngularDrag( const F32 angularDrag ) { mAngularDrag = angularDrag; }
+    inline F32 getAngularDrag( void ) const { return mAngularDrag; }
 
     /// Integration.
     virtual void integrate( Scene* pScene, const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats );

+ 52 - 0
engine/source/2d/controllers/PointForceController_ScriptBinding.h

@@ -92,3 +92,55 @@ ConsoleMethod(PointForceController, getForce, F32, 2, 2,        "() Gets the poi
 {
     return object->getForce();
 }
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, setLinearDrag, void, 3, 3,  "(linearDrag) - Sets the linear drag coefficient (0.0 to 1.0).\n"
+                                                                "@param linearDrag The linear drag coefficient\n"
+                                                                "@return No return value.")
+{
+    object->setLinearDrag( dAtof(argv[2]) );
+} 
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, getLinearDrag, F32, 2, 2,   "() Gets the linear drag coefficient.\n"
+                                                                "@return The linear drag coefficient.")
+{
+    return object->getLinearDrag();
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, setAngularDrag, void, 3, 3, "(angularDrag) - Sets the angular drag coefficient (0.0 to 1.0).\n"
+                                                                "@param angularDrag The angular drag coefficient\n"
+                                                                "@return No return value.")
+{
+    object->setAngularDrag( dAtof(argv[2]) );
+} 
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, getAngularDrag, F32, 2, 2,  "() Gets the angular drag coefficient.\n"
+                                                                "@return The angular drag coefficient.")
+{
+    return object->getAngularDrag();
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, setNonLinear, void, 3, 3,   "(nonLinear) - Sets whether to apply the force non-linearly (using the inverse square law) or linearly.\n"
+                                                                "@param nonLinear whether to apply the force non-linearly (using the inverse square law) or linearly.\n"
+                                                                "@return No return value.")
+{
+    object->setNonLinear( dAtob(argv[2]) );
+} 
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, getNonLinear, bool, 2, 2,  "() Gets whether to apply the force non-linearly (using the inverse square law) or linearly.\n"
+                                                                "@return Whether to apply the force non-linearly (using the inverse square law) or linearly.")
+{
+    return object->getNonLinear();
+}
+

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

@@ -105,10 +105,10 @@ public:
     inline bool getBatchCulling( void ) const { return mBatchCulling; }
 
     inline void setDefaultSpriteStride( const Vector2& defaultStride ) { mDefaultSpriteStride = defaultStride; }
-    inline Vector2 getDefaultSpriteStride( void ) const { return mDefaultSpriteStride; }
+    inline const Vector2& getDefaultSpriteStride( void ) const { return mDefaultSpriteStride; }
 
     inline void setDefaultSpriteSize( const Vector2& defaultSize ) { mDefaultSpriteSize = defaultSize; }
-    inline Vector2 getDefaultSpriteSize( void ) const { return mDefaultSpriteSize; }
+    inline const Vector2& getDefaultSpriteSize( void ) const { return mDefaultSpriteSize; }
 
     inline void setDefaultSpriteAngle( const F32 defaultAngle ) { mDefaultSpriteAngle = defaultAngle; }
     inline F32 getDefaultSpriteAngle( void ) const { return mDefaultSpriteAngle; }

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

@@ -127,6 +127,7 @@ struct Vector2 : b2Vec2
     inline F32 Normalize(const F32 s)                                   { const F32 length = Length(); if ( length > 0.0f ) m_point2F_normalize_f((F32*)this, s); return length; }
     inline Vector2& absolute(void)                                      { if (x < 0.0f) x = -x; if (y < 0.0f) y = -y; return *this; }
     inline Vector2& receiprocate(void)                                  { x = 1.0f/x; y = 1.0f/y; return *this; }
+    inline Vector2 getReceiprocate(void) const                          { Vector2 temp = *this; temp.receiprocate();return temp; }
     inline Vector2& add(const Vector2& v)                               { x += v.x; y += v.y; return *this; }
     inline Vector2& sub(const Vector2& v)                               { x -= v.x; y -= v.y; return *this; }
     inline Vector2& mult(const Vector2& v)                              { x *= v.x; y *= v.y; return *this; }
@@ -145,7 +146,7 @@ struct Vector2 : b2Vec2
     inline Vector2& clampMin(const Vector2& min)                        { if (x < min.x) x = min.x; if (y < min.y) y = min.y;  return *this; }
     inline Vector2& clampMax(const Vector2& max)                        { if (x > max.x) x = max.x; if (y > max.y) y = max.y;  return *this; }
     inline void rand(const Vector2& min, const Vector2& max)            { x = CoreMath::mGetRandomF(min.x, max.x), y = CoreMath::mGetRandomF(min.y,max.y); }
-    inline void round(const F32 epsilon = FLT_EPSILON)                  { F32 recip = 1.0f/epsilon; x = mFloor(x * recip + 0.5f) * epsilon; y = mFloor(y * recip + 0.5f) * epsilon; }
+    inline void round(const F32 epsilon = FLT_EPSILON)                  { x = mRound(x, epsilon); y = mRound(y, epsilon); }
 
     inline StringTableEntry stringThis(void) const                      { char buffer[32]; dSprintf(buffer, 32, "%g %g", x, y ); return StringTable->insert(buffer); }
     inline const char* scriptThis(void) const                           { char* pBuffer = Con::getReturnBuffer(32); dSprintf(pBuffer, 32, "%.5g %.5g", x, y ); return pBuffer; }

+ 0 - 1
modules/CollisionToy/1/main.cs

@@ -185,7 +185,6 @@ function CollisionToyBall::onCollision(%this, %object, %collisionDetails)
     // Create a marker sprite with a limited lifetime.
     // Also set this so that it can't be picked so you can't drag it via the Sandbox "pull" feature.
     %object = new Sprite();
-    //%object.BodyType = static;
     %object.Position = %contactPosition;
     %object.Layer = 10;   
     %object.Size = 3;

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

@@ -22,23 +22,45 @@
 
 function PointForceControllerToy::create( %this )
 {
+    // Activate the package.
+    activatePackage( PointForceControllerToyPackage );    
+    
     // Set the sandbox drag mode availability.
-    Sandbox.allowManipulation( pan );
     Sandbox.allowManipulation( pull );
     
     // Set the manipulation mode.
     Sandbox.useManipulation( pull );
     
-    // Configure settings.
-    PointForceControllerToy.ForceRadius = 20;
-    PointForceControllerToy.ForceMagnitude = 50;
-    PointForceControllerToy.DebrisCount = 100;
-
-    // Add options.    
-    addNumericOption("Force Radius", 1, 200, 1, "setForceRadius", PointForceControllerToy.ForceRadius, false, "The radius of the point force.");   
-    addNumericOption("Force Magnitude", -1000, 1000, 10, "setForceMagnitude", PointForceControllerToy.ForceMagnitude, false, "The magnitude of the point force.");   
-    addNumericOption("Debris Count", 10, 1000, 10, "setDebrisCount", PointForceControllerToy.DebrisCount, true, "The amount of debris to use.");
+    // Initialize the toys settings.
+    PointForceControllerToy.autoSpawnAsteroids = false;
+    PointForceControllerToy.showPlanetoid = true;
+    PointForceControllerToy.showExplosions = true;    
+    PointForceControllerToy.nonLinearController = true;
+    PointForceControllerToy.controllerForce = 35;
+    PointForceControllerToy.controllerRadius = 36;
+    PointForceControllerToy.controllerLinearDrag = 0.1;
+    PointForceControllerToy.controllerAngularDrag = 0;
+    PointForceControllerToy.planetoidSize = 26;
+    PointForceControllerToy.asteroidSize = 4;
+    PointForceControllerToy.asteroidDensity = 0.2;
+    PointForceControllerToy.asteroidLifetime = 10;
+    PointForceControllerToy.asteroidSpeed = 30;
     
+    // Add the custom controls.
+    addFlagOption("Auto Spawn Asteroids", "setAutoSpawnAsteroids", PointForceControllerToy.autoSpawnAsteroids, true, "Whether to auto-spawn asteroids or not." );
+    addFlagOption("Show Planetoid", "setShowPlanetoid", PointForceControllerToy.showPlanetoid, true, "Whether to show the planetoid or not or not." );
+    addFlagOption("Show Explosions", "setShowExplosions", PointForceControllerToy.showExplosions, false, "Whether to show the explosions or not or not." );
+    addFlagOption("Controller Non-Linear", "setNonLinearController", PointForceControllerToy.nonLinearController, true, " Whether to apply the controller force non-linearly (using the inverse square law) or linearly" );
+    addNumericOption("Controller Force", -1000, 1000, 10, "setControllerForce", PointForceControllerToy.controllerForce, true, "Sets the controller force.");
+    addNumericOption("Controller Radius", 1, 30, 1, "setControllerRadius", PointForceControllerToy.controllerRadius, true, "Sets the controller radius.");
+    addNumericOption("Controller Linear Drag", 0, 1, 0.1, "setControllerLinearDrag", PointForceControllerToy.controllerLinearDrag, true, "Sets the controller linear drag.");
+    addNumericOption("Controller Angular Drag", 0, 1, 0.1, "setControllerAngularDrag", PointForceControllerToy.controllerAngularDrag, true, "Sets the controller angular drag.");
+    addNumericOption("Planetoid Size", 1, 30, 1, "setPlanetoidSize", PointForceControllerToy.planetoidSize, true, "Sets the planetoid size.");
+    addNumericOption("Asteroid Size", 1, 10, 1, "setAsteroidSize", PointForceControllerToy.asteroidSize, true, "Sets the asteroid size.");
+    addNumericOption("Asteroid Density", 1, 10, 1, "setAsteroidDensity", PointForceControllerToy.asteroidDensity, true, "Sets the asteroid density.");
+    addNumericOption("Asteroid Lifetime", 1, 10, 1, "setAsteroidLifetime", PointForceControllerToy.asteroidLifetime, true, "Sets the asteroid lifetime.");
+    addNumericOption("Asteroid Speed", 1, 100, 1, "setAsteroidSpeed", PointForceControllerToy.asteroidSpeed, true, "Sets the asteroid speed.");
+      
     // Reset the toy.
     PointForceControllerToy.reset();
 }
@@ -48,6 +70,8 @@ function PointForceControllerToy::create( %this )
 
 function PointForceControllerToy::destroy( %this )
 {
+    // Deactivate the package.
+    deactivatePackage( PointForceControllerToyPackage );    
 }
 
 //-----------------------------------------------------------------------------
@@ -60,8 +84,12 @@ function PointForceControllerToy::reset( %this )
     // Create background.
     %this.createBackground();
     
-    // Create point force controller.
-    %this.createPointForceController();
+    // Create the planetoid.
+    %this.createPlanetoid();
+    
+    // Start a timer throwing asteroids.
+    if ( PointForceControllerToy.autoSpawnAsteroids )
+        %this.startTimer( "createAsteroid", 1000 );
 }
 
 //-----------------------------------------------------------------------------
@@ -69,136 +97,235 @@ function PointForceControllerToy::reset( %this )
 function PointForceControllerToy::createBackground( %this )
 {    
     // Create the sprite.
-    %object = new Sprite();
-    
-    // Set the sprite as "static" so it is not affected by gravity.
-    %object.setBodyType( static );
-       
-    // Always try to configure a scene-object prior to adding it to a scene for best performance.
+    %object = new Scroller();
+    %object.BodyType = static;
+    %object.Size = "200 150";
+    %object.SceneLayer = 31;
+    %object.Image = "ToyAssets:SkyBackground";  
+    %object.ScrollX = 2;
+    SandboxScene.add( %object );    
+}
 
-    // Set the position.
-    %object.Position = "0 0";
+//-----------------------------------------------------------------------------
 
-    // Set the size.        
-    %object.Size = "100 75";
-    
-    // Set to the furthest background layer.
-    %object.SceneLayer = 31;
+function PointForceControllerToy::createPlanetoid( %this )
+{
+    if ( PointForceControllerToy.showPlanetoid )
+    {
+        // Create the planetoid.
+        %object = new Sprite()
+        {
+            class = "Planetoid";
+        };
+        //%object.BodyType = static;
+        %object.Size = PointForceControllerToy.planetoidSize;
+        %object.Image = "ToyAssets:Planetoid";
+        %object.AngularVelocity = -5;
+        %object.setDefaultDensity( 10000 );
+        %object.createCircleCollisionShape( PointForceControllerToy.planetoidSize * 0.48 );
+        %object.CollisionCallback = true;
+        SandboxScene.add( %object );
+    }
     
-    // Set the scroller to use an animation!
-    %object.Image = "ToyAssets:highlightBackground";
+    // Create planetoid bubble.
+    %player = new ParticlePlayer();
+    %player.BodyType = static;
+    %player.Particle = "ToyAssets:ForceBubble";
+    %player.SceneLayer = 0;
+    SandboxScene.add( %player );
+        
+    // Create a new controller.
+    %controller = new PointForceController();
+    %controller.setControlLayers( 10 ); // Only affect asteroids.
+    %controller.Radius = PointForceControllerToy.controllerRadius;
+    %controller.Force = PointForceControllerToy.ControllerForce;
+    %controller.NonLinear = PointForceControllerToy.nonLinearController;
+    %controller.LinearDrag = PointForceControllerToy.controllerLinearDrag;
+    %controller.AngularDrag = PointForceControllerToy.controllerAngularDrag;
+    SandboxScene.Controllers.add( %controller );
     
-    // Set the blend color.
-    %object.BlendColor = SlateGray;
+    // This is so we can reference it in the toy, no other reason.
+    PointForceControllerToy.Controller = %controller;
+}
+
+//-----------------------------------------------------------------------------
+
+function Planetoid::onCollision( %this, %object, %collisionDetails )
+{
+    // Are we showing explosions?
+    if ( PointForceControllerToy.showExplosions )
+    {
+        // Yes, so calculate position angle.
+        %positionDelta = Vector2Sub( %object.Position, %this.Position );
+        %angle = -mRadToDeg( mAtan( %positionDelta._0, %positionDelta._1 ) );
+        
+        // Fetch contact position.
+        %contactPosition = %collisionDetails._4 SPC %collisionDetails._5;
+        
+        // Calculate total impact force.
+        %impactForce = mAbs(%collisionDetails._6 / 100) + mAbs(%collisionDetails._7 / 20);
+        
+        // Create explosion.
+        %player = new ParticlePlayer();
+        %player.BodyType = static;
+        %player.Particle = "ToyAssets:impactExplosion";
+        %player.Position = %contactPosition;
+        %player.Angle = %angle;
+        %player.SizeScale = mClamp( %impactForce, 0.1, 10 );
+        %player.SceneLayer = 0;
+        SandboxScene.add( %player );            
+    }
     
-    // Create border collisions.
-    %object.createEdgeCollisionShape( -50, -37.5, -50, 37.5 );
-    %object.createEdgeCollisionShape( 50, -37.5, 50, 37.5 );
-    %object.createEdgeCollisionShape( -50, 37.5, 50, 37.5 );
-    %object.createEdgeCollisionShape( -50, -34.5, 50, -34.5 );
-           
-    // Add the sprite to the scene.
-    SandboxScene.add( %object );    
+    // Delete the asteroid.
+    %object.Trail.LinearVelocity = 0;
+    %object.Trail.AngularVelocity = 0;
+    %object.Trail.safeDelete();
+    %object.safeDelete();  
 }
 
 //-----------------------------------------------------------------------------
 
-function PointForceControllerToy::createSprite( %this, %asset, %position, %size, %angle, %blendColor )
-{    
-    // Create the sprite.
+function PointForceControllerToy::createAsteroid( %this, %position )
+{
+    // Create an asteroid.
     %object = new Sprite();
+    %object.Position = %position !$= "" ? %position : -40 SPC getRandom(-35,35);
+    %object.Size = PointForceControllerToy.asteroidSize;
+    %object.Image = "ToyAssets:Asteroids";
+    %object.ImageFrame = getRandom(0,3);
+    %object.SceneLayer = 10;
+    %object.setDefaultDensity( PointForceControllerToy.asteroidDensity );
+    %object.createCircleCollisionShape( PointForceControllerToy.asteroidSize * 0.4 );
+    %object.setLinearVelocity( PointForceControllerToy.asteroidSpeed, 0 );
+    %object.setAngularVelocity( getRandom(-90,90) );
+    %object.setLifetime( PointForceControllerToy.asteroidLifetime );  
+    SandboxScene.add( %object ); 
     
-    // Set the position.
-    %object.Position = %position;
+    // Create fire trail.
+    %player = new ParticlePlayer();
+    %player.Particle = "ToyAssets:bonfire";
+    %player.Position = %object.Position;
+    %player.EmissionRateScale = 3;
+    %player.SizeScale = 2;
+    %player.SceneLayer = 11;
+    %player.setLifetime( PointForceControllerToy.asteroidLifetime );  
+    SandboxScene.add( %player );
+    %jointId = SandboxScene.createRevoluteJoint( %object, %player );
+    SandboxScene.setRevoluteJointLimit( %jointId, 0, 0 );    
 
-    // Set the size.        
-    %object.Size = %size;
-    
-    // Set the angle.
-    %object.Angle = %angle;
-       
-    // Set the scroller to use an animation!
-    %object.Image = %asset;
-    
-    // Set the blend color.
-    %object.BlendColor = %blendColor $= "" ? White : %blendColor;
+    %object.Trail = %player;
             
-    // Add the sprite to the scene.
-    SandboxScene.add( %object );    
-    
     return %object;
 }
 
 //-----------------------------------------------------------------------------
 
-function PointForceControllerToy::createPointForceController( %this )
+function PointForceControllerToy::setAutoSpawnAsteroids( %this, %value )
 {
-    // Create a new controller.
-    %controller = new PointForceController();
-    
-    // Set scene controller.
-    PointForceControllerToy.SceneController = %controller;
+    %this.autoSpawnAsteroids = %value;
+}
 
-    // Update the point force controller.
-    %this.updatePointForceController();
-    
-    // Add the controller.
-    SandboxScene.Controllers.add( %controller );
-   
-    // Create some sprites used by the controller.
-    for( %n = 0; %n < PointForceControllerToy.DebrisCount; %n++ )
-    {    
-        %sizeX = getRandom(1,4);
-        %sizeY = getRandom(1,4);
-        %size = %sizeX SPC %sizeY;
-        
-        // Create some sprites.
-        %sprite = %this.createSprite( "ToyAssets:blocks", getRandom(-40,40) SPC getRandom(-30,30), %size, getRandom(0,360), White );
-        %sprite.Frame = getRandom( 0, 55 );
-        %sprite.createPolygonBoxCollisionShape( %sizeX, %sizeY );
-        %sprite.setAngularVelocity(getRandom(-180,180));
-        
-        // Add to the controller.
-        %controller.add( %sprite );
-    }   
-    
+//-----------------------------------------------------------------------------
+
+function PointForceControllerToy::setShowPlanetoid( %this, %value )
+{
+    %this.showPlanetoid = %value;
 }
 
 //-----------------------------------------------------------------------------
 
-function PointForceControllerToy::updatePointForceController( %this )
+function AngryBirdsSpaceToy::setShowExplosions( %this, %value )
 {
-    // Fetch the controller.
-    %controller = PointForceControllerToy.SceneController;
-    
-    // Update the controller.
-    %controller.Radius = %this.ForceRadius;
-    %controller.Force = %this.ForceMagnitude;
+    %this.showExplosions = %value;
 }
 
 //-----------------------------------------------------------------------------
 
-function PointForceControllerToy::setForceRadius(%this, %value)
+function PointForceControllerToy::setNonLinearController( %this, %value )
 {
-    %this.ForceRadius = %value;
-    
-    // Update the controller.
-    %this.updatePointForceController();   
+    %this.nonLinearController = %value;
 }
 
 //-----------------------------------------------------------------------------
 
-function PointForceControllerToy::setForceMagnitude(%this, %value)
+function PointForceControllerToy::setControllerForce( %this, %value )
 {
-    %this.ForceMagnitude = %value;
-    
-    // Update the controller.
-    %this.updatePointForceController();   
+    %this.controllerForce = %value;
+}
+
+//-----------------------------------------------------------------------------
+
+function PointForceControllerToy::setControllerRadius( %this, %value )
+{
+    %this.controllerRadius = %value;
+}
+
+//-----------------------------------------------------------------------------
+
+function PointForceControllerToy::setControllerLinearDrag( %this, %value )
+{
+    %this.controllerLinearDrag = %value;
+}
+
+//-----------------------------------------------------------------------------
+
+function PointForceControllerToy::setControllerAngularDrag( %this, %value )
+{
+    %this.controllerAngularDrag = %value;
+}
+
+//-----------------------------------------------------------------------------
+
+function PointForceControllerToy::setPlanetoidSize( %this, %value )
+{
+    %this.planetoidSize = %value;
+}
+
+//-----------------------------------------------------------------------------
+
+function PointForceControllerToy::setAsteroidSize( %this, %value )
+{
+    %this.asteroidSize = %value;
+}
+
+//-----------------------------------------------------------------------------
+
+function PointForceControllerToy::setAsteroidDensity( %this, %value )
+{
+    %this.asteroidDensity = %value;
 }
 
 //-----------------------------------------------------------------------------
 
-function PointForceControllerToy::setDebrisCount(%this, %value)
+function PointForceControllerToy::setAsteroidLifetime( %this, %value )
 {
-    %this.DebrisCount = %value;
+    %this.asteroidLifetime = %value;
 }
+
+//-----------------------------------------------------------------------------
+
+function PointForceControllerToy::setAsteroidSpeed( %this, %value )
+{
+    %this.asteroidSpeed = %value;
+}
+
+//-----------------------------------------------------------------------------
+
+package PointForceControllerToyPackage
+{
+
+function SandboxWindow::onTouchDown(%this, %touchID, %worldPosition)
+{
+    // Call parent.
+    Parent::onTouchDown(%this, %touchID, %worldPosition );
+
+    // Create an asteroid.
+    %object = PointForceControllerToy.createAsteroid( %worldPosition );
+    
+    if ( %worldPosition.x < PointForceControllerToy.Controller.Position.x )
+        %object.setLinearVelocity( PointForceControllerToy.asteroidSpeed, 0 );
+    else
+        %object.setLinearVelocity( -PointForceControllerToy.asteroidSpeed, 0 );    
+}
+    
+};

+ 1 - 1
modules/PointForceControllerToy/1/module.taml

@@ -1,7 +1,7 @@
 <ModuleDefinition
 	ModuleId="PointForceControllerToy"
 	VersionId="1"
-	Description="Demonstrates using a point-force controller."
+	Description="Demonstrates the point-force controller."
 	Dependencies="ToyAssets=1"
 	Type="toy"
 	ToyCategoryIndex="3"

+ 3 - 0
modules/ToyAssets/1/assets/images/Planetoid.asset.taml

@@ -0,0 +1,3 @@
+<ImageAsset
+    AssetName="Planetoid"
+    ImageFile="Planetoid.png" />

BIN
modules/ToyAssets/1/assets/images/Planetoid.png


+ 49 - 0
modules/ToyAssets/1/assets/particles/forceBubble.asset.taml

@@ -0,0 +1,49 @@
+<ParticleAsset
+    AssetName="ForceBubble">
+    <ParticleAssetEmitter
+        EmitterName="PermanentBubble"
+        Image="@asset=ToyAssets:Particles5"
+        Frame="1"
+		SingleParticle="1">
+        <ParticleAssetEmitter.Fields>
+            <SizeX>
+				<Key Time="0" Value="72"/>
+            </SizeX>
+            <AlphaChannel>
+				<Key Time="0" Value="0.2"/>
+			</AlphaChannel>
+        </ParticleAssetEmitter.Fields>
+    </ParticleAssetEmitter>
+    <ParticleAssetEmitter
+        EmitterName="MovingBubbles"
+        Image="@asset=ToyAssets:Particles5"
+        Frame="1">
+        <ParticleAssetEmitter.Fields>
+            <Quantity>
+				<Key Time="0" Value="0.2"/>
+            </Quantity>
+            <QuantityVariation>
+				<Key Time="0" Value="0.1"/>
+            </QuantityVariation>			
+            <Lifetime>
+				<Key Time="0" Value="5"/>
+            </Lifetime>						
+            <Speed>
+				<Key Time="0" Value="0"/>
+            </Speed>			
+            <SizeX>
+				<Key Time="0" Value="72.0"/>
+            </SizeX>			
+            <SizeXLife>
+				<Key Time="0" Value="0.3"/>
+				<Key Time="1" Value="1.0"/>
+            </SizeXLife>			
+            <AlphaChannel>
+				<Key Time="0.0" Value="0.0"/>
+				<Key Time="0.3" Value="0.2"/>
+				<Key Time="0.9" Value="0.1"/>
+				<Key Time="1.0" Value="0.0"/>				
+			</AlphaChannel>
+        </ParticleAssetEmitter.Fields>
+    </ParticleAssetEmitter>	
+</ParticleAsset>

+ 4 - 0
modules/ToyAssets/1/assets/particles/impactExplosion.asset.taml

@@ -7,6 +7,8 @@
         EmitterType="BOX"
         EmitterAngle="90"
         EmitterSize="2 1"
+		AttachPositionToEmitter="1"
+		AttachRotationToEmitter="1"
         FixedForceAngle="-90"
         OldestInFront="1"
         Image="@asset=ToyAssets:Asteroids"
@@ -44,6 +46,8 @@
         EmitterName="flames"
         EmitterType="LINE"
         EmitterSize="1 0"
+		AttachPositionToEmitter="1"
+		AttachRotationToEmitter="1"		
         IntenseParticles="1"
         OldestInFront="1"
         Animation="@asset=ToyAssets:Impact_ExplosionAnimation">

+ 6 - 0
tools/VisualStudioVisualizer/VS2012/T2D_Vector2.natvis

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<AutoVisualizer xmlns="http://schemas.microsoft.com/vstudio/debugger/natvis/2010">
+    <Type Name="b2Vec2">
+		<DisplayString>{{ X = {x}, Y = {y} }}</DisplayString>
+    </Type>
+</AutoVisualizer>