瀏覽代碼

add hud to cpp ragdoll example

JimMarlowe 9 年之前
父節點
當前提交
89909d8443

二進制
FeatureExamples/CPlusPlus/Data/NinjaSnowWar/Sight.png


+ 10 - 0
FeatureExamples/CPlusPlus/Data/PostProcess/FrontPath.xml

@@ -0,0 +1,10 @@
+<renderpath>
+    <command type="scenepass" pass="base" vertexlights="true" metadata="base" />
+    <command type="forwardlights" pass="light" />
+    <command type="scenepass" pass="postopaque" />
+    <command type="scenepass" pass="refract">
+        <texture unit="environment" name="viewport" />
+    </command>
+    <command type="scenepass" pass="alpha" vertexlights="true" sort="backtofront" metadata="alpha" />
+    <command type="scenepass" pass="postalpha" sort="backtofront" />
+</renderpath>

二進制
FeatureExamples/CPlusPlus/Data/hudfill1.png


二進制
FeatureExamples/CPlusPlus/Data/hudfill2.png


二進制
FeatureExamples/CPlusPlus/Data/hudfill3.png


二進制
FeatureExamples/CPlusPlus/Data/hudfill4.png


二進制
FeatureExamples/CPlusPlus/Data/hudfill5.png


二進制
FeatureExamples/CPlusPlus/Data/hudfill6.png


二進制
FeatureExamples/CPlusPlus/Data/hudmass.png


二進制
FeatureExamples/CPlusPlus/Data/hudsize.png


二進制
FeatureExamples/CPlusPlus/Data/hudspeed.png


+ 45 - 1
FeatureExamples/CPlusPlus/Source/CreateRagdoll.cpp

@@ -25,6 +25,11 @@
 #include <Atomic/IO/Log.h>
 #include <Atomic/IO/Log.h>
 #include <Atomic/Physics/PhysicsEvents.h>
 #include <Atomic/Physics/PhysicsEvents.h>
 #include <Atomic/Physics/RigidBody.h>
 #include <Atomic/Physics/RigidBody.h>
+#include <Atomic/Scene/Scene.h>
+#include <Atomic/Resource/ResourceCache.h>
+#include <Atomic/Graphics/Material.h>
+#include <Atomic/Graphics/ParticleEmitter.h>
+#include <Atomic/Graphics/ParticleEffect.h>
 
 
 #include "CreateRagdoll.h"
 #include "CreateRagdoll.h"
 
 
