Browse Source

- Reorganized controllers into a picking/grouped hierarchy.
- Renamed the ConstantForceController to AmbientForceController
- Added Script-Bindings for controllers.
- Buoyancy controller is now a picked controller and is specified by area.

MelvMay-GG 12 years ago
parent
commit
7ed1f79
48 changed files with 948 additions and 571 deletions
  1. 10 6
      engine/compilers/VisualStudio 2012/Torque 2D.vcxproj
  2. 33 18
      engine/compilers/VisualStudio 2012/Torque 2D.vcxproj.filters
  3. 34 16
      engine/compilers/Xcode/Torque2D.xcodeproj/project.pbxproj
  4. 34 16
      engine/compilers/Xcode_iOS/Torque2D.xcodeproj/project.pbxproj
  5. 12 12
      engine/source/2d/controllers/AmbientForceController.cc
  6. 10 10
      engine/source/2d/controllers/AmbientForceController.h
  7. 6 6
      engine/source/2d/controllers/AmbientForceController_ScriptBinding.h
  8. 16 19
      engine/source/2d/controllers/BuoyancyController.cc
  9. 4 4
      engine/source/2d/controllers/BuoyancyController.h
  10. 2 6
      engine/source/2d/controllers/PointForceController.cc
  11. 11 7
      engine/source/2d/controllers/PointForceController.h
  12. 71 0
      engine/source/2d/controllers/PointForceController_ScriptBinding.h
  13. 11 37
      engine/source/2d/controllers/core/GroupedSceneController.cc
  14. 13 22
      engine/source/2d/controllers/core/GroupedSceneController.h
  15. 0 0
      engine/source/2d/controllers/core/GroupedSceneController_ScriptBinding.h
  16. 79 0
      engine/source/2d/controllers/core/PickingSceneController.cc
  17. 76 0
      engine/source/2d/controllers/core/PickingSceneController.h
  18. 187 0
      engine/source/2d/controllers/core/PickingSceneController_ScriptBinding.h
  19. 48 0
      engine/source/2d/controllers/core/SceneController.h
  20. 8 29
      engine/source/2d/scene/Scene.cc
  21. 6 13
      engine/source/2d/sceneobject/SceneObject.cc
  22. 4 5
      engine/source/2d/sceneobject/SceneObject.h
  23. 114 113
      engine/source/2d/sceneobject/SceneObject_ScriptBinding.h
  24. 2 0
      engine/source/sim/simObject.h
  25. 30 30
      modules/AmbientForceControllerToy/1/main.cs
  26. 2 2
      modules/AmbientForceControllerToy/1/module.taml
  27. 0 3
      modules/BuoyancyControllerToy/1/assets/images/background.asset.taml
  28. BIN
      modules/BuoyancyControllerToy/1/assets/images/background.jpg
  29. 0 3
      modules/BuoyancyControllerToy/1/assets/images/beam.asset.taml
  30. BIN
      modules/BuoyancyControllerToy/1/assets/images/beam.png
  31. 0 3
      modules/BuoyancyControllerToy/1/assets/images/bubble.asset.taml
  32. BIN
      modules/BuoyancyControllerToy/1/assets/images/bubble.png
  33. 0 3
      modules/BuoyancyControllerToy/1/assets/images/rocksfar.asset.taml
  34. BIN
      modules/BuoyancyControllerToy/1/assets/images/rocksfar.png
  35. 0 3
      modules/BuoyancyControllerToy/1/assets/images/rocksnear.asset.taml
  36. BIN
      modules/BuoyancyControllerToy/1/assets/images/rocksnear.png
  37. 0 3
      modules/BuoyancyControllerToy/1/assets/images/wave.asset.taml
  38. BIN
      modules/BuoyancyControllerToy/1/assets/images/wave.png
  39. 3 0
      modules/BuoyancyControllerToy/1/assets/images/waveCrests.asset.taml
  40. BIN
      modules/BuoyancyControllerToy/1/assets/images/waveCrests.png
  41. 116 176
      modules/BuoyancyControllerToy/1/main.cs
  42. 1 1
      modules/MoveToToy/1/main.cs
  43. 1 1
      modules/PointForceControllerToy/1/main.cs
  44. 1 1
      modules/RotateToToy/1/main.cs
  45. 1 1
      modules/SceneLayerToy/1/main.cs
  46. 1 1
      modules/SpriteToy/1/main.cs
  47. BIN
      modules/ToyAssets/1/assets/images/highlightBackground.png
  48. 1 1
      modules/TruckToy/1/main.cs

+ 10 - 6
engine/compilers/VisualStudio 2012/Torque 2D.vcxproj

@@ -246,10 +246,11 @@
     <ClCompile Include="..\..\source\2d\assets\ParticleAssetEmitter.cc" />
     <ClCompile Include="..\..\source\2d\assets\ParticleAssetField.cc" />
     <ClCompile Include="..\..\source\2d\assets\ParticleAssetFieldCollection.cc" />
+    <ClCompile Include="..\..\source\2d\controllers\AmbientForceController.cc" />
+    <ClCompile Include="..\..\source\2d\controllers\core\GroupedSceneController.cc" />
+    <ClCompile Include="..\..\source\2d\controllers\core\PickingSceneController.cc" />
     <ClCompile Include="..\..\source\2d\controllers\PointForceController.cc" />
     <ClCompile Include="..\..\source\2d\controllers\BuoyancyController.cc" />
-    <ClCompile Include="..\..\source\2d\controllers\ConstantForceController.cc" />
-    <ClCompile Include="..\..\source\2d\controllers\SceneController.cc" />
     <ClCompile Include="..\..\source\2d\core\BatchRender.cc" />
     <ClCompile Include="..\..\source\2d\core\CoreMath.cc" />
     <ClCompile Include="..\..\source\2d\core\ParticleSystem.cc" />
@@ -625,14 +626,17 @@
     <ClInclude Include="..\..\source\2d\assets\ParticleAssetField.h" />
     <ClInclude Include="..\..\source\2d\assets\ParticleAssetFieldCollection.h" />
     <ClInclude Include="..\..\source\2d\assets\ParticleAsset_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\controllers\AmbientForceController.h" />
+    <ClInclude Include="..\..\source\2d\controllers\AmbientForceController_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\controllers\core\GroupedSceneController.h" />
+    <ClInclude Include="..\..\source\2d\controllers\core\GroupedSceneController_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\controllers\core\PickingSceneController.h" />
+    <ClInclude Include="..\..\source\2d\controllers\core\PickingSceneController_ScriptBinding.h" />
+    <ClInclude Include="..\..\source\2d\controllers\core\SceneController.h" />
     <ClInclude Include="..\..\source\2d\controllers\PointForceController.h" />
     <ClInclude Include="..\..\source\2d\controllers\PointForceController_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\controllers\BuoyancyController.h" />
     <ClInclude Include="..\..\source\2d\controllers\BuoyancyController_ScriptBinding.h" />
-    <ClInclude Include="..\..\source\2d\controllers\ConstantForceController.h" />
-    <ClInclude Include="..\..\source\2d\controllers\ConstantForceController_ScriptBinding.h" />
-    <ClInclude Include="..\..\source\2d\controllers\SceneController.h" />
-    <ClInclude Include="..\..\source\2d\controllers\SceneController_ScriptBinding.h" />
     <ClInclude Include="..\..\source\2d\core\BatchRender.h" />
     <ClInclude Include="..\..\source\2d\core\CoreMath.h" />
     <ClInclude Include="..\..\source\2d\core\ParticleSystem.h" />

+ 33 - 18
engine/compilers/VisualStudio 2012/Torque 2D.vcxproj.filters

@@ -169,6 +169,9 @@
     <Filter Include="2d\controllers">
       <UniqueIdentifier>{a9e97335-bed5-4f6a-9959-12f5f41dbdcb}</UniqueIdentifier>
     </Filter>
+    <Filter Include="2d\controllers\core">
+      <UniqueIdentifier>{e11e344e-6418-4ed0-980a-77d66cd64d65}</UniqueIdentifier>
+    </Filter>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="..\..\source\audio\audio.cc">
@@ -1272,24 +1275,27 @@
     <ClCompile Include="..\..\source\persistence\taml\tamlCustom.cc">
       <Filter>persistence\taml</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\source\2d\controllers\SceneController.cc">
-      <Filter>2d\controllers</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectSet.cc">
       <Filter>2d\sceneobject</Filter>
     </ClCompile>
     <ClCompile Include="..\..\source\2d\sceneobject\SceneObjectList.cc">
       <Filter>2d\sceneobject</Filter>
     </ClCompile>
-    <ClCompile Include="..\..\source\2d\controllers\ConstantForceController.cc">
-      <Filter>2d\controllers</Filter>
-    </ClCompile>
     <ClCompile Include="..\..\source\2d\controllers\BuoyancyController.cc">
       <Filter>2d\controllers</Filter>
     </ClCompile>
     <ClCompile Include="..\..\source\2d\controllers\PointForceController.cc">
       <Filter>2d\controllers</Filter>
     </ClCompile>
+    <ClCompile Include="..\..\source\2d\controllers\core\GroupedSceneController.cc">
+      <Filter>2d\controllers\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\2d\controllers\core\PickingSceneController.cc">
+      <Filter>2d\controllers\core</Filter>
+    </ClCompile>
+    <ClCompile Include="..\..\source\2d\controllers\AmbientForceController.cc">
+      <Filter>2d\controllers</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="..\..\source\audio\audio.h">
@@ -2607,12 +2613,6 @@
     <ClInclude Include="..\..\source\sim\simObjectTimerEvent.h">
       <Filter>sim</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\source\2d\controllers\SceneController.h">
-      <Filter>2d\controllers</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\source\2d\controllers\SceneController_ScriptBinding.h">
-      <Filter>2d\controllers</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectSet.h">
       <Filter>2d\sceneobject</Filter>
     </ClInclude>
@@ -2622,12 +2622,6 @@
     <ClInclude Include="..\..\source\2d\sceneobject\SceneObjectSet_ScriptBinding.h">
       <Filter>2d\sceneobject</Filter>
     </ClInclude>
-    <ClInclude Include="..\..\source\2d\controllers\ConstantForceController.h">
-      <Filter>2d\controllers</Filter>
-    </ClInclude>
-    <ClInclude Include="..\..\source\2d\controllers\ConstantForceController_ScriptBinding.h">
-      <Filter>2d\controllers</Filter>
-    </ClInclude>
     <ClInclude Include="..\..\source\2d\controllers\BuoyancyController.h">
       <Filter>2d\controllers</Filter>
     </ClInclude>
@@ -2640,6 +2634,27 @@
     <ClInclude Include="..\..\source\2d\controllers\PointForceController_ScriptBinding.h">
       <Filter>2d\controllers</Filter>
     </ClInclude>
+    <ClInclude Include="..\..\source\2d\controllers\core\GroupedSceneController.h">
+      <Filter>2d\controllers\core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\controllers\core\GroupedSceneController_ScriptBinding.h">
+      <Filter>2d\controllers\core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\controllers\core\PickingSceneController.h">
+      <Filter>2d\controllers\core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\controllers\core\PickingSceneController_ScriptBinding.h">
+      <Filter>2d\controllers\core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\controllers\core\SceneController.h">
+      <Filter>2d\controllers\core</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\controllers\AmbientForceController.h">
+      <Filter>2d\controllers</Filter>
+    </ClInclude>
+    <ClInclude Include="..\..\source\2d\controllers\AmbientForceController_ScriptBinding.h">
+      <Filter>2d\controllers</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <CustomBuild Include="..\..\source\math\mMath_ASM.asm">

+ 34 - 16
engine/compilers/Xcode/Torque2D.xcodeproj/project.pbxproj

@@ -11,10 +11,12 @@
 		2A033011165D1D4100E9CD70 /* platformFileIoTests.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2A033010165D1D4100E9CD70 /* platformFileIoTests.cc */; };
 		2A25739016A48DAC00363C6F /* ParticlePlayer.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2A25738E16A48DAC00363C6F /* ParticlePlayer.cc */; };
 		2A6F78CE16A4528C005C76D9 /* ParticleAssetEmitter.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2A6F78CC16A4528C005C76D9 /* ParticleAssetEmitter.cc */; };
-		2AA6865916D6992B003CEF0A /* SceneController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AA6865716D6992B003CEF0A /* SceneController.cc */; };
 		2AA6865F16D69943003CEF0A /* SceneObjectList.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AA6865A16D69943003CEF0A /* SceneObjectList.cc */; };
 		2AA6866016D69943003CEF0A /* SceneObjectSet.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AA6865D16D69943003CEF0A /* SceneObjectSet.cc */; };
 		2AB14A0516D7CDC300EABBF2 /* PointForceController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB14A0316D7CDC200EABBF2 /* PointForceController.cc */; };
+		2AB4C19E16DE9F0600B02479 /* GroupedSceneController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB4C19816DE9F0600B02479 /* GroupedSceneController.cc */; };
+		2AB4C19F16DE9F0600B02479 /* PickingSceneController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB4C19B16DE9F0600B02479 /* PickingSceneController.cc */; };
+		2AB4C1A316DE9F1100B02479 /* AmbientForceController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB4C1A116DE9F1100B02479 /* AmbientForceController.cc */; };
 		2AB97A1D16B66BC70080F940 /* tamlCustom.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB97A1B16B66BC70080F940 /* tamlCustom.cc */; };
 		2ABF5C8F16569A0C00BBBF1D /* osxMutex.mm in Sources */ = {isa = PBXBuildFile; fileRef = 2ABF5C8E16569A0C00BBBF1D /* osxMutex.mm */; };
 		2AC4404516B0142B00FC4091 /* ImageFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AC4404316B0142B00FC4091 /* ImageFont.cc */; };