@@ -52,7 +57,9 @@ void CreateRagdoll::HandleNodeCollision(StringHash eventType, VariantMap& eventD
 
 
     if (otherBody->GetMass() > 0.0f)
     if (otherBody->GetMass() > 0.0f)
     {
     {
-        // We do not need the physics components in the AnimatedModel's root scene node anymore
+        HitEffect (node_); // bam!
+
+       // We do not need the physics components in the AnimatedModel's root scene node anymore
         node_->RemoveComponent<RigidBody>();
         node_->RemoveComponent<RigidBody>();
         node_->RemoveComponent<CollisionShape>();
         node_->RemoveComponent<CollisionShape>();
 
 
@@ -173,3 +180,40 @@ void CreateRagdoll::CreateRagdollConstraint(const String& boneName, const String
     constraint->SetHighLimit(highLimit);
     constraint->SetHighLimit(highLimit);
     constraint->SetLowLimit(lowLimit);
     constraint->SetLowLimit(lowLimit);
 }
 }
+
+void CreateRagdoll::HitEffect ( Node* parent ) // ragdoll gets the donuts blown out of him
+{
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+    Scene* myscene = parent->GetScene ();
+    Vector3 where = parent->GetWorldPosition ();
+    
+    for (int mm=0; mm<5; mm++)
+    {
+        Node* xNode = myscene->CreateChild("Stuffing");
+        xNode->SetPosition( Vector3( Random(1), Random(4), Random(15)) + where );
+        xNode->SetRotation( Quaternion(Random(360), 0, Random(360)));
+        xNode->SetScale(0.3f);
+
+        ParticleEmitter* pEmitter = xNode->CreateComponent<ParticleEmitter>();
+        pEmitter->SetEffect(cache->GetResource<ParticleEffect>("Particle/Fire.xml"));
+        pEmitter->SetEnabled(true);  // sparkle donuts
+
+        //create obj
+        StaticModel* boxObject = xNode->CreateComponent<StaticModel>();
+        boxObject->SetModel(cache->GetResource<Model>("Models/Torus.mdl"));
+        boxObject->SetMaterial(cache->GetResource<Material>("Materials/Mushroom.xml"));
+        boxObject->SetCastShadows(true);
+        RigidBody* body = xNode->CreateComponent<RigidBody>();
+        body->SetMass( 0.45f);
+        body->SetRollingFriction(0.15f);
+        body->SetFriction( 0.75f);
+        body->SetUseGravity (true);
+        // Disable collision event signaling to reduce CPU load of the physics simulation a111
+        body->SetCollisionEventMode( COLLISION_NEVER );
+        CollisionShape* shape = xNode->CreateComponent<CollisionShape>();
+        shape->SetSphere(1.0f, Vector3(0,0,0), Quaternion(1,0,0,0));
+        float objectVelocity = 22.0f;
+        //Node.Rotation
+        body->SetLinearVelocity( Quaternion(Random(360), 0, Random(360))* Vector3(0.0f, 0.02f, 1.0f) * objectVelocity);
+    }
+}

+ 1 - 0
FeatureExamples/CPlusPlus/Source/CreateRagdoll.h

@@ -40,6 +40,7 @@ public:
 protected:
 protected:
     /// Handle node being assigned.
     /// Handle node being assigned.
     virtual void OnNodeSet(Node* node);
     virtual void OnNodeSet(Node* node);
+    void HitEffect ( Node* parent ); // ragdoll gets the donuts blown out of him
     
     
 private:
 private:
     /// Handle scene node's physics collision.
     /// Handle scene node's physics collision.

+ 332 - 59
FeatureExamples/CPlusPlus/Source/Ragdolls.cpp

@@ -41,6 +41,12 @@
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/Resource/ResourceCache.h>
 #include <Atomic/Scene/Scene.h>
 #include <Atomic/Scene/Scene.h>
 #include <Atomic/UI/UI.h>
 #include <Atomic/UI/UI.h>
+#include <Atomic/Atomic2D/StaticSprite2D.h>
+#include <Atomic/Atomic2D/AnimationSet2D.h>
+#include <Atomic/Atomic2D/AnimatedSprite2D.h>
+#include <Atomic/Atomic2D/Sprite2D.h>
+#include <Atomic/Graphics/RenderPath.h>
+#include <Atomic/Resource/XMLFile.h>
 
 
 #include "CreateRagdoll.h"
 #include "CreateRagdoll.h"
 #include "Ragdolls.h"
 #include "Ragdolls.h"
@@ -53,6 +59,36 @@ Ragdolls::Ragdolls(Context* context) :
 {
 {
     // Register an object factory for our custom CreateRagdoll component so that we can create them to scene nodes
     // Register an object factory for our custom CreateRagdoll component so that we can create them to scene nodes
     context->RegisterFactory<CreateRagdoll>();
     context->RegisterFactory<CreateRagdoll>();
+    
+    massCount = 2;
+    speedCount = 2;
+    sizeCount = 2;
+
+    bulletMass.Push(1.0f);
+    bulletMass.Push(10.0f);
+    bulletMass.Push(50.0f);
+    bulletMass.Push(100.0f);
+    bulletMass.Push(300.0f);
+    bulletMass.Push(666.0f);
+    bulletMass.Push(1000.0f);
+    bulletSpeed.Push(10.0f);
+    bulletSpeed.Push(22.0f);
+    bulletSpeed.Push(41.0f);
+    bulletSpeed.Push(72.0f);
+    bulletSpeed.Push(116.0f);
+    bulletSpeed.Push(200.0f);
+    bulletSpeed.Push(450.0f);
+    bulletSize.Push(0.25f);
+    bulletSize.Push(0.5f);
+    bulletSize.Push(1.25f);
+    bulletSize.Push(3.25f);
+    bulletSize.Push(5.25f);
+    bulletSize.Push(7.25f);
+    bulletSize.Push(11.25f);
+    bulletSize.Push(16.25f);
+
+    bulletArc = 0.25f;
+
 }
 }
 
 
 void Ragdolls::Start()
 void Ragdolls::Start()
@@ -63,6 +99,9 @@ void Ragdolls::Start()
     // Create the scene content
     // Create the scene content
     CreateScene();
     CreateScene();
 
 
+    // add an overlay HUD that tells you settings
+    CreateHUD();
+
     // Create the UI content
     // Create the UI content
     CreateInstructions();
     CreateInstructions();
 
 
@@ -74,6 +113,15 @@ void Ragdolls::Start()
 
 
     // Set the mouse mode to use in the sample
     // Set the mouse mode to use in the sample
     Sample::InitMouseMode(MM_ABSOLUTE);
     Sample::InitMouseMode(MM_ABSOLUTE);
+    
+    RestartJacks ();
+
+    UpdateSpeedHud (speedCount);
+    UpdateMassHud (massCount);
+    UpdateSizeHud (sizeCount);
+
+    GetSubsystem<Input>()->SetMouseVisible (false);
+
 }
 }
 
 
 void Ragdolls::CreateScene()
 void Ragdolls::CreateScene()