@@ -22,7 +24,6 @@
 		2ACFC0A8166CE1AB00FE7370 /* platformMemoryTests.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2ACFC0A7166CE1AB00FE7370 /* platformMemoryTests.cc */; };
 		2ADCAC1516A41E5500E07619 /* ParticleAsset.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2ADCAC1116A41E5500E07619 /* ParticleAsset.cc */; };
 		2ADCAC1716A41E5500E07619 /* ParticleAssetField.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2ADCAC1316A41E5500E07619 /* ParticleAssetField.cc */; };
-		2AE2F55116D6AB3100B6A058 /* ConstantForceController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AE2F54F16D6AB3100B6A058 /* ConstantForceController.cc */; };
 		2AE2F55D16D6B08800B6A058 /* BuoyancyController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AE2F55B16D6B08800B6A058 /* BuoyancyController.cc */; };
 		2AE5B54216A6D860006908D5 /* ParticleAssetFieldCollection.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AE5B54016A6D860006908D5 /* ParticleAssetFieldCollection.cc */; };
 		2AE851D21681E56E00193F17 /* color.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AE851D11681E56E00193F17 /* color.cc */; };
@@ -457,9 +458,6 @@
 		2A25738F16A48DAC00363C6F /* ParticlePlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticlePlayer.h; sourceTree = "<group>"; };
 		2A6F78CC16A4528C005C76D9 /* ParticleAssetEmitter.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleAssetEmitter.cc; sourceTree = "<group>"; };
 		2A6F78CD16A4528C005C76D9 /* ParticleAssetEmitter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleAssetEmitter.h; sourceTree = "<group>"; };
-		2AA6865616D6992B003CEF0A /* SceneController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SceneController_ScriptBinding.h; path = controllers/SceneController_ScriptBinding.h; sourceTree = "<group>"; };
-		2AA6865716D6992B003CEF0A /* SceneController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SceneController.cc; path = controllers/SceneController.cc; sourceTree = "<group>"; };
-		2AA6865816D6992B003CEF0A /* SceneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SceneController.h; path = controllers/SceneController.h; sourceTree = "<group>"; };
 		2AA6865A16D69943003CEF0A /* SceneObjectList.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneObjectList.cc; sourceTree = "<group>"; };
 		2AA6865B16D69943003CEF0A /* SceneObjectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObjectList.h; sourceTree = "<group>"; };
 		2AA6865C16D69943003CEF0A /* SceneObjectSet_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObjectSet_ScriptBinding.h; sourceTree = "<group>"; };
@@ -468,6 +466,16 @@
 		2AB14A0216D7CDC200EABBF2 /* PointForceController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PointForceController_ScriptBinding.h; path = controllers/PointForceController_ScriptBinding.h; sourceTree = "<group>"; };
 		2AB14A0316D7CDC200EABBF2 /* PointForceController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PointForceController.cc; path = controllers/PointForceController.cc; sourceTree = "<group>"; };
 		2AB14A0416D7CDC300EABBF2 /* PointForceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PointForceController.h; path = controllers/PointForceController.h; sourceTree = "<group>"; };
+		2AB4C19716DE9F0600B02479 /* GroupedSceneController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GroupedSceneController_ScriptBinding.h; path = controllers/core/GroupedSceneController_ScriptBinding.h; sourceTree = "<group>"; };
+		2AB4C19816DE9F0600B02479 /* GroupedSceneController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GroupedSceneController.cc; path = controllers/core/GroupedSceneController.cc; sourceTree = "<group>"; };
+		2AB4C19916DE9F0600B02479 /* GroupedSceneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GroupedSceneController.h; path = controllers/core/GroupedSceneController.h; sourceTree = "<group>"; };
+		2AB4C19A16DE9F0600B02479 /* PickingSceneController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PickingSceneController_ScriptBinding.h; path = controllers/core/PickingSceneController_ScriptBinding.h; sourceTree = "<group>"; };
+		2AB4C19B16DE9F0600B02479 /* PickingSceneController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PickingSceneController.cc; path = controllers/core/PickingSceneController.cc; sourceTree = "<group>"; };
+		2AB4C19C16DE9F0600B02479 /* PickingSceneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PickingSceneController.h; path = controllers/core/PickingSceneController.h; sourceTree = "<group>"; };
+		2AB4C19D16DE9F0600B02479 /* SceneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SceneController.h; path = controllers/core/SceneController.h; sourceTree = "<group>"; };
+		2AB4C1A016DE9F1100B02479 /* AmbientForceController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AmbientForceController_ScriptBinding.h; path = controllers/AmbientForceController_ScriptBinding.h; sourceTree = "<group>"; };
+		2AB4C1A116DE9F1100B02479 /* AmbientForceController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AmbientForceController.cc; path = controllers/AmbientForceController.cc; sourceTree = "<group>"; };
+		2AB4C1A216DE9F1100B02479 /* AmbientForceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AmbientForceController.h; path = controllers/AmbientForceController.h; sourceTree = "<group>"; };
 		2AB97A1B16B66BC70080F940 /* tamlCustom.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tamlCustom.cc; sourceTree = "<group>"; };
 		2AB97A1C16B66BC70080F940 /* tamlCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tamlCustom.h; sourceTree = "<group>"; };
 		2ABF5C8E16569A0C00BBBF1D /* osxMutex.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = osxMutex.mm; sourceTree = "<group>"; };
@@ -484,9 +492,6 @@
 		2ADCAC1216A41E5500E07619 /* ParticleAsset.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleAsset.h; sourceTree = "<group>"; };
 		2ADCAC1316A41E5500E07619 /* ParticleAssetField.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ParticleAssetField.cc; sourceTree = "<group>"; };
 		2ADCAC1416A41E5500E07619 /* ParticleAssetField.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ParticleAssetField.h; sourceTree = "<group>"; };
-		2AE2F54E16D6AB3100B6A058 /* ConstantForceController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConstantForceController_ScriptBinding.h; path = controllers/ConstantForceController_ScriptBinding.h; sourceTree = "<group>"; };
-		2AE2F54F16D6AB3100B6A058 /* ConstantForceController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConstantForceController.cc; path = controllers/ConstantForceController.cc; sourceTree = "<group>"; };
-		2AE2F55016D6AB3100B6A058 /* ConstantForceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConstantForceController.h; path = controllers/ConstantForceController.h; sourceTree = "<group>"; };
 		2AE2F55A16D6B08800B6A058 /* BuoyancyController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BuoyancyController_ScriptBinding.h; path = controllers/BuoyancyController_ScriptBinding.h; sourceTree = "<group>"; };
 		2AE2F55B16D6B08800B6A058 /* BuoyancyController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BuoyancyController.cc; path = controllers/BuoyancyController.cc; sourceTree = "<group>"; };
 		2AE2F55C16D6B08800B6A058 /* BuoyancyController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BuoyancyController.h; path = controllers/BuoyancyController.h; sourceTree = "<group>"; };
@@ -1367,21 +1372,33 @@
 			name = tests;
 			sourceTree = "<group>";
 		};
+		2AB4C19616DE9EEA00B02479 /* core */ = {
+			isa = PBXGroup;
+			children = (
+				2AB4C19716DE9F0600B02479 /* GroupedSceneController_ScriptBinding.h */,
+				2AB4C19816DE9F0600B02479 /* GroupedSceneController.cc */,
+				2AB4C19916DE9F0600B02479 /* GroupedSceneController.h */,
+				2AB4C19A16DE9F0600B02479 /* PickingSceneController_ScriptBinding.h */,
+				2AB4C19B16DE9F0600B02479 /* PickingSceneController.cc */,
+				2AB4C19C16DE9F0600B02479 /* PickingSceneController.h */,
+				2AB4C19D16DE9F0600B02479 /* SceneController.h */,
+			);
+			name = core;
+			sourceTree = "<group>";
+		};
 		2AB4F1CF16D55B7300C9A27B /* controllers */ = {
 			isa = PBXGroup;
 			children = (
+				2AB4C1A016DE9F1100B02479 /* AmbientForceController_ScriptBinding.h */,
+				2AB4C1A116DE9F1100B02479 /* AmbientForceController.cc */,
+				2AB4C1A216DE9F1100B02479 /* AmbientForceController.h */,
+				2AB4C19616DE9EEA00B02479 /* core */,
 				2AB14A0216D7CDC200EABBF2 /* PointForceController_ScriptBinding.h */,
 				2AB14A0316D7CDC200EABBF2 /* PointForceController.cc */,
 				2AB14A0416D7CDC300EABBF2 /* PointForceController.h */,
 				2AE2F55A16D6B08800B6A058 /* BuoyancyController_ScriptBinding.h */,
 				2AE2F55B16D6B08800B6A058 /* BuoyancyController.cc */,
 				2AE2F55C16D6B08800B6A058 /* BuoyancyController.h */,
-				2AE2F54E16D6AB3100B6A058 /* ConstantForceController_ScriptBinding.h */,
-				2AE2F54F16D6AB3100B6A058 /* ConstantForceController.cc */,
-				2AE2F55016D6AB3100B6A058 /* ConstantForceController.h */,
-				2AA6865616D6992B003CEF0A /* SceneController_ScriptBinding.h */,
-				2AA6865716D6992B003CEF0A /* SceneController.cc */,
-				2AA6865816D6992B003CEF0A /* SceneController.h */,
 			);
 			name = controllers;
 			sourceTree = "<group>";
@@ -3246,12 +3263,13 @@
 				2AF1C54016B439BB00C1CF3A /* declaredAssets.cc in Sources */,
 				2AF1C54116B439BB00C1CF3A /* referencedAssets.cc in Sources */,
 				2AB97A1D16B66BC70080F940 /* tamlCustom.cc in Sources */,
-				2AA6865916D6992B003CEF0A /* SceneController.cc in Sources */,
 				2AA6865F16D69943003CEF0A /* SceneObjectList.cc in Sources */,
 				2AA6866016D69943003CEF0A /* SceneObjectSet.cc in Sources */,
-				2AE2F55116D6AB3100B6A058 /* ConstantForceController.cc in Sources */,
 				2AE2F55D16D6B08800B6A058 /* BuoyancyController.cc in Sources */,
 				2AB14A0516D7CDC300EABBF2 /* PointForceController.cc in Sources */,
+				2AB4C19E16DE9F0600B02479 /* GroupedSceneController.cc in Sources */,
+				2AB4C19F16DE9F0600B02479 /* PickingSceneController.cc in Sources */,
+				2AB4C1A316DE9F1100B02479 /* AmbientForceController.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 34 - 16
engine/compilers/Xcode_iOS/Torque2D.xcodeproj/project.pbxproj

@@ -7,13 +7,14 @@
 	objects = {
 
 /* Begin PBXBuildFile section */
-		2AA6866416D6995A003CEF0A /* SceneController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AA6866216D6995A003CEF0A /* SceneController.cc */; };
 		2AA6866A16D69968003CEF0A /* SceneObjectList.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AA6866516D69968003CEF0A /* SceneObjectList.cc */; };
 		2AA6866B16D69968003CEF0A /* SceneObjectSet.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AA6866816D69968003CEF0A /* SceneObjectSet.cc */; };
 		2AB14A0916D7CDCE00EABBF2 /* PointForceController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB14A0716D7CDCE00EABBF2 /* PointForceController.cc */; };
+		2AB4C1A716DE9F4B00B02479 /* AmbientForceController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB4C1A516DE9F4B00B02479 /* AmbientForceController.cc */; };
+		2AB4C1B016DE9F6700B02479 /* GroupedSceneController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB4C1AA16DE9F6700B02479 /* GroupedSceneController.cc */; };
+		2AB4C1B116DE9F6700B02479 /* PickingSceneController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB4C1AD16DE9F6700B02479 /* PickingSceneController.cc */; };
 		2AB97A2116B66BE50080F940 /* tamlCustom.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AB97A1F16B66BE50080F940 /* tamlCustom.cc */; };
 		2AC4404E16B0144500FC4091 /* ImageFont.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AC4404C16B0144500FC4091 /* ImageFont.cc */; };
-		2AE2F55516D6AB3C00B6A058 /* ConstantForceController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AE2F55316D6AB3C00B6A058 /* ConstantForceController.cc */; };
 		2AE2F55916D6B07200B6A058 /* BuoyancyController.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AE2F55716D6B07200B6A058 /* BuoyancyController.cc */; };
 		2AED7D9316B70102003482CF /* CoreText.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 2AED7D9216B70102003482CF /* CoreText.framework */; };
 		2AF1C54B16B439D900C1CF3A /* declaredAssets.cc in Sources */ = {isa = PBXBuildFile; fileRef = 2AF1C54716B439D900C1CF3A /* declaredAssets.cc */; };
@@ -479,9 +480,6 @@
 /* End PBXBuildFile section */
 
 /* Begin PBXFileReference section */