@@ -109,57 +157,23 @@ void Ragdolls::CreateScene()
     // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance
     // Set cascade splits at 10, 50 and 200 world units, fade shadows out at 80% of maximum shadow distance
     light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));
     light->SetShadowCascade(CascadeParameters(10.0f, 50.0f, 200.0f, 0.0f, 0.8f));
 
 
-    {
-        // Create a floor object, 500 x 500 world units. Adjust position so that the ground is at zero Y
-        Node* floorNode = scene_->CreateChild("Floor");
-        floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f));
-        floorNode->SetScale(Vector3(500.0f, 1.0f, 500.0f));
-        StaticModel* floorObject = floorNode->CreateComponent<StaticModel>();
-        floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
-        floorObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml"));
-
-        // Make the floor physical by adding RigidBody and CollisionShape components
-        RigidBody* body = floorNode->CreateComponent<RigidBody>();
-        // We will be spawning spherical objects in this sample. The ground also needs non-zero rolling friction so that
-        // the spheres will eventually come to rest
-        body->SetRollingFriction(0.15f);
-        CollisionShape* shape = floorNode->CreateComponent<CollisionShape>();
-        // Set a box shape of size 1 x 1 x 1 for collision. The shape will be scaled with the scene node scale, so the
-        // rendering and physics representation sizes should match (the box model is also 1 x 1 x 1.)
-        shape->SetBox(Vector3::ONE);
-    }
-
-    // Create animated models
-    for (int z = -1; z <= 1; ++z)
-    {
-        for (int x = -4; x <= 4; ++x)
-        {
-            Node* modelNode = scene_->CreateChild("Jack");
-            modelNode->SetPosition(Vector3(x * 5.0f, 0.0f, z * 5.0f));
-            modelNode->SetRotation(Quaternion(0.0f, 180.0f, 0.0f));
-            AnimatedModel* modelObject = modelNode->CreateComponent<AnimatedModel>();
-            modelObject->SetModel(cache->GetResource<Model>("Models/Jack.mdl"));
-            modelObject->SetMaterial(cache->GetResource<Material>("Materials/Jack.xml"));
-            modelObject->SetCastShadows(true);
-            // Set the model to also update when invisible to avoid staying invisible when the model should come into
-            // view, but does not as the bounding box is not updated
-            modelObject->SetUpdateInvisible(true);
-
-            // Create a rigid body and a collision shape. These will act as a trigger for transforming the
-            // model into a ragdoll when hit by a moving object
-            RigidBody* body = modelNode->CreateComponent<RigidBody>();
-            // The Trigger mode makes the rigid body only detect collisions, but impart no forces on the
-            // colliding objects
-            body->SetTrigger(true);
-            CollisionShape* shape = modelNode->CreateComponent<CollisionShape>();
-            // Create the capsule shape with an offset so that it is correctly aligned with the model, which
-            // has its origin at the feet
-            shape->SetCapsule(0.7f, 2.0f, Vector3(0.0f, 1.0f, 0.0f));
-
-            // Create a custom component that reacts to collisions and creates the ragdoll
-            modelNode->CreateComponent<CreateRagdoll>();
-        }
-    }
+    // Create a floor object, 500 x 500 world units. Adjust position so that the ground is at zero Y
+    Node* floorNode = scene_->CreateChild("Floor");
+    floorNode->SetPosition(Vector3(0.0f, -0.5f, 0.0f));
+    floorNode->SetScale(Vector3(500.0f, 1.0f, 500.0f));
+    StaticModel* floorObject = floorNode->CreateComponent<StaticModel>();
+    floorObject->SetModel(cache->GetResource<Model>("Models/Box.mdl"));
+    floorObject->SetMaterial(cache->GetResource<Material>("Materials/StoneTiled.xml"));
+
+    // Make the floor physical by adding RigidBody and CollisionShape components
+    RigidBody* body = floorNode->CreateComponent<RigidBody>();
+    // We will be spawning spherical objects in this sample. The ground also needs non-zero rolling friction so that
+    // the spheres will eventually come to rest
+    body->SetRollingFriction(0.15f);
+    CollisionShape* shape = floorNode->CreateComponent<CollisionShape>();
+    // Set a box shape of size 1 x 1 x 1 for collision. The shape will be scaled with the scene node scale, so the
+    // rendering and physics representation sizes should match (the box model is also 1 x 1 x 1.)
+    shape->SetBox(Vector3::ONE);
 
 
     // Create the camera. Limit far clip distance to match the fog. Note: now we actually create the camera node outside
     // Create the camera. Limit far clip distance to match the fog. Note: now we actually create the camera node outside
     // the scene, because we want it to be unaffected by scene load / save
     // the scene, because we want it to be unaffected by scene load / save