-		2AA6866116D6995A003CEF0A /* SceneController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SceneController_ScriptBinding.h; path = controllers/SceneController_ScriptBinding.h; sourceTree = "<group>"; };
-		2AA6866216D6995A003CEF0A /* SceneController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = SceneController.cc; path = controllers/SceneController.cc; sourceTree = "<group>"; };
-		2AA6866316D6995A003CEF0A /* SceneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SceneController.h; path = controllers/SceneController.h; sourceTree = "<group>"; };
 		2AA6866516D69968003CEF0A /* SceneObjectList.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SceneObjectList.cc; sourceTree = "<group>"; };
 		2AA6866616D69968003CEF0A /* SceneObjectList.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObjectList.h; sourceTree = "<group>"; };
 		2AA6866716D69968003CEF0A /* SceneObjectSet_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SceneObjectSet_ScriptBinding.h; sourceTree = "<group>"; };
@@ -490,15 +488,22 @@
 		2AB14A0616D7CDCE00EABBF2 /* PointForceController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PointForceController_ScriptBinding.h; path = controllers/PointForceController_ScriptBinding.h; sourceTree = "<group>"; };
 		2AB14A0716D7CDCE00EABBF2 /* PointForceController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PointForceController.cc; path = controllers/PointForceController.cc; sourceTree = "<group>"; };
 		2AB14A0816D7CDCE00EABBF2 /* PointForceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PointForceController.h; path = controllers/PointForceController.h; sourceTree = "<group>"; };
+		2AB4C1A416DE9F4B00B02479 /* AmbientForceController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AmbientForceController_ScriptBinding.h; path = controllers/AmbientForceController_ScriptBinding.h; sourceTree = "<group>"; };
+		2AB4C1A516DE9F4B00B02479 /* AmbientForceController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AmbientForceController.cc; path = controllers/AmbientForceController.cc; sourceTree = "<group>"; };
+		2AB4C1A616DE9F4B00B02479 /* AmbientForceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AmbientForceController.h; path = controllers/AmbientForceController.h; sourceTree = "<group>"; };
+		2AB4C1A916DE9F6700B02479 /* GroupedSceneController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GroupedSceneController_ScriptBinding.h; path = controllers/core/GroupedSceneController_ScriptBinding.h; sourceTree = "<group>"; };
+		2AB4C1AA16DE9F6700B02479 /* GroupedSceneController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = GroupedSceneController.cc; path = controllers/core/GroupedSceneController.cc; sourceTree = "<group>"; };
+		2AB4C1AB16DE9F6700B02479 /* GroupedSceneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = GroupedSceneController.h; path = controllers/core/GroupedSceneController.h; sourceTree = "<group>"; };
+		2AB4C1AC16DE9F6700B02479 /* PickingSceneController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PickingSceneController_ScriptBinding.h; path = controllers/core/PickingSceneController_ScriptBinding.h; sourceTree = "<group>"; };
+		2AB4C1AD16DE9F6700B02479 /* PickingSceneController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = PickingSceneController.cc; path = controllers/core/PickingSceneController.cc; sourceTree = "<group>"; };
+		2AB4C1AE16DE9F6700B02479 /* PickingSceneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = PickingSceneController.h; path = controllers/core/PickingSceneController.h; sourceTree = "<group>"; };
+		2AB4C1AF16DE9F6700B02479 /* SceneController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SceneController.h; path = controllers/core/SceneController.h; sourceTree = "<group>"; };
 		2AB97A1F16B66BE50080F940 /* tamlCustom.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = tamlCustom.cc; sourceTree = "<group>"; };
 		2AB97A2016B66BE50080F940 /* tamlCustom.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = tamlCustom.h; sourceTree = "<group>"; };
 		2AC4404B16B0144500FC4091 /* ImageFont_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFont_ScriptBinding.h; sourceTree = "<group>"; };
 		2AC4404C16B0144500FC4091 /* ImageFont.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ImageFont.cc; sourceTree = "<group>"; };
 		2AC4404D16B0144500FC4091 /* ImageFont.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ImageFont.h; sourceTree = "<group>"; };
 		2AD07B2716D15F8E0070DC79 /* simObjectTimerEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = simObjectTimerEvent.h; sourceTree = "<group>"; };
-		2AE2F55216D6AB3C00B6A058 /* ConstantForceController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConstantForceController_ScriptBinding.h; path = controllers/ConstantForceController_ScriptBinding.h; sourceTree = "<group>"; };
-		2AE2F55316D6AB3C00B6A058 /* ConstantForceController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ConstantForceController.cc; path = controllers/ConstantForceController.cc; sourceTree = "<group>"; };
-		2AE2F55416D6AB3C00B6A058 /* ConstantForceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ConstantForceController.h; path = controllers/ConstantForceController.h; sourceTree = "<group>"; };
 		2AE2F55616D6B07200B6A058 /* BuoyancyController_ScriptBinding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BuoyancyController_ScriptBinding.h; path = controllers/BuoyancyController_ScriptBinding.h; sourceTree = "<group>"; };
 		2AE2F55716D6B07200B6A058 /* BuoyancyController.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BuoyancyController.cc; path = controllers/BuoyancyController.cc; sourceTree = "<group>"; };
 		2AE2F55816D6B07200B6A058 /* BuoyancyController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BuoyancyController.h; path = controllers/BuoyancyController.h; sourceTree = "<group>"; };
@@ -1437,21 +1442,33 @@
 /* End PBXFrameworksBuildPhase section */
 
 /* Begin PBXGroup section */
+		2AB4C1A816DE9F5000B02479 /* core */ = {
+			isa = PBXGroup;
+			children = (
+				2AB4C1A916DE9F6700B02479 /* GroupedSceneController_ScriptBinding.h */,
+				2AB4C1AA16DE9F6700B02479 /* GroupedSceneController.cc */,
+				2AB4C1AB16DE9F6700B02479 /* GroupedSceneController.h */,
+				2AB4C1AC16DE9F6700B02479 /* PickingSceneController_ScriptBinding.h */,
+				2AB4C1AD16DE9F6700B02479 /* PickingSceneController.cc */,
+				2AB4C1AE16DE9F6700B02479 /* PickingSceneController.h */,
+				2AB4C1AF16DE9F6700B02479 /* SceneController.h */,
+			);
+			name = core;
+			sourceTree = "<group>";
+		};
 		2AB4F1D416D55B9F00C9A27B /* controllers */ = {
 			isa = PBXGroup;
 			children = (
+				2AB4C1A816DE9F5000B02479 /* core */,
+				2AB4C1A416DE9F4B00B02479 /* AmbientForceController_ScriptBinding.h */,
+				2AB4C1A516DE9F4B00B02479 /* AmbientForceController.cc */,
+				2AB4C1A616DE9F4B00B02479 /* AmbientForceController.h */,
 				2AB14A0616D7CDCE00EABBF2 /* PointForceController_ScriptBinding.h */,
 				2AB14A0716D7CDCE00EABBF2 /* PointForceController.cc */,
 				2AB14A0816D7CDCE00EABBF2 /* PointForceController.h */,
 				2AE2F55616D6B07200B6A058 /* BuoyancyController_ScriptBinding.h */,
 				2AE2F55716D6B07200B6A058 /* BuoyancyController.cc */,
 				2AE2F55816D6B07200B6A058 /* BuoyancyController.h */,
-				2AE2F55216D6AB3C00B6A058 /* ConstantForceController_ScriptBinding.h */,
-				2AE2F55316D6AB3C00B6A058 /* ConstantForceController.cc */,
-				2AE2F55416D6AB3C00B6A058 /* ConstantForceController.h */,
-				2AA6866116D6995A003CEF0A /* SceneController_ScriptBinding.h */,
-				2AA6866216D6995A003CEF0A /* SceneController.cc */,
-				2AA6866316D6995A003CEF0A /* SceneController.h */,
 			);
 			name = controllers;
 			sourceTree = "<group>";
@@ -3382,12 +3399,13 @@
 				2AF1C54C16B439D900C1CF3A /* referencedAssets.cc in Sources */,
 				2AB97A2116B66BE50080F940 /* tamlCustom.cc in Sources */,
 				33230F1656FA2C7C493DA2D2 /* guiSliderCtrl.cc in Sources */,
-				2AA6866416D6995A003CEF0A /* SceneController.cc in Sources */,
 				2AA6866A16D69968003CEF0A /* SceneObjectList.cc in Sources */,
 				2AA6866B16D69968003CEF0A /* SceneObjectSet.cc in Sources */,
-				2AE2F55516D6AB3C00B6A058 /* ConstantForceController.cc in Sources */,
 				2AE2F55916D6B07200B6A058 /* BuoyancyController.cc in Sources */,
 				2AB14A0916D7CDCE00EABBF2 /* PointForceController.cc in Sources */,
+				2AB4C1A716DE9F4B00B02479 /* AmbientForceController.cc in Sources */,
+				2AB4C1B016DE9F6700B02479 /* GroupedSceneController.cc in Sources */,
+				2AB4C1B116DE9F6700B02479 /* PickingSceneController.cc in Sources */,
 			);
 			runOnlyForDeploymentPostprocessing = 0;
 		};

+ 12 - 12
engine/source/2d/controllers/ConstantForceController.cc → engine/source/2d/controllers/AmbientForceController.cc

@@ -20,20 +20,20 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
-#ifndef _CONSTANT_FORCE_CONTROLLER_H_
-#include "2d/controllers/ConstantForceController.h"
+#ifndef _AMBIENT_FORCE_CONTROLLER_H_
+#include "2d/controllers/AmbientForceController.h"
 #endif
 
 // Script bindings.
-#include "ConstantForceController_ScriptBinding.h"
+#include "AmbientForceController_ScriptBinding.h"
 
 //------------------------------------------------------------------------------
 
-IMPLEMENT_CONOBJECT(ConstantForceController);
+IMPLEMENT_CONOBJECT(AmbientForceController);
 
 //------------------------------------------------------------------------------
 