@@ -184,10 +198,15 @@ void Ragdolls::CreateInstructions()
 void Ragdolls::SetupViewport()
 void Ragdolls::SetupViewport()
 {
 {
     Renderer* renderer = GetSubsystem<Renderer>();
     Renderer* renderer = GetSubsystem<Renderer>();
-
-    // Set up a viewport to the Renderer subsystem so that the 3D scene can be seen
-    SharedPtr<Viewport> viewport(new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>()));
-    renderer->SetViewport(0, viewport);
+    ResourceCache* cache = GetSubsystem<ResourceCache>();
+   
+    renderer->SetNumViewports(2);  // use 2 viewports, 1 for 3d and 1 for the 2d hud
+    Viewport* viewport2_ = new Viewport(context_, hudScene, hudCamera );  // hud orthographic viewport, scene and camera
+    RenderPath *overlayRenderPath = new RenderPath(); 
+    overlayRenderPath->Load(cache->GetResource<XMLFile>("PostProcess/FrontPath.xml"));  //special renderpath that does not clear
+    viewport2_->SetRenderPath(overlayRenderPath);  // apply to hud viewport, so the background is transparent
+    renderer->SetViewport(0, new Viewport(context_, scene_, cameraNode_->GetComponent<Camera>())); // perspective viewport, scene and camera
+    renderer->SetViewport(1, viewport2_);  // and add in the HUD viewport
 }
 }
 
 
 void Ragdolls::MoveCamera(float timeStep)
 void Ragdolls::MoveCamera(float timeStep)
@@ -238,6 +257,42 @@ void Ragdolls::MoveCamera(float timeStep)
     // Toggle physics debug geometry with space
     // Toggle physics debug geometry with space
     if (input->GetKeyPress(KEY_SPACE))
     if (input->GetKeyPress(KEY_SPACE))
         drawDebug_ = !drawDebug_;
         drawDebug_ = !drawDebug_;
+        
+    if (input->GetKeyPress (KEY_U)) {
+        massCount++;
+        if ( massCount > 5 )
+            massCount = 0;
+        UpdateMassHud (massCount);
+    }
+
+    if (input->GetKeyPress (KEY_I)) {
+        speedCount++;
+        if ( speedCount> 5 )
+            speedCount = 0;
+        UpdateSpeedHud (speedCount);
+    }
+
+    if (input->GetKeyPress (KEY_O)) {
+        sizeCount++;
+        if ( sizeCount > 5 )
+            sizeCount = 0;
+        UpdateSizeHud (sizeCount);
+    }
+
+    if (input->GetKeyPress (KEY_P)) {
+        if ( bulletArc == 0.0 )
+            bulletArc = 0.25f;
+        else if ( bulletArc > 0.0 )
+            bulletArc = 0.0f;
+    }
+
+    if (input->GetKeyPress (KEY_R)) {
+        RestartJacks ();
+    }
+
+    UpdateFps ();
+    CleanUpSome ();
+
 }
 }
 
 
 void Ragdolls::SpawnObject()
 void Ragdolls::SpawnObject()
@@ -247,23 +302,23 @@ void Ragdolls::SpawnObject()
     Node* boxNode = scene_->CreateChild("Sphere");
     Node* boxNode = scene_->CreateChild("Sphere");
     boxNode->SetPosition(cameraNode_->GetPosition());
     boxNode->SetPosition(cameraNode_->GetPosition());
     boxNode->SetRotation(cameraNode_->GetRotation());
     boxNode->SetRotation(cameraNode_->GetRotation());
-    boxNode->SetScale(0.25f);
+    boxNode->SetScale(bulletSize[sizeCount]);
     StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
     StaticModel* boxObject = boxNode->CreateComponent<StaticModel>();
     boxObject->SetModel(cache->GetResource<Model>("Models/Sphere.mdl"));
     boxObject->SetModel(cache->GetResource<Model>("Models/Sphere.mdl"));
     boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneSmall.xml"));
     boxObject->SetMaterial(cache->GetResource<Material>("Materials/StoneSmall.xml"));
     boxObject->SetCastShadows(true);
     boxObject->SetCastShadows(true);
 
 
     RigidBody* body = boxNode->CreateComponent<RigidBody>();
     RigidBody* body = boxNode->CreateComponent<RigidBody>();
-    body->SetMass(1.0f);
+    body->SetMass(bulletMass[massCount]);
     body->SetRollingFriction(0.15f);
     body->SetRollingFriction(0.15f);
     CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
     CollisionShape* shape = boxNode->CreateComponent<CollisionShape>();
     shape->SetSphere(1.0f);
     shape->SetSphere(1.0f);
 
 
-    const float OBJECT_VELOCITY = 10.0f;
+    const float OBJECT_VELOCITY = bulletSpeed[speedCount];
 
 
     // Set initial velocity for the RigidBody based on camera forward vector. Add also a slight up component
     // Set initial velocity for the RigidBody based on camera forward vector. Add also a slight up component
     // to overcome gravity better
     // to overcome gravity better