-ConstantForceController::ConstantForceController()        
+AmbientForceController::AmbientForceController()        
 {
     // Reset the constant force.
     mForce.SetZero();
@@ -41,34 +41,34 @@ ConstantForceController::ConstantForceController()
 
 //------------------------------------------------------------------------------
 
-ConstantForceController::~ConstantForceController()
+AmbientForceController::~AmbientForceController()
 {
 }
 
 
 //------------------------------------------------------------------------------
 
-void ConstantForceController::initPersistFields()
+void AmbientForceController::initPersistFields()
 {
     // Call parent.
     Parent::initPersistFields();
 
     // Force.
-    addProtectedField("Force", TypeVector2, Offset( mForce, ConstantForceController), &defaultProtectedSetFn, &defaultProtectedGetFn, "The constant force to apply.");
+    addProtectedField("Force", TypeVector2, Offset( mForce, AmbientForceController), &defaultProtectedSetFn, &defaultProtectedGetFn, "The constant force to apply.");
 }
 
 //------------------------------------------------------------------------------
 
-void ConstantForceController::copyTo(SimObject* object)
+void AmbientForceController::copyTo(SimObject* object)
 {
     // Call to parent.
     Parent::copyTo(object);
 
     // Cast to controller.
-    ConstantForceController* pController = static_cast<ConstantForceController*>(object);
+    AmbientForceController* pController = static_cast<AmbientForceController*>(object);
 
     // Sanity!
-    AssertFatal(pController != NULL, "ConstantForceController::copyTo() - Object is not the correct type.");
+    AssertFatal(pController != NULL, "AmbientForceController::copyTo() - Object is not the correct type.");
 
     // Copy state.
     pController->setForce( getForce() );
@@ -76,7 +76,7 @@ void ConstantForceController::copyTo(SimObject* object)
 
 //------------------------------------------------------------------------------
 
-void ConstantForceController::integrate( Scene* pScene, const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats )
+void AmbientForceController::integrate( Scene* pScene, const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats )
 {
     // Process all the scene objects.
     for( SceneObjectSet::iterator itr = begin(); itr != end(); ++itr )

+ 10 - 10
engine/source/2d/controllers/ConstantForceController.h → engine/source/2d/controllers/AmbientForceController.h

@@ -20,11 +20,11 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
-#ifndef _CONSTANT_FORCE_CONTROLLER_H_
-#define _CONSTANT_FORCE_CONTROLLER_H_
+#ifndef _AMBIENT_FORCE_CONTROLLER_H_
+#define _AMBIENT_FORCE_CONTROLLER_H_
 
-#ifndef _SCENE_CONTROLLER_H_
-#include "2d/controllers/sceneController.h"
+#ifndef _GROUPED_SCENE_CONTROLLER_H_
+#include "2d/controllers/core/GroupedSceneController.h"
 #endif
 
 #ifndef _VECTOR2_H_
@@ -33,16 +33,16 @@
 
 //------------------------------------------------------------------------------
 
-class ConstantForceController : public SceneController
+class AmbientForceController : public GroupedSceneController
 {
 private:
-    typedef SceneController Parent;
+    typedef GroupedSceneController Parent;
 
     Vector2 mForce;
 
 public:
-    ConstantForceController();
-    virtual ~ConstantForceController();
+    AmbientForceController();
+    virtual ~AmbientForceController();
 
     static void initPersistFields();
     virtual void copyTo(SimObject* object);
@@ -54,7 +54,7 @@ public:
     inline const Vector2& getForce( void ) const { return mForce; }
 
     /// Declare Console Object.
-    DECLARE_CONOBJECT( ConstantForceController );
+    DECLARE_CONOBJECT( AmbientForceController );
 };
 
-#endif // _CONSTANT_FORCE_CONTROLLER_H_
+#endif // _AMBIENT_FORCE_CONTROLLER_H_

+ 6 - 6
engine/source/2d/controllers/ConstantForceController_ScriptBinding.h → engine/source/2d/controllers/AmbientForceController_ScriptBinding.h

@@ -20,9 +20,9 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
-ConsoleMethod(ConstantForceController, setForce, void, 3, 4,    "(float x, float y) - Sets the constant (world) force to use.\n"
-                                                                "@param x The component of the constant force along the horizontal (world) axis.\n"
-                                                                "@param y The component of the constant force along the vertical (world) axis.\n"
+ConsoleMethod(AmbientForceController, setForce, void, 3, 4,     "(float x, float y) - Sets the ambient force to use.\n"
+                                                                "@param x The component of the ambient force along the horizontal (world) axis.\n"
+                                                                "@param y The component of the ambient force along the vertical (world) axis.\n"
                                                                 "@return No return value.")
 {
     // The new force.
@@ -42,7 +42,7 @@ ConsoleMethod(ConstantForceController, setForce, void, 3, 4,    "(float x, float
     // Invalid
     else
     {
-        Con::warnf("ConstantForceController::setForce() - Invalid number of parameters!");
+        Con::warnf("AmbientForceController::setForce() - Invalid number of parameters!");
         return;
     }
 
@@ -51,8 +51,8 @@ ConsoleMethod(ConstantForceController, setForce, void, 3, 4,    "(float x, float
 
 //-----------------------------------------------------------------------------
 
-ConsoleMethod(ConstantForceController, getForce, const char*, 2, 2, "() Gets the constant (world) force being used.\n"
-                                                                    "@return The constant (world) force being used.")
+ConsoleMethod(AmbientForceController, getForce, const char*, 2, 2, "() Gets the ambient force being used.\n"
+                                                                    "@return The ambient force being used.")
 {
     return object->getForce().scriptThis();
 }

+ 16 - 19
engine/source/2d/controllers/BuoyancyController.cc

@@ -103,16 +103,29 @@ void BuoyancyController::copyTo(SimObject* object)
 
 void BuoyancyController::integrate( Scene* pScene, const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats )
 {
-    // Process all the scene objects.
-    for( SceneObjectSet::iterator itr = begin(); itr != end(); ++itr )
+    // Prepare query filter.
+    WorldQuery* pWorldQuery = prepareQueryFilter( pScene );
+
+    // Query for candidate objects.
+    pWorldQuery->anyQueryArea( mFluidArea ); 
+
+    // Fetch results.
+    typeWorldQueryResultVector& queryResults = pWorldQuery->getQueryResults();
+
+    // Iterate the results.
+    for ( U32 n = 0; n < (U32)queryResults.size(); n++ )
     {
         // Fetch the scene object.
-        SceneObject* pSceneObject = *itr;
+        SceneObject* pSceneObject = queryResults[n].mpSceneObject;
 
         // Skip if asleep.
         if ( !pSceneObject->getAwake() )
             continue;
 
+        // Ignore if it's a static body.
+        if ( pSceneObject->getBodyType() == b2BodyType::b2_staticBody )
+            continue;
+
         // Fetch the shape count.
         const U32 shapeCount = pSceneObject->getCollisionShapeCount();
 
@@ -202,14 +215,6 @@ F32 BuoyancyController::ComputeCircleSubmergedArea( const b2Transform& bodyTrans
     // Sanity!
     AssertFatal( pShape != NULL, "BuoyancyController::ComputeCircleSubmergedArea() - Invalid shape." );
 
-    // Calculate the shape AABB.
-    b2AABB shapeAABB;
-    pShape->ComputeAABB( &shapeAABB, bodyTransform, 0 );
-
-    // If no overlap then the object cannot be submerged at all so return zero area submerged.
-    if ( !b2TestOverlap( mFluidArea, shapeAABB ) )
-        return 0.0f;
-
     // Calculate the world shape center.
     const b2Vec2 worldShapeCenter = b2Mul( bodyTransform, pShape->m_p );
 
@@ -253,14 +258,6 @@ F32 BuoyancyController::ComputePolygonSubmergedArea( const b2Transform& bodyTran
     // Sanity!
     AssertFatal( pShape != NULL, "BuoyancyController::ComputePolygonSubmergedArea() - Invalid shape." );
 
-    // Calculate the shape AABB.
-    b2AABB shapeAABB;
-    pShape->ComputeAABB( &shapeAABB, bodyTransform, 0 );
-
-    // If no overlap then the object cannot be submerged at all so return zero area submerged.
-    if ( !b2TestOverlap( mFluidArea, shapeAABB ) )
-        return 0.0f;
-
     // Transform plane into shape co-ordinates
     b2Vec2 normalL = b2MulT( bodyTransform.q, mSurfaceNormal);
     F32 offsetL = mFluidArea.upperBound.y - b2Dot(mSurfaceNormal, bodyTransform.p);

+ 4 - 4
engine/source/2d/controllers/BuoyancyController.h

@@ -23,8 +23,8 @@
 #ifndef _BUOYANCY_CONTROLLER_H_
 #define _BUOYANCY_CONTROLLER_H_
 
-#ifndef _SCENE_CONTROLLER_H_
-#include "2d/controllers/sceneController.h"
+#ifndef _PICKING_SCENE_CONTROLLER_H_
+#include "2d/controllers/core/pickingSceneController.h"
 #endif
 
 #ifndef _VECTOR2_H_
@@ -33,10 +33,10 @@
 
 //------------------------------------------------------------------------------
 
-class BuoyancyController : public SceneController
+class BuoyancyController : public PickingSceneController
 {
 private:
-    typedef SceneController Parent;
+    typedef PickingSceneController Parent;
 
     /// The fluid area.
     b2AABB mFluidArea;

+ 2 - 6
engine/source/2d/controllers/PointForceController.cc

@@ -86,12 +86,8 @@ void PointForceController::integrate( Scene* pScene, const F32 totalTime, const
     if ( mIsZero( mForce ) || mIsZero( mRadius ) )
         return;
 
-    // Fetch world query and clear results.
-    WorldQuery* pWorldQuery = pScene->getWorldQuery( true );
-
-    // Set filter.
-    WorldQueryFilter queryFilter( 0xFFFFFFFF, 0xFFFFFFFF, true, false, true, true );
-    pWorldQuery->setQueryFilter( queryFilter );
+    // Prepare query filter.
+    WorldQuery* pWorldQuery = prepareQueryFilter( pScene );
 
     // Calculate the AABB of the attractor.
     b2AABB aabb;

+ 11 - 7
engine/source/2d/controllers/PointForceController.h

@@ -23,8 +23,8 @@
 #ifndef _ATTRACTOR_CONTROLLER_H_
 #define _ATTRACTOR_CONTROLLER_H_
 
-#ifndef _SCENE_CONTROLLER_H_
-#include "2d/controllers/sceneController.h"
+#ifndef _PICKING_SCENE_CONTROLLER_H_
+#include "2d/controllers/core/pickingSceneController.h"
 #endif
 
 #ifndef _VECTOR2_H_
@@ -33,10 +33,10 @@
 
 //------------------------------------------------------------------------------
 
-class PointForceController : public SceneController
+class PointForceController : public PickingSceneController
 {
 private:
-    typedef SceneController Parent;
+    typedef PickingSceneController Parent;
 
     Vector2 mPosition;
     F32 mRadius;
@@ -49,15 +49,19 @@ public:
     static void initPersistFields();
     virtual void copyTo(SimObject* object);
 
+    inline void setPosition( const Vector2& position ) { mPosition = position; }
+    inline const Vector2& getPosition( void ) const { return mPosition; }
+    inline void setRadius( const F32 radius ) { mRadius = getMax( radius, FLT_MIN ); }
+    inline F32 getRadius( void ) const { return mRadius; }
+    inline void setForce( const F32 force ) { mForce = force; }
+    inline F32 getForce( void ) const { return mForce; }
+
     /// Integration.
     virtual void integrate( Scene* pScene, const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats );
 
     // Scene render.
     virtual void renderOverlay( Scene* pScene, const SceneRenderState* pSceneRenderState, BatchRender* pBatchRenderer );
 
-    inline void setForce( const F32& force ) { mForce = force; }
-    inline const F32 getForce( void ) const { return mForce; }
-
     /// Declare Console Object.
     DECLARE_CONOBJECT( PointForceController );
 };

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

@@ -20,4 +20,75 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
+ConsoleMethod(PointForceController, setPosition, void, 3, 4,    "(float x, float y) - Sets the position of the force center.\n"
+                                                                "@param x The position along the horizontal axis.\n"
+                                                                "@param y The position along the vertical axis.\n"
+                                                                "@return No return value.")
+{
+    // The new position.
+    b2Vec2 position;
 
+    // Elements in the first argument.
+    U32 elementCount = Utility::mGetStringElementCount(argv[2]);
+
+    // ("x y")
+    if ((elementCount == 2) && (argc == 3))
+        position = Utility::mGetStringElementVector(argv[2]);
+
+    // (x, y)
+    else if ((elementCount == 1) && (argc == 4))
+        position.Set(dAtof(argv[2]), dAtof(argv[3]));
+
+    // Invalid
+    else
+    {
+        Con::warnf("PointForceController::setPosition() - Invalid number of parameters!");
+        return;
+    }
+
+    // Set Position.
+    object->setPosition(position);
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, PointForceController, const char*, 2, 2,    "() Gets the position of the force center.\n"
+                                                                                "@return (float x/float y) The x and y (horizontal and vertical) position of the force center.")
+{
+    // Get position.
+    return object->getPosition().scriptThis();
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, setRadius, void, 3, 3,       "(radius) - Sets the radius of the point force to use.\n"
+                                                                "@param radius The radius of the point force to use.\n"
+                                                                "@return No return value.")
+{
+    object->setRadius( dAtof(argv[2]) );
+} 
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, getRadius, F32, 2, 2,        "() Gets the radius of the point force being used.\n"
+                                                                "@return The radius of the point force being used.")
+{
+    return object->getRadius();
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, setForce, void, 3, 3,       "(force) - Sets the point force to use.\n"
+                                                                "@param force The point force to use.\n"
+                                                                "@return No return value.")
+{
+    object->setForce( dAtof(argv[2]) );
+} 
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PointForceController, getForce, F32, 2, 2,        "() Gets the point force being used.\n"
+                                                                "@return The point force being used.")
+{
+    return object->getForce();
+}

+ 11 - 37
engine/source/2d/controllers/SceneController.cc → engine/source/2d/controllers/core/GroupedSceneController.cc

@@ -20,58 +20,32 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
-#ifndef _SCENE_CONTROLLER_H_
-#include "2d/controllers/SceneController.h"
-#endif
-
-#ifndef _SCENE_OBJECT_SET_H_
-#include "2d/sceneObject/sceneObjectSet.h"
-#endif
-
-#ifndef _SCENE_H_
-#include "2d/scene/scene.h"
+#ifndef _GROUPED_SCENE_CONTROLLER_H_
+#include "2d/controllers/core/GroupedSceneController.h"
 #endif
 
 // Script bindings.
-#include "SceneController_ScriptBinding.h"
-
-//------------------------------------------------------------------------------
-
-IMPLEMENT_CONOBJECT(SceneController);
-
-//------------------------------------------------------------------------------
-
-SceneController::SceneController()
-{
-}
+#include "2d/controllers/core/GroupedSceneController_ScriptBinding.h"
 
 //------------------------------------------------------------------------------
 
-SceneController::~SceneController()
-{
-}
-
+IMPLEMENT_CONOBJECT(GroupedSceneController);
 
 //------------------------------------------------------------------------------
 
-void SceneController::initPersistFields()
-{
-    // Call parent.
-    Parent::initPersistFields();
-
-}
-
-//------------------------------------------------------------------------------
-
-void SceneController::copyTo(SimObject* object)
+void GroupedSceneController::copyTo(SimObject* object)
 {
     // Call to parent.
     Parent::copyTo(object);
 
     // Cast to controller.
-    SceneController* pController = static_cast<SceneController*>(object);
+    GroupedSceneController* pController = static_cast<GroupedSceneController*>(object);
 
     // Sanity!
-    AssertFatal(pController != NULL, "SceneController::copyTo() - Object is not the correct type.");
+    AssertFatal(pController != NULL, "GroupedSceneController::copyTo() - Object is not the correct type.");
+
+    // Add objects to the controller.
+    for( SceneObjectSet::iterator objectItr = begin(); objectItr != end(); ++objectItr )
+        pController->addObject( *objectItr );
 }
 

+ 13 - 22
engine/source/2d/controllers/SceneController.h → engine/source/2d/controllers/core/GroupedSceneController.h

@@ -20,44 +20,35 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
-#ifndef _SCENE_CONTROLLER_H_
-#define _SCENE_CONTROLLER_H_
-
-#ifndef _SCENE_OBJECT_SET_H_
-#include "2d/sceneObject/sceneObjectSet.h"
-#endif
+#ifndef _GROUPED_SCENE_CONTROLLER_H_
+#define _GROUPED_SCENE_CONTROLLER_H_
 
-#ifndef _SCENE_RENDER_STATE_H_
-#include "2d/scene/sceneRenderState.h"
+#ifndef _CONSOLETYPES_H_
+#include "console/consoleTypes.h"
 #endif
 
-#ifndef _BATCH_RENDER_H_
-#include "2d/core/batchRender.h"
+#ifndef _SCENE_OBJECT_SET_H_
+#include "2d/sceneObject/sceneObjectSet.h"
 #endif
 
 #ifndef _SCENE_OBJECT_H_
 #include "2d/sceneObject/sceneObject.h"
 #endif
 
-#ifndef _DEBUG_STATS_H_
-#include "2d/scene/DebugStats.h"
+#ifndef _SCENE_CONTROLLER_H_
+#include "2d/controllers/core/sceneController.h"
 #endif
 
 //------------------------------------------------------------------------------
 
-class Scene;
-
-//------------------------------------------------------------------------------
-
-class SceneController : public SceneObjectSet
+class GroupedSceneController : public SceneObjectSet, public SceneController
 {
     typedef SceneObjectSet Parent;
 
 public:
-    SceneController();
-    virtual ~SceneController();
+    GroupedSceneController() {}
+    virtual ~GroupedSceneController() {}
 
-    static void initPersistFields();
     virtual void copyTo(SimObject* object);
 
     /// Integration.
@@ -67,7 +58,7 @@ public:
     virtual void renderOverlay( Scene* pScene, const SceneRenderState* pSceneRenderState, BatchRender* pBatchRenderer ) {}
 
     /// Declare Console Object.
-    DECLARE_CONOBJECT( SceneController );
+    DECLARE_CONOBJECT( GroupedSceneController );
 };
 
-#endif // _SCENE_CONTROLLER_H_
+#endif // _GROUPED_SCENE_CONTROLLER_H_

+ 0 - 0
engine/source/2d/controllers/SceneController_ScriptBinding.h → engine/source/2d/controllers/core/GroupedSceneController_ScriptBinding.h


+ 79 - 0
engine/source/2d/controllers/core/PickingSceneController.cc

@@ -0,0 +1,79 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef PickingSceneController
+#include "2d/controllers/core/PickingSceneController.h"
+#endif
+
+// Script bindings.
+#include "2d/controllers/core/PickingSceneController_ScriptBinding.h"
+
+//------------------------------------------------------------------------------
+
+IMPLEMENT_CONOBJECT(PickingSceneController);
+
+//------------------------------------------------------------------------------
+
+PickingSceneController::PickingSceneController() :
+        mControlGroupMask( MASK_ALL ),
+        mControlLayerMask( MASK_ALL )
+{
+}
+
+//------------------------------------------------------------------------------
+
+PickingSceneController::~PickingSceneController()
+{
+}
+
+//------------------------------------------------------------------------------
+
+void PickingSceneController::copyTo(SimObject* object)
+{
+    // Call to parent.
+    Parent::copyTo(object);
+
+    // Cast to controller.
+    PickingSceneController* pController = static_cast<PickingSceneController*>(object);
+
+    // Sanity!
+    AssertFatal(pController != NULL, "PickingSceneController::copyTo() - Object is not the correct type.");
+
+    // Set masks.
+    pController->setControlGroupMask( getControlGroupMask() );
+    pController->setControlLayerMask( getControlLayerMask() );
+}
+
+//------------------------------------------------------------------------------
+
+WorldQuery* PickingSceneController::prepareQueryFilter( Scene* pScene, const bool clearQuery )
+{
+    // Fetch world query and clear results.
+    WorldQuery* pWorldQuery = pScene->getWorldQuery( clearQuery );
+
+    // Set filter.
+    WorldQueryFilter queryFilter( mControlLayerMask, mControlGroupMask, true, false, true, true );
+    pWorldQuery->setQueryFilter( queryFilter );
+
+    return pWorldQuery;
+}
+

+ 76 - 0
engine/source/2d/controllers/core/PickingSceneController.h

@@ -0,0 +1,76 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _PICKING_SCENE_CONTROLLER_H_
+#define _PICKING_SCENE_CONTROLLER_H_
+
+#ifndef _CONSOLETYPES_H_
+#include "console/consoleTypes.h"
+#endif
+
+#ifndef _SCENE_H_
+#include "2d/scene/scene.h"
+#endif
+
+#ifndef _SCENE_OBJECT_H_
+#include "2d/sceneObject/sceneObject.h"
+#endif
+
+#ifndef _SCENE_CONTROLLER_H_
+#include "2d/controllers/core/sceneController.h"
+#endif
+
+//------------------------------------------------------------------------------
+
+class PickingSceneController : public SimObject, public SceneController
+{
+    typedef SimObject Parent;
+
+private:
+    U32 mControlGroupMask;
+    U32 mControlLayerMask;
+
+public:
+    PickingSceneController();
+    virtual ~PickingSceneController();
+
+    virtual void copyTo(SimObject* object);
+
+    inline void setControlGroupMask( const U32 groupMask ) { mControlGroupMask = groupMask; }
+    inline U32 getControlGroupMask( void ) const { return mControlGroupMask; }
+    inline void setControlLayerMask( const U32 layerMask ) { mControlLayerMask = layerMask; }
+    inline U32 getControlLayerMask( void ) const { return mControlLayerMask; }
+
+    /// Integration.
+    virtual void integrate( Scene* pScene, const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats ) {}
+
+    // Scene render.
+    virtual void renderOverlay( Scene* pScene, const SceneRenderState* pSceneRenderState, BatchRender* pBatchRenderer ) {}
+
+    /// Declare Console Object.
+    DECLARE_CONOBJECT( PickingSceneController );
+
+protected:
+    WorldQuery* prepareQueryFilter( Scene* pScene, const bool clearQuery = true );
+};
+
+#endif // _PICKING_SCENE_CONTROLLER_H_

+ 187 - 0
engine/source/2d/controllers/core/PickingSceneController_ScriptBinding.h

@@ -0,0 +1,187 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PickingSceneController, setControlGroups, void, 3, 2 + MASK_BITCOUNT, "(groups$) - Sets the control group(s).\n"
+                                                                                    "@param groups A list of groups that are affected by the controller.\n"
+                                                                                    "@return No return value.")
+{
+    // The mask.
+    U32 mask = 0;
+
+    // Grab the element count of the first parameter.
+    const U32 elementCount = Utility::mGetStringElementCount(argv[2]);
+
+    // Make sure we get at least one number.
+    if (elementCount < 1)
+    {
+        object->setControlGroupMask(MASK_ALL);
+        return;
+    }
+
+    // Space separated list.
+    if (argc == 3)
+    {
+        // Convert the string to a mask.
+        for (U32 i = 0; i < elementCount; i++)
+        {
+            S32 bit = dAtoi(Utility::mGetStringElement(argv[2], i));
+         
+            // Make sure the group is valid.
+            if ((bit < 0) || (bit >= MASK_BITCOUNT))
+            {
+            Con::warnf("PickingSceneController::setControlGroups() - Invalid group specified (%d); skipped!", bit);
+            continue;
+            }
+         
+            mask |= (1 << bit);
+        }
+    }
+
+    // Comma separated list.
+    else
+    {
+        // Convert the list to a mask.
+        for (U32 i = 2; i < (U32)argc; i++)
+        {
+            S32 bit = dAtoi(argv[i]);
+         
+            // Make sure the group is valid.
+            if ((bit < 0) || (bit >= MASK_BITCOUNT))
+            {
+            Con::warnf("PickingSceneController::setControlGroups() - Invalid group specified (%d); skipped!", bit);
+            continue;
+            }
+
+            mask |= (1 << bit);
+        }
+    }
+    // Set control groups.
+    object->setControlGroupMask(mask);
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PickingSceneController, getControlGroups, const char*, 2, 2,  "() - Gets the control groups.\n"
+                                                                            "@return (controlGroups) A list of groups that are affected by the controller.")
+{
+    U32 mask = object->getControlGroupMask();
+
+    bool first = true;
+    char* bits = Con::getReturnBuffer(128);
+    bits[0] = '\0';
+    for (S32 i = 0; i < MASK_BITCOUNT; i++)
+    {
+        if (mask & BIT(i))
+        {
+            char bit[4];
+            dSprintf(bit, 4, "%s%d", first ? "" : " ", i);
+            first = false;
+            dStrcat(bits, bit);
+        }
+    }
+
+    return bits;
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PickingSceneController, setControlLayers, void, 3, 2 + MASK_BITCOUNT, "(layers$) - Sets the control layers(s).\n"
+                                                                                    "@param layers A list of layers that are affected by the controller.\n"
+                                                                                    "@return No return value.")
+{
+    // The mask.
+    U32 mask = 0;
+
+    // Grab the element count of the first parameter.
+    const U32 elementCount = Utility::mGetStringElementCount(argv[2]);
+
+    // Make sure we get at least one number.
+    if (elementCount < 1)
+    {
+        object->setControlLayerMask(MASK_ALL);
+        return;
+    }
+
+    // Space separated list.
+    if (argc == 3)
+    {
+        // Convert the string to a mask.
+        for (U32 i = 0; i < elementCount; i++)
+        {
+            S32 bit = dAtoi(Utility::mGetStringElement(argv[2], i));
+         
+            // Make sure the group is valid.
+            if ((bit < 0) || (bit >= MASK_BITCOUNT))
+            {
+            Con::warnf("PickingSceneController::setControlLayers() - Invalid layer specified (%d); skipped!", bit);
+            continue;
+            }
+         
+            mask |= (1 << bit);
+        }
+    }
+
+    // Comma separated list.
+    else
+    {
+        // Convert the list to a mask.
+        for (U32 i = 2; i < (U32)argc; i++)
+        {
+            S32 bit = dAtoi(argv[i]);
+         
+            // Make sure the group is valid.
+            if ((bit < 0) || (bit >= MASK_BITCOUNT))
+            {
+            Con::warnf("PickingSceneController::setControlLayers() - Invalid layer specified (%d); skipped!", bit);
+            continue;
+            }
+
+            mask |= (1 << bit);
+        }
+    }
+    // Set control Layers
+    object->setControlLayerMask(mask);
+}
+
+//-----------------------------------------------------------------------------
+
+ConsoleMethod(PickingSceneController, getControlLayers, const char*, 2, 2,  "() - Gets the control layers.\n"
+                                                                            "@return (controlLayers) A list of layers that are affected by the controller.")
+{
+    U32 mask = object->getControlLayerMask();
+
+    bool first = true;
+    char* bits = Con::getReturnBuffer(128);
+    bits[0] = '\0';
+    for (S32 i = 0; i < MASK_BITCOUNT; i++)
+    {
+        if (mask & BIT(i))
+        {
+            char bit[4];
+            dSprintf(bit, 4, "%s%d", first ? "" : " ", i);
+            first = false;
+            dStrcat(bits, bit);
+        }
+    }
+
+    return bits;
+}

+ 48 - 0
engine/source/2d/controllers/core/SceneController.h

@@ -0,0 +1,48 @@
+//-----------------------------------------------------------------------------
+// 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.
+//-----------------------------------------------------------------------------
+
+#ifndef _SCENE_CONTROLLER_H_
+#define _SCENE_CONTROLLER_H_
+
+//------------------------------------------------------------------------------
+
+class Scene;
+struct SceneRenderState;
+class BatchRender;
+class DebugStats;
+
+//------------------------------------------------------------------------------
+
+class SceneController
+{
+public:
+    SceneController() {}
+    virtual ~SceneController() {}
+
+    /// Integration.
+    virtual void integrate( Scene* pScene, const F32 totalTime, const F32 elapsedTime, DebugStats* pDebugStats ) = 0;
+
+    // Scene render.
+    virtual void renderOverlay( Scene* pScene, const SceneRenderState* pSceneRenderState, BatchRender* pBatchRenderer ) = 0;
+};
+
+#endif // _SCENE_CONTROLLER_H_

+ 8 - 29
engine/source/2d/scene/Scene.cc

@@ -49,7 +49,7 @@
 #endif
 
 #ifndef _SCENE_CONTROLLER_H_
-#include "2d/controllers/SceneController.h"
+#include "2d/controllers/core/SceneController.h"
 #endif
 
 #ifndef _PARTICLE_SYSTEM_H_
@@ -1310,30 +1310,9 @@ void Scene::clearScene( bool deleteObjects )
     if ( pControllerSet == NULL )
         return;
 
-	// Fetch scene controller count.
-	const S32 sceneControllerCount = (S32)pControllerSet->size();
-
-	// Iterate scene controllers.
-	for( S32 i = 0; i < sceneControllerCount; i++ )
-	{
-		// Fetch the scene controller.
-		SceneController* pController = dynamic_cast<SceneController*>((*pControllerSet)[i]);
-
-        // Clear objects from the controller.
-        pController->clear();
-	}
-
-    // Are we deleting objects?
-    if ( deleteObjects )
-    {
-        // Yes, so delete the controllers.
-        pControllerSet->deleteObjects();
-    }
-    else
-    {
-        // No, so just clear the controllers.
-        pControllerSet->clear();
-    }
+    // Delete all the scene controllers.
+    while( pControllerSet->size() > 0 )
+        pControllerSet->at(0)->deleteObject();
 }
 
 //-----------------------------------------------------------------------------
@@ -4877,15 +4856,15 @@ void Scene::onTamlCustomWrite( TamlCustomNodes& customNodes )
 		// Iterate scene controllers.
 		for( S32 i = 0; i < sceneControllerCount; i++ )
 		{
-			// Fetch the scene controller.
-			SceneController* pController = dynamic_cast<SceneController*>((*pControllerSet)[i]);
+            // Fetch the set object.
+            SimObject* pSetObject = pControllerSet->at(i);
 
 			// Skip if not a controller.
-			if ( pController == NULL )
+            if ( !pSetObject->isType<SceneController*>() )
 				continue;
 
             // Add controller node.
-            pControllerCustomNode->addNode( pController );
+            pControllerCustomNode->addNode( pSetObject );
 		}
 	}
 }

+ 6 - 13
engine/source/2d/sceneobject/SceneObject.cc

@@ -1437,27 +1437,20 @@ void SceneObject::applyAngularImpulse( const F32 impulse, const bool wake )
 
 //-----------------------------------------------------------------------------
 
-void SceneObject::setCollisionMasks( const U32 groupMask, const U32 layerMask )
-{
-    // Set Group/Layer Collision Masks.
-    mCollisionGroupMask = groupMask;
-    mCollisionLayerMask = layerMask;
-}
-
-//-----------------------------------------------------------------------------
-
 void SceneObject::setCollisionAgainst( const SceneObject* pSceneObject, const bool clearMasks )
 {
     // Do we need to clear existing masks?
     if ( clearMasks )
     {
         // Yes, so just set the masks to the referenced-objects' masks.
-        setCollisionMasks( pSceneObject->getSceneGroupMask(), pSceneObject->getSceneLayerMask() );
+        setCollisionGroupMask( pSceneObject->getCollisionGroupMask() );
+        setCollisionLayerMask( pSceneObject->getCollisionLayerMask() ); 
     }
     else
     {
         // No, so merge with existing masks.
-        setCollisionMasks( getCollisionGroupMask() | pSceneObject->getSceneGroupMask(), getCollisionLayerMask() | pSceneObject->getSceneLayerMask() );
+        setCollisionGroupMask( getCollisionGroupMask() | pSceneObject->getCollisionGroupMask() );
+        setCollisionLayerMask( getCollisionLayerMask() | pSceneObject->getCollisionLayerMask() ); 
     }
 }
 
@@ -2878,8 +2871,8 @@ void SceneObject::copyTo( SimObject* obj )
     pSceneObject->setSleepingAllowed( getSleepingAllowed() );
 
     /// Collision control.
-    pSceneObject->setCollisionGroups( getCollisionGroupMask() );
-    pSceneObject->setCollisionLayers( getCollisionLayerMask() );
+    pSceneObject->setCollisionGroupMask( getCollisionGroupMask() );
+    pSceneObject->setCollisionLayerMask( getCollisionLayerMask() );
     pSceneObject->setCollisionSuppress( getCollisionSuppress() );
     pSceneObject->setGatherContacts( getGatherContacts() );
     pSceneObject->setDefaultDensity( getDefaultDensity() );

+ 4 - 5
engine/source/2d/sceneobject/SceneObject.h

@@ -360,11 +360,10 @@ public:
     inline F32              getInertia( void ) const                    { if ( mpScene ) return mpBody->GetInertia(); else return 0.0f; }
 
     /// Collision control.
-    void                    setCollisionMasks( const U32 groupMask, const U32 layerMask = MASK_ALL );
     void                    setCollisionAgainst( const SceneObject* pSceneObject, const bool clearMasks );
-    inline void             setCollisionLayers( const U32 layerMask )   { setCollisionMasks(getCollisionGroupMask(), layerMask); }
-    inline void             setCollisionGroups( const U32 groupMask )   { setCollisionMasks(groupMask, getCollisionLayerMask()); }
+    inline void             setCollisionGroupMask( const U32 groupMask ) { mCollisionGroupMask = groupMask; }
     inline U32              getCollisionGroupMask(void) const           { return mCollisionGroupMask; }
+    inline void             setCollisionLayerMask( const U32 layerMask ) { mCollisionLayerMask = layerMask; }
     inline U32              getCollisionLayerMask(void) const           { return mCollisionLayerMask; }
     void                    setDefaultDensity( const F32 density, const bool updateShapes = true );
     inline F32              getDefaultDensity( void ) const             { return mDefaultFixture.density; }
@@ -665,9 +664,9 @@ protected:
     static bool             writeDefaultFriction( void* obj, StringTableEntry pFieldName ) {return mNotEqual(static_cast<SceneObject*>(obj)->getDefaultFriction(), 0.2f); }
     static bool             setDefaultRestitution(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setDefaultRestitution(dAtof(data)); return false; }
     static bool             writeDefaultRestitution( void* obj, StringTableEntry pFieldName ) { return mNotEqual(static_cast<SceneObject*>(obj)->getDefaultRestitution(), 0.0f); }
-    static bool             setCollisionGroups(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionGroups(dAtoi(data)); return false; }
+    static bool             setCollisionGroups(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionGroupMask(dAtoi(data)); return false; }
     static bool             writeCollisionGroups( void* obj, StringTableEntry pFieldName ) { return static_cast<SceneObject*>(obj)->getCollisionGroupMask() != MASK_ALL; }
-    static bool             setCollisionLayers(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionLayers(dAtoi(data)); return false; }
+    static bool             setCollisionLayers(void* obj, const char* data) { static_cast<SceneObject*>(obj)->setCollisionLayerMask(dAtoi(data)); return false; }
     static bool             writeCollisionLayers( void* obj, StringTableEntry pFieldName ) { return static_cast<SceneObject*>(obj)->getCollisionLayerMask() != MASK_ALL; }
     static bool             writeCollisionSuppress( void* obj, StringTableEntry pFieldName ) { return static_cast<SceneObject*>(obj)->getCollisionSuppress() == true; }
     static bool             setGatherContacts(void* obj, const char* data)  { static_cast<SceneObject*>(obj)->setGatherContacts(dAtoi(data)); return false; }

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

@@ -1080,7 +1080,8 @@ ConsoleMethod(SceneObject, setCollisionMasks, void, 3, 4,    "(groupMask, [layer
     const U32 layerMask = (argc > 3) ? dAtoi(argv[3]) : MASK_ALL;
 
     // Set Collision Masks.
-    object->setCollisionMasks( groupMask, layerMask );
+    object->setCollisionGroupMask( groupMask );
+    object->setCollisionLayerMask( layerMask );
 }
 
 //-----------------------------------------------------------------------------
@@ -1125,121 +1126,121 @@ ConsoleMethod(SceneObject, setCollisionAgainst, void, 3, 4, "(SceneObject object
 //-----------------------------------------------------------------------------
 
 ConsoleMethod(SceneObject, setCollisionLayers, void, 3, 2 + MASK_BITCOUNT, "(layers$) - Sets the collision layers(s).\n"
-                                                                                  "@param layers A list of layers numbers to collide with.\n"
+                                                                                  "@param layers A list of layers to collide with.\n"
                                                       "@return No return value.")
 {
-   // The mask.
-   U32 mask = 0;
+    // The mask.
+    U32 mask = 0;
 
-   // Grab the element count of the first parameter.
-   const U32 elementCount = Utility::mGetStringElementCount(argv[2]);
+    // Grab the element count of the first parameter.
+    const U32 elementCount = Utility::mGetStringElementCount(argv[2]);
 
-   // Make sure we get at least one number.
-   if (elementCount < 1)
-   {
-      object->setCollisionLayers(0);
-      return;
-   }
+    // Make sure we get at least one number.
+    if (elementCount < 1)
+    {
+        object->setCollisionLayerMask(MASK_ALL);
+        return;
+    }
 
-   // Space separated list.
-   if (argc == 3)
-   {
-      // Convert the string to a mask.
-      for (U32 i = 0; i < elementCount; i++)
-      {
-         S32 bit = dAtoi(Utility::mGetStringElement(argv[2], i));
+    // Space separated list.
+    if (argc == 3)
+    {
+        // Convert the string to a mask.
+        for (U32 i = 0; i < elementCount; i++)
+        {
+            S32 bit = dAtoi(Utility::mGetStringElement(argv[2], i));
          
-         // Make sure the group is valid.
-         if ((bit < 0) || (bit >= MASK_BITCOUNT))
-         {
+            // Make sure the group is valid.
+            if ((bit < 0) || (bit >= MASK_BITCOUNT))
+            {
             Con::warnf("SceneObject::setCollisionLayers() - Invalid layer specified (%d); skipped!", bit);
             continue;
-         }
+            }
          
-         mask |= (1 << bit);
-      }
-   }
+            mask |= (1 << bit);
+        }
+    }
 
-   // Comma separated list.
-   else
-   {
-      // Convert the list to a mask.
-      for (U32 i = 2; i < (U32)argc; i++)
-      {
-         S32 bit = dAtoi(argv[i]);
+    // Comma separated list.
+    else
+    {
+        // Convert the list to a mask.
+        for (U32 i = 2; i < (U32)argc; i++)
+        {
+            S32 bit = dAtoi(argv[i]);
          
-         // Make sure the group is valid.
-         if ((bit < 0) || (bit >= MASK_BITCOUNT))
-         {
+            // Make sure the group is valid.
+            if ((bit < 0) || (bit >= MASK_BITCOUNT))
+            {
             Con::warnf("SceneObject::setCollisionLayers() - Invalid layer specified (%d); skipped!", bit);
             continue;
-         }
+            }
 
-         mask |= (1 << bit);
-      }
-   }
-   // Set Collision Groups.
-   object->setCollisionLayers(mask);
+            mask |= (1 << bit);
+        }
+    }
+    // Set Collision Layers
+    object->setCollisionLayerMask(mask);
 }
 
 //-----------------------------------------------------------------------------
 
 ConsoleMethod(SceneObject, setCollisionGroups, void, 3, 2 + MASK_BITCOUNT, "(groups$) - Sets the collision group(s).\n"
-                                                                                  "@param groups A list of collision group numbers to collide with.\n"
+                                                                                  "@param groups A list of collision groups to collide with.\n"
                                                                                 "@return No return value.")
 {
-   // The mask.
-   U32 mask = 0;
+    // The mask.
+    U32 mask = 0;
 
-   // Grab the element count of the first parameter.
-   const U32 elementCount = Utility::mGetStringElementCount(argv[2]);
+    // Grab the element count of the first parameter.
+    const U32 elementCount = Utility::mGetStringElementCount(argv[2]);
 
-   // Make sure we get at least one number.
-   if (elementCount < 1)
-   {
-      object->setCollisionGroups(0);
-      return;
-   }
+    // Make sure we get at least one number.
+    if (elementCount < 1)
+    {
+        object->setCollisionGroupMask(MASK_ALL);
+        return;
+    }
 
-   // Space separated list.
-   if (argc == 3)
-   {
-      // Convert the string to a mask.
-      for (U32 i = 0; i < elementCount; i++)
-      {
-         S32 bit = dAtoi(Utility::mGetStringElement(argv[2], i));
+    // Space separated list.
+    if (argc == 3)
+    {
+        // Convert the string to a mask.
+        for (U32 i = 0; i < elementCount; i++)
+        {
+            S32 bit = dAtoi(Utility::mGetStringElement(argv[2], i));
          
-         // Make sure the group is valid.
-         if ((bit < 0) || (bit >= MASK_BITCOUNT))
-         {
+            // Make sure the group is valid.
+            if ((bit < 0) || (bit >= MASK_BITCOUNT))
+            {
             Con::warnf("SceneObject::setCollisionGroups() - Invalid group specified (%d); skipped!", bit);
             continue;
-         }
+            }
          
-         mask |= (1 << bit);
-      }
-   }
+            mask |= (1 << bit);
+        }
+    }
 
-   // Comma separated list.
-   else
-   {
-      // Convert the list to a mask.
-      for (U32 i = 2; i < (U32)argc; i++)
-      {
-         S32 bit = dAtoi(argv[i]);
+    // Comma separated list.
+    else
+    {
+        // Convert the list to a mask.
+        for (U32 i = 2; i < (U32)argc; i++)
+        {
+            S32 bit = dAtoi(argv[i]);
          
-         // Make sure the group is valid.
-         if ((bit < 0) || (bit >= MASK_BITCOUNT))
-         {
+            // Make sure the group is valid.
+            if ((bit < 0) || (bit >= MASK_BITCOUNT))
+            {
             Con::warnf("SceneObject::setCollisionGroups() - Invalid group specified (%d); skipped!", bit);
             continue;
-         }
+            }
 
-         mask |= (1 << bit);
-      }
-   }
-   // Set Collision Groups.
-   object->setCollisionGroups(mask);
+            mask |= (1 << bit);
+        }
+    }
+    // Set Collision Groups.
+    object->setCollisionGroupMask(mask);
 }
 
 //-----------------------------------------------------------------------------
@@ -1247,23 +1248,23 @@ ConsoleMethod(SceneObject, setCollisionGroups, void, 3, 2 + MASK_BITCOUNT, "(gro
 ConsoleMethod(SceneObject, getCollisionLayers, const char*, 2, 2, "() - Gets the collision layers.\n"
                                                                      "@return (collisionLayers) A list of collision layers.")
 {
-   U32 mask = object->getCollisionLayerMask();
+    U32 mask = object->getCollisionLayerMask();
 
-   bool first = true;
-   char* bits = Con::getReturnBuffer(128);
-   bits[0] = '\0';
-   for (S32 i = 0; i < MASK_BITCOUNT; i++)
-   {
-      if (mask & BIT(i))
-      {
-         char bit[4];
-         dSprintf(bit, 4, "%s%d", first ? "" : " ", i);
-         first = false;
-         dStrcat(bits, bit);
-      }
-   }
+    bool first = true;
+    char* bits = Con::getReturnBuffer(128);
+    bits[0] = '\0';
+    for (S32 i = 0; i < MASK_BITCOUNT; i++)
+    {
+        if (mask & BIT(i))
+        {
+            char bit[4];
+            dSprintf(bit, 4, "%s%d", first ? "" : " ", i);
+            first = false;
+            dStrcat(bits, bit);
+        }
+    }
 
-   return bits;
+    return bits;
 }
 
 //-----------------------------------------------------------------------------
@@ -1271,23 +1272,23 @@ ConsoleMethod(SceneObject, getCollisionLayers, const char*, 2, 2, "() - Gets the
 ConsoleMethod(SceneObject, getCollisionGroups, const char*, 2, 2, "() - Gets the collision groups.\n"
                                                                      "@return (collisionGroups) A list of collision groups.")
 {
-   U32 mask = object->getCollisionGroupMask();
+    U32 mask = object->getCollisionGroupMask();
 
-   bool first = true;
-   char* bits = Con::getReturnBuffer(128);
-   bits[0] = '\0';
-   for (S32 i = 0; i < MASK_BITCOUNT; i++)
-   {
-      if (mask & BIT(i))
-      {
-         char bit[4];
-         dSprintf(bit, 4, "%s%d", first ? "" : " ", i);
-         first = false;
-         dStrcat(bits, bit);
-      }
-   }
+    bool first = true;
+    char* bits = Con::getReturnBuffer(128);
+    bits[0] = '\0';
+    for (S32 i = 0; i < MASK_BITCOUNT; i++)
+    {
+        if (mask & BIT(i))
+        {
+            char bit[4];
+            dSprintf(bit, 4, "%s%d", first ? "" : " ", i);
+            first = false;
+            dStrcat(bits, bit);
+        }
+    }
 
-   return bits;
+    return bits;
 }
 
 //-----------------------------------------------------------------------------

+ 2 - 0
engine/source/sim/simObject.h

@@ -727,6 +727,8 @@ public:
     SimObject* clone( const bool copyDynamicFields );
     virtual void copyTo(SimObject* object);
 
+    template<typename T> bool isType(void) { return dynamic_cast<T>(this) != NULL; }
+
     // Component Console Overrides
     virtual bool handlesConsoleMethod(const char * fname, S32 * routingId) { return false; }
     DECLARE_CONOBJECT(SimObject);

+ 30 - 30
modules/ConstantForceControllerToy/1/main.cs → modules/AmbientForceControllerToy/1/main.cs

@@ -20,7 +20,7 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::create( %this )
+function AmbientForceControllerToy::create( %this )
 {
     // Set the sandbox drag mode availability.
     Sandbox.allowManipulation( pan );
@@ -30,29 +30,29 @@ function ConstantForceControllerToy::create( %this )
     Sandbox.useManipulation( pull );
     
     // Configure settings.
-    ConstantForceControllerToy.ForceAngle = 45;
-    ConstantForceControllerToy.ForceMagnitude = 50;
-    ConstantForceControllerToy.DebrisCount = 100;
+    AmbientForceControllerToy.ForceAngle = 45;
+    AmbientForceControllerToy.ForceMagnitude = 50;
+    AmbientForceControllerToy.DebrisCount = 100;
 
     // Add options.    
-    addNumericOption("Force Angle", -359, 359, 1, "setForceAngle", ConstantForceControllerToy.ForceAngle, false, "The angle of the constant force.");   
-    addNumericOption("Force Magnitude", 0, 1000, 10, "setForceMagnitude", ConstantForceControllerToy.ForceMagnitude, false, "The magnitude of the constant force.");   
-    addNumericOption("Debris Count", 10, 1000, 10, "setDebrisCount", ConstantForceControllerToy.DebrisCount, true, "The amount of debris affected by the constant force controller.");
+    addNumericOption("Force Angle", -359, 359, 1, "setForceAngle", AmbientForceControllerToy.ForceAngle, false, "The angle of the ambient force.");   
+    addNumericOption("Force Magnitude", 0, 1000, 10, "setForceMagnitude", AmbientForceControllerToy.ForceMagnitude, false, "The magnitude of the ambient force.");   
+    addNumericOption("Debris Count", 10, 1000, 10, "setDebrisCount", AmbientForceControllerToy.DebrisCount, true, "The amount of debris affected by the ambient force controller.");
     
     // Reset the toy.
-    ConstantForceControllerToy.reset();
+    AmbientForceControllerToy.reset();
 }
 
 
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::destroy( %this )
+function AmbientForceControllerToy::destroy( %this )
 {
 }
 
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::reset( %this )
+function AmbientForceControllerToy::reset( %this )
 {
     // Clear the scene.
     SandboxScene.clear();
@@ -60,13 +60,13 @@ function ConstantForceControllerToy::reset( %this )
     // Create background.
     %this.createBackground();
     
-    // Create constant force controller.
-    %this.createConstantForceController();
+    // Create ambient force controller.
+    %this.createAmbientForceController();
 }
 
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::createBackground( %this )
+function AmbientForceControllerToy::createBackground( %this )
 {    
     // Create the sprite.
     %object = new Sprite();
@@ -89,7 +89,7 @@ function ConstantForceControllerToy::createBackground( %this )
     %object.Image = "ToyAssets:highlightBackground";
     
     // Set the blend color.
-    %object.BlendColor = LightBlue;
+    %object.BlendColor = DarkGray;
     
     // Create border collisions.
     %object.createEdgeCollisionShape( -50, -37.5, -50, 37.5 );
@@ -104,7 +104,7 @@ function ConstantForceControllerToy::createBackground( %this )
 
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::createSprite( %this, %asset, %position, %size, %angle, %blendColor )
+function AmbientForceControllerToy::createSprite( %this, %asset, %position, %size, %angle, %blendColor )
 {    
     // Create the sprite.
     %object = new Sprite();
@@ -132,22 +132,22 @@ function ConstantForceControllerToy::createSprite( %this, %asset, %position, %si
 
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::createConstantForceController( %this )
+function AmbientForceControllerToy::createAmbientForceController( %this )
 {
     // Create a new controller.
-    %controller = new ConstantForceController();
+    %controller = new AmbientForceController();
     
     // Set scene controller.
-    ConstantForceControllerToy.SceneController = %controller;
+    AmbientForceControllerToy.SceneController = %controller;
 
-    // Update the constant force controller.
-    %this.updateConstantForceController();
+    // Update the ambient force controller.
+    %this.updateAmbientForceController();
     
     // Add the controller.
     SandboxScene.Controllers.add( %controller );
    
     // Create some sprites used by the controller.
-    for( %n = 0; %n < ConstantForceControllerToy.DebrisCount; %n++ )
+    for( %n = 0; %n < AmbientForceControllerToy.DebrisCount; %n++ )
     {    
         %sizeX = getRandom(1,4);
         %sizeY = getRandom(1,4);
@@ -178,35 +178,35 @@ function ConstantForceControllerToy::createConstantForceController( %this )
 
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::updateConstantForceController( %this )
+function AmbientForceControllerToy::updateAmbientForceController( %this )
 {
     // Calculate the force.
-    ConstantForceControllerToy.SceneController.Force = Vector2Direction( %this.ForceAngle, %this.ForceMagnitude );
+    AmbientForceControllerToy.SceneController.Force = Vector2Direction( %this.ForceAngle, %this.ForceMagnitude );
 }
 
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::setForceAngle(%this, %value)
+function AmbientForceControllerToy::setForceAngle(%this, %value)
 {
     %this.ForceAngle = %value;
     
-    // Update the constant force.
-    %this.updateConstantForceController();   
+    // Update the ambient force.
+    %this.updateAmbientForceController();   
 }
 
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::setForceMagnitude(%this, %value)
+function AmbientForceControllerToy::setForceMagnitude(%this, %value)
 {
     %this.ForceMagnitude = %value;
     
-    // Update the constant force.
-    %this.updateConstantForceController();    
+    // Update the ambient force.
+    %this.updateAmbientForceController();    
 }
 
 //-----------------------------------------------------------------------------
 
-function ConstantForceControllerToy::setDebrisCount(%this, %value)
+function AmbientForceControllerToy::setDebrisCount(%this, %value)
 {
     %this.DebrisCount = %value;
 }

+ 2 - 2
modules/ConstantForceControllerToy/1/module.taml → modules/AmbientForceControllerToy/1/module.taml

@@ -1,7 +1,7 @@
 <ModuleDefinition
-	ModuleId="ConstantForceControllerToy"
+	ModuleId="AmbientForceControllerToy"
 	VersionId="1"
-	Description="Demonstrates using a constant-force controller."
+	Description="Demonstrates using an ambient-force controller."
 	Dependencies="ToyAssets=1"
 	Type="toy"
 	ToyCategoryIndex="3"

+ 0 - 3
modules/BuoyancyControllerToy/1/assets/images/background.asset.taml

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

BIN
modules/BuoyancyControllerToy/1/assets/images/background.jpg


+ 0 - 3
modules/BuoyancyControllerToy/1/assets/images/beam.asset.taml

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

BIN
modules/BuoyancyControllerToy/1/assets/images/beam.png


+ 0 - 3
modules/BuoyancyControllerToy/1/assets/images/bubble.asset.taml

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

BIN
modules/BuoyancyControllerToy/1/assets/images/bubble.png


+ 0 - 3
modules/BuoyancyControllerToy/1/assets/images/rocksfar.asset.taml

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

BIN
modules/BuoyancyControllerToy/1/assets/images/rocksfar.png


+ 0 - 3
modules/BuoyancyControllerToy/1/assets/images/rocksnear.asset.taml

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

BIN
modules/BuoyancyControllerToy/1/assets/images/rocksnear.png


+ 0 - 3
modules/BuoyancyControllerToy/1/assets/images/wave.asset.taml

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

BIN
modules/BuoyancyControllerToy/1/assets/images/wave.png


+ 3 - 0
modules/BuoyancyControllerToy/1/assets/images/waveCrests.asset.taml

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

BIN
modules/BuoyancyControllerToy/1/assets/images/waveCrests.png


+ 116 - 176
modules/BuoyancyControllerToy/1/main.cs

@@ -33,9 +33,7 @@ function BuoyancyControllerToy::create( %this )
     SandboxScene.setGravity( 0, -29.8 );
     
     // Configure settings.
-    BuoyancyControllerToy.FluidArea = "-30 -30 30 0";
-    BuoyancyControllerToy.SurfaceNormal = "0 1";
-    BuoyancyControllerToy.SurfaceOffset = 0;
+    BuoyancyControllerToy.FluidArea = "-30 -34 30 0";
     BuoyancyControllerToy.FluidDensity = 2.5;
     BuoyancyControllerToy.LinearDrag = 3;
     BuoyancyControllerToy.AngularDrag = 3;
@@ -48,9 +46,10 @@ function BuoyancyControllerToy::create( %this )
     BuoyancyControllerToy.MaxDebrisCount = 50;
     BuoyancyControllerToy.MinDebrisDensity = 1;
     BuoyancyControllerToy.MaxDebrisDensity = 1;
+    
+    BuoyancyControllerToy.GroundWidth = 140;
 
     // Add options.    
-    addNumericOption("Surface Offset", -35, 35, 1, "setSurfaceOffset", BuoyancyControllerToy.SurfaceOffset, false, "The height of the fluid surface along the normal.");
     addNumericOption("Fluid Density", 0, 10, 0.1, "setFluidDensity", BuoyancyControllerToy.FluidDensity, false, "The fluid density.");   
     addNumericOption("Fluid Flow Angle", -359, 359, 1, "setFluidFlowAngle", BuoyancyControllerToy.FlowAngle, true, "The angle of the constant force.");   
     addNumericOption("Fluid Flow Magnitude", 0, 1000, 10, "setFluidFlowMagnitude", BuoyancyControllerToy.FlowMagnitude, true, "The magnitude of the constant force.");      
@@ -65,7 +64,6 @@ function BuoyancyControllerToy::create( %this )
     BuoyancyControllerToy.reset();
 }
 
-
 //-----------------------------------------------------------------------------
 
 function BuoyancyControllerToy::destroy( %this )
@@ -78,97 +76,27 @@ function BuoyancyControllerToy::reset( %this )
 {
     // Clear the scene.
     SandboxScene.clear();
-
-    // Build the aquarium.       
-    %this.buildAquarium();
-    
-    // Create the aquarium effects.
-    %this.createAquariumEffects();
-           
-    // Create background.
-    %this.createBackground();
-    
-    // Create buoyancy controller.
-    %this.createBuoyancyController();
-    
-    // Create the water overlay.
-    %this.createWaterOverlay();   
-}
-
-//-----------------------------------------------------------------------------
-
-function BuoyancyControllerToy::buildAquarium(%this)
-{
-    // Background
-    %background = new Sprite();
-    %background.setBodyType( "static" );
-    %background.setImage( "BuoyancyControllerToy:background" );
-    %background.setPosition( 0, -18.75 );
-    %background.setSize( 100, 37.5 );
-    %background.setCollisionSuppress();
-    %background.setAwake( false );
-    %background.setActive( false );
-    %background.setSceneLayer(5);
-    SandboxScene.add( %background );
     
-    // Far rocks
-    %farRocks = new Sprite();
-    %farRocks.setBodyType( "static" );
-    %farRocks.setImage( "BuoyancyControllerToy:rocksfar" );
-    %farRocks.setPosition( 0, -18.75 );
-    %farRocks.setSize( 100, 37.5 );
-    %farRocks.setCollisionSuppress();
-    %farRocks.setAwake( false );
-    %farRocks.setActive( false );
-    %farRocks.setSceneLayer(4);
-    SandboxScene.add( %farRocks );
-    
-    // Near rocks
-    %nearRocks = new Sprite();
-    %nearRocks.setBodyType( "static" );
-    %nearRocks.setPosition( 0, -18.75 );
-    %nearRocks.setImage( "BuoyancyControllerToy:rocksnear" );
-    %nearRocks.setSize( 100, 37.5 );
-    %nearRocks.setCollisionSuppress();
-    %nearRocks.setAwake( false );
-    %nearRocks.setActive( false );
-    %nearRocks.setSceneLayer(3);
-    SandboxScene.add( %nearRocks ); 
-}
-
-//-----------------------------------------------------------------------------
+    // Calculate fluid bounds to help layout only.
+    BuoyancyControllerToy.FluidLeft = getWord( BuoyancyControllerToy.FluidArea, 0 );
+    BuoyancyControllerToy.FluidBottom = getWord( BuoyancyControllerToy.FluidArea, 1 );
+    BuoyancyControllerToy.FluidRight = getWord( BuoyancyControllerToy.FluidArea, 2 );
+    BuoyancyControllerToy.FluidTop = getWord( BuoyancyControllerToy.FluidArea, 3 );    
 
-function BuoyancyControllerToy::createAquariumEffects(%this)
-{
-    %obj = new Scroller();
-    %obj.setBodyType( "static" );
-    %obj.setImage( "BuoyancyControllerToy:wave" );
-    %obj.setPosition( 0, 0 );
-    %obj.setScrollX(2);
-    %obj.setPosition( 0, -18.75 );
-    %obj.setSize( 100, 37.5 );
-    %obj.setRepeatX( 0.2 );   
-    %obj.setSceneLayer( 0 );
-    %obj.setSceneGroup( 0 );
-    %obj.setCollisionSuppress();
-    %obj.setAwake( false );
-    %obj.setActive( false );
-    SandboxScene.add( %obj );
-}
-
-//-----------------------------------------------------------------------------
-
-function BuoyancyControllerToy::createWaterOverlay( %this )
-{
-    // Add the water.
-    %water = new Sprite();
-    %water.BodyType = static;
-    %water.Position = "0 -18.75";
-    %water.Size = "100 37.5";
-    %water.Image = "ToyAssets:SkyBackground";
-    %water.SetBlendAlpha( 0.6 );
-    
-    SandboxScene.add( %water );      
+    // Create a background.
+    %this.createBackground();
+   
+    // Create fluid.
+    %this.createFluid("-45 -30 -30 -20");
+    %this.createFluid("-35 5 10 20");
+    %this.createFluid("-25 -25 15 -5");
+    %this.createFluid("25 -25 45 10");
+    
+    // Create debris.    
+    %this.createDebris();   
+    
+    // Update the buoyancy controllers.
+    %this.updateBuoyancyControllers();     
 }
 
 //-----------------------------------------------------------------------------
@@ -177,42 +105,26 @@ function BuoyancyControllerToy::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.
-
-    // Set the position.
+    %object.BodyType = static;
     %object.Position = "0 0";
-
-    // Set the size.        
     %object.Size = "100 75";
-    
-    // Set to the furthest background layer.
     %object.SceneLayer = 31;
-    
-    // Set the scroller to use an animation!
-    %object.Image = "ToyAssets:skyBackground";
-
-    // Flip the sky.
-    %object.FlipY = true;
-    
-    // Set the blend color.
-    %object.BlendColor = LightBlue;
+    %object.Image = "ToyAssets:highlightBackground";
+    %object.BlendColor = SlateGray;
+    SandboxScene.add( %object );
     
     // Create border collisions.
     %object.createEdgeCollisionShape( -50, -37.5, -50, 37.5 );
     %object.createEdgeCollisionShape( 50, -37.5, 50, 37.5 );
-    %object.createEdgeCollisionShape( -50, -34.5, 50, -34.5 );
-        
+    %object.createEdgeCollisionShape( -50, -34, 50, -34 );
+                
     // Add the sprite to the scene.
     SandboxScene.add( %object );    
 }
 
 //-----------------------------------------------------------------------------
 
-function BuoyancyControllerToy::createSprite( %this, %asset, %position, %size, %angle, %blendColor )
+function BuoyancyControllerToy::createSprite( %this, %asset, %position, %size, %angle )
 {    
     // Create the sprite.
     %object = new Sprite();
@@ -229,9 +141,9 @@ function BuoyancyControllerToy::createSprite( %this, %asset, %position, %size, %
     // Set the scroller to use an animation!
     %object.Image = %asset;
     
-    // Set the blend color.
-    %object.BlendColor = %blendColor $= "" ? White : %blendColor;
-            
+    // Set the scene layer.
+    %object.SceneLayer = 10;
+    
     // Add the sprite to the scene.
     SandboxScene.add( %object );    
     
@@ -240,20 +152,8 @@ function BuoyancyControllerToy::createSprite( %this, %asset, %position, %size, %
 
 //-----------------------------------------------------------------------------
 
-function BuoyancyControllerToy::createBuoyancyController( %this )
-{
-    // Create a new controller.
-    %controller = new BuoyancyController();
-    
-    // Set scene controller.
-    BuoyancyControllerToy.SceneController = %controller;  
-    
-    // Update the controller.
-    %this.updateBuoyancyController();  
-    
-    // Add the controller.
-    SandboxScene.Controllers.add( %controller );
-    
+function BuoyancyControllerToy::createDebris( %this )
+{  
     // Fetch the debris count.
     %debrisCount = BuoyancyControllerToy.MaxDebrisCount;
 
@@ -262,46 +162,78 @@ function BuoyancyControllerToy::createBuoyancyController( %this )
         // Choose a random debris (polygon or circle shapes).
         if ( getRandom(0,100) < 10 )
         {    
-            %size = 3;
+            %size = 2;
             
             // Create some sprites.
-            %sprite = %this.createSprite( "ToyAssets:football", getRandom(-40,40) SPC getRandom(50,70), %size, getRandom(0,360), White );
+            %sprite = %this.createSprite( "ToyAssets:football", getRandom(-40,40) SPC getRandom(50,70), %size, getRandom(0,360) );
             %sprite.setDefaultFriction( 0.5 );
             %sprite.setDefaultDensity( getRandom(%this.MinDebrisDensity, %this.MaxDebrisDensity) );
             %sprite.createCircleCollisionShape( %size * 0.5 );
             %sprite.setAngularVelocity(getRandom(-180,180));
-            
-            // Add to the controller.
-            %controller.add( %sprite );
         }
         else
         {    
-            %sizeX = getRandom(1,10);
+            %sizeX = getRandom(1,5);
             %sizeY = getRandom(1,2);
             %size = %sizeX SPC %sizeY;
             
             // Create some sprites.
-            %sprite = %this.createSprite( "ToyAssets:Blocks", getRandom(-40,40) SPC getRandom(50,70), %size, getRandom(0,360), White );
+            %sprite = %this.createSprite( "ToyAssets:Blocks", getRandom(-40,40) SPC getRandom(50,70), %size, getRandom(0,360) );
             %sprite.Frame = getRandom( 0, 55 );
             %sprite.setDefaultFriction( 0.5 );
             %sprite.setDefaultDensity( getRandom(%this.MinDebrisDensity, %this.MaxDebrisDensity) );
             %sprite.createPolygonBoxCollisionShape( %sizeX, %sizeY );
             %sprite.setAngularVelocity(getRandom(-180,180));
-            
-            // Add to the controller.
-            %controller.add( %sprite );
         }
-    }
+    }    
 }
 
+
 //-----------------------------------------------------------------------------
 
-function BuoyancyControllerToy::setSurfaceOffset(%this, %value)
+function BuoyancyControllerToy::createFluid( %this, %area )
 {
-    %this.SurfaceOffset = %value;
+    %areaLeft = getWord( %area, 0 );
+    %areaBottom = getWord( %area, 1 );
+    %areaRight = getWord( %area, 2 );
+    %areaTop = getWord( %area, 3 );
+
+    %crestHeight = 0.2;
+    %crestY = %areaTop - ((%areaTop - %areaBottom) * %crestHeight);
     
-    // Update the controller.
-    %this.updateBuoyancyController();   
+    // Add the water.
+    %water = new Sprite();
+    %water.BodyType = static;
+    %water.setArea( %areaLeft SPC %areaBottom SPC %areaRight SPC %crestY);
+    %water.Image = "ToyAssets:Blank";
+    %water.BlendColor = Navy;    
+    %water.SetBlendAlpha( 0.5 );
+    SandboxScene.add( %water );
+
+    // Create some wave crests.
+    %crests1 = new Scroller();   
+    %crests1.setArea( %areaLeft SPC %crestY SPC %areaRight SPC %areaTop );
+    %crests1.Image = "BuoyancyControllerToy:WaveCrests";
+    %crests1.BlendColor = Navy;    
+    %crests1.SetBlendAlpha( 0.3 );
+    %crests1.ScrollX = getRandom(5,10);
+    %crests2.ScrollPositionX = getRandom(0,50);
+    SandboxScene.add( %crests1 );
+    
+    // Create some wave crests.
+    %crests2 = new Scroller();   
+    %crests2.setArea( %areaLeft SPC %crestY SPC %areaRight SPC %areaTop );
+    %crests2.Image = "BuoyancyControllerToy:WaveCrests";
+    %crests2.BlendColor = Navy;    
+    %crests2.SetBlendAlpha( 0.3 );
+    %crests2.ScrollX = getRandom(-5,-10);
+    %crests2.ScrollPositionX = getRandom(0,50);
+    SandboxScene.add( %crests2 );    
+        
+    // Create a new controller.
+    %controller = new BuoyancyController();
+    %controller.FluidArea = %area;
+    SandboxScene.Controllers.add( %controller );    
 }
 
 //-----------------------------------------------------------------------------
@@ -310,8 +242,8 @@ function BuoyancyControllerToy::setFluidFlowAngle(%this, %value)
 {
     %this.FlowAngle = %value;
     
-    // Update the controller.
-    %this.updateBuoyancyController();   
+    // Update the controllers.
+    %this.updateBuoyancyControllers();   
 }
 
 //-----------------------------------------------------------------------------
@@ -320,8 +252,8 @@ function BuoyancyControllerToy::setFluidFlowMagnitude(%this, %value)
 {
     %this.FlowMagnitude = %value;
     
-    // Update the controller.
-    %this.updateBuoyancyController();   
+    // Update the controllers.
+    %this.updateBuoyancyControllers();   
 }
 
 //-----------------------------------------------------------------------------
@@ -330,8 +262,8 @@ function BuoyancyControllerToy::setFluidDensity(%this, %value)
 {
     %this.FluidDensity = %value;
     
-    // Update the controller.
-    %this.updateBuoyancyController();   
+    // Update the controllers.
+    %this.updateBuoyancyControllers();   
 }
 
 //-----------------------------------------------------------------------------
@@ -340,8 +272,8 @@ function BuoyancyControllerToy::setLinearDrag(%this, %value)
 {
     %this.LinearDrag = %value;
     
-    // Update the controller.
-    %this.updateBuoyancyController();   
+    // Update the controllers.
+    %this.updateBuoyancyControllers();   
 }
 
 //-----------------------------------------------------------------------------
@@ -350,8 +282,8 @@ function BuoyancyControllerToy::setAngularDrag(%this, %value)
 {
     %this.AngularDrag = %value;
     
-    // Update the controller.
-    %this.updateBuoyancyController();   
+    // Update the controllers.
+    %this.updateBuoyancyControllers();   
 }
 
 //-----------------------------------------------------------------------------
@@ -360,8 +292,8 @@ function BuoyancyControllerToy::setFluidGravity(%this, %value)
 {
     %this.FluidGravity = %value;
     
-    // Update the controller.
-    %this.updateBuoyancyController();   
+    // Update the controllers.
+    %this.updateBuoyancyControllers();   
 }
 
 //-----------------------------------------------------------------------------
@@ -370,8 +302,8 @@ function BuoyancyControllerToy::setUseShapeDensity(%this, %value)
 {
     %this.UseShapeDensity = %value;
     
-    // Update the controller.
-    %this.updateBuoyancyController();   
+    // Update the controllers.
+    %this.updateBuoyancyControllers();   
 }
 
 //-----------------------------------------------------------------------------
@@ -397,19 +329,27 @@ function BuoyancyControllerToy::setMaxDebrisDensity(%this, %value)
 
 //-----------------------------------------------------------------------------
 
-function BuoyancyControllerToy::updateBuoyancyController( %this )
+function BuoyancyControllerToy::updateBuoyancyControllers( %this )
 {
-    // Fetch the buoyancy controller.
-    %controller = BuoyancyControllerToy.SceneController;
+    // Fetch the controller set.
+    %controllerSet = SandboxScene.Controllers;
     
-    // Update the controller.
-    %controller.FluidArea = BuoyancyControllerToy.FluidArea;
-    %controller.SurfaceNormal = BuoyancyControllerToy.SurfaceNormal;
-    %controller.SurfaceOffset = BuoyancyControllerToy.SurfaceOffset;
-    %controller.FluidDensity = BuoyancyControllerToy.FluidDensity;
-    %controller.FlowVelocity = Vector2Direction( %this.FlowAngle, %this.FlowMagnitude );
-    %controller.LinearDrag = BuoyancyControllerToy.LinearDrag;
-    %controller.AngularDrag = BuoyancyControllerToy.AngularDrag;
-    %controller.FluidGravity = BuoyancyControllerToy.FluidGravity;
-    %controller.UseShapeDensity = BuoyancyControllerToy.UseShapeDensity;
+    // Fetch controller count.
+    %controllerCount = %controllerSet.getCount();
+    
+    // Iterate controllers.
+    for( %i = 0; %i < %controllerCount; %i++ )
+    {
+        %controller = %controllerSet.getObject(%i);
+        if ( %controller.getClassName() !$= "BuoyancyController" )
+            continue;
+
+        // Update the controllers.
+        %controller.FluidDensity = BuoyancyControllerToy.FluidDensity;
+        %controller.FlowVelocity = Vector2Direction( %this.FlowAngle, %this.FlowMagnitude );
+        %controller.LinearDrag = BuoyancyControllerToy.LinearDrag;
+        %controller.AngularDrag = BuoyancyControllerToy.AngularDrag;
+        %controller.FluidGravity = BuoyancyControllerToy.FluidGravity;
+        %controller.UseShapeDensity = BuoyancyControllerToy.UseShapeDensity;        
+    }
 }

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

@@ -87,7 +87,7 @@ function MoveToToy::createBackground( %this )
     %object.Image = "ToyAssets:highlightBackground";
     
     // Set the blend color.
-    %object.BlendColor = Bisque;
+    %object.BlendColor = SlateGray;
             
     // Add the sprite to the scene.
     SandboxScene.add( %object );    

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

@@ -89,7 +89,7 @@ function PointForceControllerToy::createBackground( %this )
     %object.Image = "ToyAssets:highlightBackground";
     
     // Set the blend color.
-    %object.BlendColor = LightBlue;
+    %object.BlendColor = SlateGray;
     
     // Create border collisions.
     %object.createEdgeCollisionShape( -50, -37.5, -50, 37.5 );

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

@@ -85,7 +85,7 @@ function RotateToToy::createBackground( %this )
     %object.Image = "ToyAssets:highlightBackground";
     
     // Set the blend color.
-    %object.BlendColor = Bisque;
+    %object.BlendColor = SlateGray;
             
     // Add the sprite to the scene.
     SandboxScene.add( %object );    

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

@@ -77,7 +77,7 @@ function SceneLayerToy::createBackground( %this )
     %object.Image = "ToyAssets:highlightBackground";
     
     // Set the blend color.
-    %object.BlendColor = Bisque;
+    %object.BlendColor = SlateGray;
             
     // Add the sprite to the scene.
     SandboxScene.add( %object );    

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

@@ -81,7 +81,7 @@ function SpriteToy::createBackground( %this )
     %object.Image = "ToyAssets:highlightBackground";
     
     // Set the blend color.
-    %object.BlendColor = Bisque;
+    %object.BlendColor = SlateGray;
             
     // Add the sprite to the scene.
     SandboxScene.add( %object );    

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


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

@@ -185,7 +185,7 @@ function TruckToy::createBackground(%this)
     %obj = new Sprite();
     %obj.setBodyType( "static" );
     %obj.setImage( "ToyAssets:highlightBackground" );
-    //%obj.setImage( "TruckToy:background_day" );
+    %obj.BlendColor = DarkGray;
     %obj.setSize( TruckToy.WorldWidth * (TruckToy.CameraWidth*2), 75 );
     %obj.setSceneLayer( TruckToy.BackdropDomain );
     %obj.setSceneGroup( TruckToy.BackdropDomain );