-    body->SetLinearVelocity(cameraNode_->GetRotation() * Vector3(0.0f, 0.25f, 1.0f) * OBJECT_VELOCITY);
+    body->SetLinearVelocity(cameraNode_->GetRotation() * Vector3(0.0f, bulletArc, 1.0f) * OBJECT_VELOCITY);
 }
 }
 
 
 void Ragdolls::SubscribeToEvents()
 void Ragdolls::SubscribeToEvents()
@@ -293,3 +348,221 @@ void Ragdolls::HandlePostRenderUpdate(StringHash eventType, VariantMap& eventDat
     if (drawDebug_)
     if (drawDebug_)
         scene_->GetComponent<PhysicsWorld>()->DrawDebugGeometry(true);
         scene_->GetComponent<PhysicsWorld>()->DrawDebugGeometry(true);
 }
 }
+
+    // support for 2D hud and new features
+void Ragdolls::CreateHUD()
+{
+     float hscal = 0.4f;
+    //
+    // create a 2nd viewport and scene for a hud with sprites.
+    //
+    hudScene = new Scene(context_);
+    hudScene->CreateComponent<Octree>();
+    // Create camera node
+    Node* hudCam = hudScene->CreateChild("HudCamera");
+    // Set camera's position
+    hudCam->SetPosition( Vector3(0.0f, 0.0f, -10.0f));
+    hudCamera = hudCam->CreateComponent<Camera>();
+    hudCamera->SetOrthographic(true);
+    Graphics* graphics = GetSubsystem<Graphics>();
+    hudCamera->SetOrthoSize ((float)graphics->GetHeight () * 0.01f ); //PIXEL_SIZE
+
+    ResourceCache *cache = GetSubsystem<ResourceCache>();
+
+    // add a crosshair in the center of the screen
+    Sprite2D* sprite = cache->GetResource<Sprite2D>("Textures/NinjaSnowWar/Sight.png");
+    Node* targetSprite_ = hudScene->CreateChild("targetSprite");
+    targetSprite_->SetPosition2D(Vector2(0,0));
+    targetSprite_->SetScale2D(Vector2(0.75f, 0.75f));
+    StaticSprite2D* staticSprite = targetSprite_->CreateComponent<StaticSprite2D>();
+    staticSprite->SetSprite(sprite);   // Set sprite
+    staticSprite->SetBlendMode( BLEND_ALPHA ); // Set blend mode
+    staticSprite->SetAlpha(0.3f);  
+
+    // borrow the spinning coin from the 2DSprite example to show what the possibilities are
+    float halfWidth = graphics->GetWidth() * 0.5f * 0.01;
+    float halfHeight = graphics->GetHeight() * 0.5f * 0.01;
+    // Get animation set
+    AnimationSet2D* animationSet = cache->GetResource<AnimationSet2D>("Urho2D/GoldIcon.scml");
+    if (animationSet == NULL) return;
+    Node* spriteNode2 = hudScene->CreateChild("AnimatedSprite2D");
+    AnimatedSprite2D* animatedSprite = spriteNode2->CreateComponent<AnimatedSprite2D>();
+    animatedSprite->SetAnimationSet(animationSet);         // Set animation
+    animatedSprite->SetAnimation("idle", LM_DEFAULT);
+    spriteNode2->SetPosition2D( Vector2(halfWidth - 0.4f, halfHeight - 0.4f));
+
+    // (bullet) mass, speed size feature huds
+    filler.Push ( cache->GetResource<Sprite2D>("Textures/hudfill1.png") );
+    filler.Push ( cache->GetResource<Sprite2D>("Textures/hudfill2.png") );
+    filler.Push ( cache->GetResource<Sprite2D>("Textures/hudfill3.png") );
+    filler.Push ( cache->GetResource<Sprite2D>("Textures/hudfill4.png") );
+    filler.Push ( cache->GetResource<Sprite2D>("Textures/hudfill5.png") );
+    filler.Push ( cache->GetResource<Sprite2D>("Textures/hudfill6.png") );
+
+    Sprite2D* spritem = cache->GetResource<Sprite2D>("Textures/hudmass.png");
+    Node* hudm = hudScene->CreateChild("hudMass");
+    hudm->SetScale2D( Vector2(hscal,hscal));
+    hudm->SetPosition2D( Vector2( 0 - (halfWidth/3.0), halfHeight - 0.4)); 
+    StaticSprite2D* hudSpritem = hudm->CreateComponent<StaticSprite2D>();
+    hudSpritem->SetSprite(spritem);
+    hudSpritem->SetAlpha(0.9);
+    hudSpritem->SetBlendMode( BLEND_ALPHA);
+    hudSpritem->SetOrderInLayer(3); 
+    Node* hudfm = hudm->CreateChild("hudMassFill");
+    hudfm->SetScale2D( Vector2(1,1));
+    hudfm->SetPosition2D(  Vector2( 0, 0)); 
+    StaticSprite2D* hudSpritefm = hudfm->CreateComponent<StaticSprite2D>();
+    hudSpritefm->SetSprite(filler[0]);
+    hudSpritefm->SetAlpha(0.9);
+    hudSpritefm->SetBlendMode( BLEND_ALPHA);
+    hudSpritefm->SetOrderInLayer(-3); 
+
+    Sprite2D* sprites = cache->GetResource<Sprite2D>("Textures/hudspeed.png");
+    Node* huds = hudScene->CreateChild("hudSpeed");
+    huds->SetScale2D( Vector2(hscal,hscal));
+    huds->SetPosition2D(  Vector2( 0, halfHeight - 0.4)); 
+    StaticSprite2D* hudSprites = huds->CreateComponent<StaticSprite2D>();
+    hudSprites->SetSprite(sprites);
+    hudSprites->SetAlpha(0.9);
+    hudSprites->SetBlendMode( BLEND_ALPHA);
+    hudSprites->SetOrderInLayer(3); 
+    Node* hudsm = huds->CreateChild("hudSpeedFill");
+    hudsm->SetScale2D( Vector2(1,1));
+    hudsm->SetPosition2D( Vector2( 0, 0)); 
+    StaticSprite2D* hudSpritesm = hudsm->CreateComponent<StaticSprite2D>();
+    hudSpritesm->SetSprite(filler[0]);
+    hudSpritesm->SetAlpha(0.9);
+    hudSpritesm->SetBlendMode( BLEND_ALPHA);
+    hudSpritesm->SetOrderInLayer(-3); 
+
+    Sprite2D* spritez = cache->GetResource<Sprite2D>("Textures/hudsize.png");
+    Node* hudz = hudScene->CreateChild("hudSize");
+    hudz->SetScale2D( Vector2(hscal,hscal));
+    hudz->SetPosition2D(  Vector2( 0 + (halfWidth/3.0), halfHeight - 0.4)); 
+    StaticSprite2D* hudSpritez = hudz->CreateComponent<StaticSprite2D>();
+    hudSpritez->SetSprite(spritez);
+    hudSpritez->SetAlpha(0.9);
+    hudSpritez->SetBlendMode( BLEND_ALPHA);
+    hudSpritez->SetOrderInLayer(3); 
+    Node* hudzm = hudz->CreateChild("hudSizeFill");
+    hudzm->SetScale2D( Vector2(1,1));
+    hudzm->SetPosition2D( Vector2( 0, 0)); 
+    StaticSprite2D* hudSpritezm = hudzm->CreateComponent<StaticSprite2D>();
+    hudSpritezm->SetSprite(filler[0]);
+    hudSpritezm->SetAlpha(0.9);
+    hudSpritezm->SetBlendMode( BLEND_ALPHA);
+    hudSpritezm->SetOrderInLayer(-3);
+}
+
+void Ragdolls::RestartJacks()
+{
+    PODVector< Node * >allnodes;
+    scene_->GetChildren (allnodes, true);
+
+    for ( int ii=0; ii<allnodes.Size() ; ii++ ) 
+    { 
+        if ( allnodes[ii]->GetName().Compare ("Sphere") == 0) allnodes[ii]->Remove ();
+        else if ( allnodes[ii]->GetName().Compare ("Stuffing") == 0 ) allnodes[ii]->Remove ();
+        else if ( allnodes[ii]->GetName().Compare ("Jack") == 0 ) allnodes[ii]->Remove ();
+    }
+
+    ResourceCache *cache = GetSubsystem<ResourceCache>();
+    // Create animated models, you dont know ... jack
+   for (int z = -1; z <= 1; ++z)
+    {
+        for (int x = -4; x <= 4; ++x)
+        {
+            Node* modelNode = scene_->CreateChild("Jack");
+            modelNode->SetPosition(Vector3(x * 5.0f, 0.0f, z * 5.0f));
+            modelNode->SetRotation(Quaternion(0.0f, 180.0f, 0.0f));
+            AnimatedModel* modelObject = modelNode->CreateComponent<AnimatedModel>();
+            modelObject->SetModel(cache->GetResource<Model>("Models/Jack.mdl"));
+            modelObject->SetMaterial(cache->GetResource<Material>("Materials/Jack.xml"));
+            modelObject->SetCastShadows(true);
+            // Set the model to also update when invisible to avoid staying invisible when the model should come into
+            // view, but does not as the bounding box is not updated
+            modelObject->SetUpdateInvisible(true);
+
+            // Create a rigid body and a collision shape. These will act as a trigger for transforming the
+            // model into a ragdoll when hit by a moving object
+            RigidBody* body = modelNode->CreateComponent<RigidBody>();
+            // The Trigger mode makes the rigid body only detect collisions, but impart no forces on the
+            // colliding objects
+            body->SetTrigger(true);
+            CollisionShape* shape = modelNode->CreateComponent<CollisionShape>();
+            // Create the capsule shape with an offset so that it is correctly aligned with the model, which
+            // has its origin at the feet
+            shape->SetCapsule(0.7f, 2.0f, Vector3(0.0f, 1.0f, 0.0f));
+
+            // Create a custom component that reacts to collisions and creates the ragdoll
+            modelNode->CreateComponent<CreateRagdoll>();
+        }
+    }    
+}
+
+void Ragdolls::CleanUpSome()
+{
+    Node* cam = cameraNode_; // note - the camera isnt in the scene
+    if ( cam == NULL )
+        return;
+
+    PODVector< Node * >allnodes;
+    scene_->GetChildren (allnodes, true);
+    for ( int ii=0; ii<allnodes.Size() ; ii++ ) 
+    { 
+        if ( allnodes[ii]->GetName().Compare ("Sphere") == 0 ) 
+        {
+            if (( allnodes[ii]->GetWorldPosition() - cam->GetWorldPosition() ).Length() > 270.0f)
+            {
+                allnodes[ii]->Remove ();
+            }
+        }
+    }    
+}
+
+void Ragdolls::UpdateFps ()
+{
+    Engine* eng = GetSubsystem<Engine>();
+    String mystr = "FPS: " + String(eng->GetFps());
+    mystr += "\nUse WASD keys and mouse/touch to move\n";
+    mystr += "LMB to spawn physics objects\n";
+    mystr += "U=Mass, I=Speed, O=Size, R=Restart\n";
+    mystr += "Space to toggle physics debug geometry";
+    SetInstructions ( mystr );
+}
+
+void Ragdolls::UpdateMassHud ( int value )
+{
+    Node* xNode = hudScene->GetChild("hudMass", true);
+    if (xNode) {
+        Node* fillx = xNode->GetChild("hudMassFill");
+        if (fillx) {
+            StaticSprite2D* hudSprite = fillx->GetComponent<StaticSprite2D>();
+            hudSprite->SetSprite(filler[value]);
+        }
+    }
+}
+
+void Ragdolls::UpdateSpeedHud ( int value )
+{
+    Node* xNode = hudScene->GetChild("hudSpeed", true);
+    if (xNode) {
+        Node* fillx = xNode->GetChild("hudSpeedFill");
+        if (fillx) {
+            StaticSprite2D* hudSprite = fillx->GetComponent<StaticSprite2D>();
+            hudSprite->SetSprite(filler[value]);
+        }
+    }
+}
+
+void Ragdolls::UpdateSizeHud ( int value )
+{
+    Node* xNode = hudScene->GetChild("hudSize", true);
+    if (xNode) {
+        Node* fillx = xNode->GetChild("hudSizeFill");
+        if (fillx) {
+            StaticSprite2D* hudSprite = fillx->GetComponent<StaticSprite2D>();
+            hudSprite->SetSprite(filler[value]);
+        }
+    }
+}

+ 24 - 0
FeatureExamples/CPlusPlus/Source/Ragdolls.h

@@ -30,6 +30,7 @@ namespace Atomic
 
 
 class Node;
 class Node;
 class Scene;
 class Scene;
+class Sprite2D;
 
 
 }
 }
 
 
@@ -71,4 +72,27 @@ private:
 
 
     /// Flag for drawing debug geometry.
     /// Flag for drawing debug geometry.
     bool drawDebug_;
     bool drawDebug_;
+    
+    // support for 2D hud and new features
+    void CreateHUD();
+    void RestartJacks();
+    void CleanUpSome();
+    void UpdateFps ();
+    void UpdateMassHud ( int value );
+    void UpdateSpeedHud ( int value );
+    void UpdateSizeHud ( int value );
+    
+    // the  2nd scene for the hud "overlay"
+    SharedPtr<Scene> hudScene;    // the hud scene
+    SharedPtr<Camera> hudCamera;  // ortho cam for the (pixel perfect) hud
+    Vector <Sprite2D*> filler;    // for bargraph display
+
+    // more fun features...
+    PODVector <float> bulletMass;   // how heavy the bullet is
+    PODVector <float> bulletSpeed;  // how fast the bullet is
+    PODVector <float> bulletSize;   // how big the bullet is
+    int massCount, speedCount, sizeCount; // counters
+
+    float bulletArc;    // shooting inclination
+
 };
 };

+ 14 - 8
FeatureExamples/CPlusPlus/Source/Sample.cpp

@@ -33,7 +33,6 @@
 #include <Atomic/UI/UIFontDescription.h>
 #include <Atomic/UI/UIFontDescription.h>
 #include <Atomic/UI/UIView.h>
 #include <Atomic/UI/UIView.h>
 #include <Atomic/UI/UILayout.h>
 #include <Atomic/UI/UILayout.h>
-#include <Atomic/UI/UIEditField.h>
 
 
 #include "Sample.h"
 #include "Sample.h"
 #include "SampleSelector.h"
 #include "SampleSelector.h"
@@ -95,6 +94,8 @@ void Sample::InitMouseMode(MouseMode mode)
 
 
 void Sample::BackToSelector()
 void Sample::BackToSelector()
 {
 {
+    GetSubsystem<Input>()->SetMouseVisible(true);
+ 
     UnsubscribeFromAllEvents();
     UnsubscribeFromAllEvents();
     Renderer* renderer = GetSubsystem<Renderer>();
     Renderer* renderer = GetSubsystem<Renderer>();
     for (unsigned i = 0; i <  renderer->GetNumViewports(); i++)
     for (unsigned i = 0; i <  renderer->GetNumViewports(); i++)
@@ -220,18 +221,23 @@ void Sample::SimpleCreateInstructions(const String& text)
 
 
     msgText += "Press ESC for menu";
     msgText += "Press ESC for menu";
 
 
-    UIEditField* label = new UIEditField(context_);
-    label->SetFontDescription(fontDesc);
-    label->SetReadOnly(true);
-    label->SetMultiline(true);
-    label->SetAdaptToContentSize(true);
-    label->SetText(msgText);
-    layout->AddChild(label);
+    label_ = new UIEditField(context_);
+    label_->SetFontDescription(fontDesc);
+    label_->SetReadOnly(true);
+    label_->SetMultiline(true);
+    label_->SetAdaptToContentSize(true);
+    label_->SetText(msgText);
+    layout->AddChild(label_);
 
 
     FeatureExamples::GetUIView()->AddChild(layout);
     FeatureExamples::GetUIView()->AddChild(layout);
 
 
 }
 }
 
 
+void Sample::SetInstructions(const String& text)
+{
+    if ( label_ != NULL )
+        label_->SetText(text);
+}
 
 
 // If the user clicks the canvas, attempt to switch to relative mouse mode on web platform
 // If the user clicks the canvas, attempt to switch to relative mouse mode on web platform
 void Sample::HandleMouseModeRequest(StringHash eventType, VariantMap& eventData)
 void Sample::HandleMouseModeRequest(StringHash eventType, VariantMap& eventData)

+ 7 - 1
FeatureExamples/CPlusPlus/Source/Sample.h

@@ -26,12 +26,14 @@
 #include <Atomic/Core/Object.h>
 #include <Atomic/Core/Object.h>
 #include <Atomic/Core/StringUtils.h>
 #include <Atomic/Core/StringUtils.h>
 #include <Atomic/Input/Input.h>
 #include <Atomic/Input/Input.h>
+#include <Atomic/UI/UIEditField.h>
 
 
 namespace Atomic
 namespace Atomic
 {
 {
 
 
 class Node;
 class Node;
 class Scene;
 class Scene;
+class UIEditField;
 
 
 }
 }
 
 
@@ -74,6 +76,8 @@ protected:
 
 
     void SimpleCreateInstructions(const String& text = String::EMPTY);
     void SimpleCreateInstructions(const String& text = String::EMPTY);
 
 
+    void SetInstructions(const String& text = String::EMPTY);
+
     void BackToSelector();
     void BackToSelector();
 
 
     /// Logo sprite.
     /// Logo sprite.
@@ -90,7 +94,9 @@ protected:
     bool touchEnabled_;
     bool touchEnabled_;
     /// Mouse mode option to use in the sample.
     /// Mouse mode option to use in the sample.
     MouseMode useMouseMode_;
     MouseMode useMouseMode_;
-
+    /// for making the instructions writable
+    SharedPtr<UIEditField> label_;
+    
 private:
 private:
 
 
     /// Create logo.
     /// Create logo.

+ 4 - 0
FeatureExamples/CSharp/Resources/Components/Ragdoll.cs

@@ -187,6 +187,10 @@ namespace FeatureExamples
                 xNode.SetRotation( new Quaternion((float)rand.Next(0,360), 0, (float)rand.Next(0,360)));
                 xNode.SetRotation( new Quaternion((float)rand.Next(0,360), 0, (float)rand.Next(0,360)));
                 xNode.SetScale(0.3f);
                 xNode.SetScale(0.3f);
 
 
+                ParticleEmitter pEmitter = xNode.CreateComponent<ParticleEmitter>();
+................pEmitter.SetEffect(cache.GetResource<ParticleEffect>("Particle/Fire.xml"));
+................pEmitter.SetEnabled(true);  // sparkle donuts.
+
                 //create obj
                 //create obj
                 StaticModel boxObject = xNode.CreateComponent<StaticModel>();
                 StaticModel boxObject = xNode.CreateComponent<StaticModel>();
                 boxObject.Model = cache.Get<Model>("Models/Torus.mdl");
                 boxObject.Model = cache.Get<Model>("Models/Torus.mdl");