Advertisement
Guest User

Untitled

a guest
Apr 14th, 2016
194
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 5.55 KB | None | 0 0
  1.     #include "Precompiled.h"
  2.  
  3.     #include "../Physics/JiggleBone.h"
  4.  
  5.     #include "../Core/Context.h"
  6.     #include "../Graphics/DebugRenderer.h"
  7.     #include "../Scene/Node.h"
  8.  
  9.     /*
  10.     Port of http://wiki.unity3d.com/index.php?title=JiggleBone
  11.     to Urho3D
  12.     */
  13.  
  14.     namespace Urho3D
  15.     {
  16.  
  17.     extern const char* PHYSICS_CATEGORY;
  18.  
  19.     JiggleBone::JiggleBone(Context* context) :
  20.        LogicComponent(context)
  21.     {
  22.        SetUpdateEventMask(USE_POSTUPDATE);
  23.        // Bone settings
  24.        boneAxis_ = Vector3(0, 0, 1);
  25.        targetDistance_ = 2.0f;
  26.  
  27.        // Dynamics settings
  28.        stiffness_ = 0.1f;
  29.        mass_ = 0.9f;
  30.        damping_ = 0.75f;
  31.        gravity_ = 0.75f;
  32.  
  33.        // Squash and stretch variables
  34.        squashAndStretch_ = true;
  35.        sideStretch_ = 0.15f;
  36.        frontStretch_ = 0.2f;
  37.     }
  38.  
  39.     JiggleBone::~JiggleBone()
  40.     {
  41.  
  42.     }
  43.  
  44.     void JiggleBone::RegisterObject(Context* context)
  45.     {
  46.        context->RegisterFactory<JiggleBone>(PHYSICS_CATEGORY);
  47.  
  48.        COPY_BASE_ATTRIBUTES(LogicComponent);
  49.        ACCESSOR_ATTRIBUTE("Is Enabled", IsEnabled, SetEnabled, bool, true, AM_DEFAULT);
  50.        ATTRIBUTE("Bone Axis", Vector3, boneAxis_, Vector3(0, 0, 1), AM_DEFAULT);
  51.  
  52.        ATTRIBUTE("Stiffness", float, stiffness_, 0.1f, AM_DEFAULT);
  53.        ATTRIBUTE("Mass", float, mass_, 0.9f, AM_DEFAULT);
  54.        ATTRIBUTE("Damping", float, damping_, 0.75f, AM_DEFAULT);
  55.        ATTRIBUTE("Gravity", float, gravity_, 0.75f, AM_DEFAULT);
  56.  
  57.        ATTRIBUTE("Allow Stretch", bool, squashAndStretch_, true, AM_DEFAULT);
  58.        ATTRIBUTE("Side Stretch", float, sideStretch_, 0.15f, AM_DEFAULT);
  59.        ATTRIBUTE("Front Stretch", float, frontStretch_, 0.15f, AM_DEFAULT);
  60.     }
  61.  
  62.     void JiggleBone::DelayedStart()
  63.     {
  64.        targetPos_ = GetNode()->GetWorldPosition() + GetNode()->GetWorldDirection() * targetDistance_;
  65.        dynamicPos_ = targetPos_;
  66.     }
  67.  
  68.     void JiggleBone::PostUpdate(float timeStep)
  69.     {
  70.        if (!IsEnabledEffective())
  71.           return;
  72.        // Update forwardVector and upVector
  73.        Vector3 forwardVector = GetNode()->GetWorldDirection() * targetDistance_;
  74.        Vector3 upVector = GetNode()->GetWorldUp();
  75.  
  76.        // Calculate target position
  77.        Vector3 targetPos = GetNode()->GetWorldPosition() + forwardVector;
  78.  
  79.        // Calculate force, acceleration, and velocity per X, Y and Z
  80.        force_.x_ = (targetPos.x_ - dynamicPos_.x_) * stiffness_;
  81.        acc_.x_ = force_.x_ / mass_;
  82.        vel_.x_ += acc_.x_ * (1 - damping_);
  83.  
  84.        force_.y_ = (targetPos.y_ - dynamicPos_.y_) * stiffness_;
  85.        force_.y_ -= gravity_ / 10; // Add some gravity
  86.        acc_.y_ = force_.y_ / mass_;
  87.        vel_.y_ += acc_.y_ * (1 - damping_);
  88.  
  89.        force_.z_ = (targetPos.z_ - dynamicPos_.z_) * stiffness_;
  90.        acc_.z_ = force_.z_ / mass_;
  91.        vel_.z_ += acc_.z_ * (1 - damping_);
  92.  
  93.        // Update dynamic postion
  94.        dynamicPos_ += vel_ + force_;
  95.  
  96.        // Set bone rotation to look at dynamicPos
  97.        GetNode()->LookAt(dynamicPos_, upVector);
  98.  
  99.        // ==================================================
  100.        // Squash and Stretch section
  101.        // ==================================================
  102.        if (squashAndStretch_){
  103.           // Create a vector from target position to dynamic position
  104.           // We will measure the magnitude of the vector to determine
  105.           // how much squash and stretch we will apply
  106.           Vector3 dynamicVec = dynamicPos_ - targetPos;
  107.  
  108.           // Get the magnitude of the vector
  109.           float stretchMag = dynamicVec.Length();
  110.  
  111.           // Here we determine the amount of squash and stretch based on stretchMag
  112.           // and the direction the Bone Axis is pointed in. Ideally there should be
  113.           // a vector with two values at 0 and one at 1. Like Vector3(0,0,1)
  114.           // for the 0 values, we assume those are the sides, and 1 is the direction
  115.           // the bone is facing
  116.           float xStretch;
  117.           if (boneAxis_.x_ == 0)
  118.              xStretch = 1 + (-stretchMag * sideStretch_);
  119.           else
  120.              xStretch = 1 + (stretchMag * frontStretch_);
  121.  
  122.           float yStretch;
  123.           if (boneAxis_.y_ == 0)
  124.              yStretch = 1 + (-stretchMag * sideStretch_);
  125.           else
  126.              yStretch = 1 + (stretchMag * frontStretch_);
  127.  
  128.           float zStretch;
  129.           if (boneAxis_.z_ == 0)
  130.              zStretch = 1 + (-stretchMag * sideStretch_);
  131.           else
  132.              zStretch = 1 + (stretchMag * frontStretch_);
  133.  
  134.           // Set the bone scale
  135.           GetNode()->SetScale(Vector3(xStretch, yStretch, zStretch));
  136.        }
  137.     }
  138.  
  139.     void JiggleBone::DrawDebugGeometry(DebugRenderer* debug, bool depthTest)
  140.     {
  141.        if (IsEnabledEffective())
  142.        {
  143.           // draw forward line
  144.           debug->AddLine(GetNode()->GetWorldPosition(),
  145.              GetNode()->GetWorldPosition() + GetNode()->GetWorldDirection() * targetDistance_,
  146.              Color(0, 0, 1), false);
  147.           // draw the up vector
  148.           debug->AddLine(GetNode()->GetWorldPosition(),
  149.              GetNode()->GetWorldPosition() + GetNode()->GetWorldUp() * (targetDistance_ * 0.5f),
  150.              Color(0, 1, 0), false);
  151.           // draw the target position
  152.           debug->AddLine(targetPos_,
  153.              Vector3::UP * (targetDistance_ * 0.2f),
  154.              Color(1, 1, 0), false);
  155.           // draw the dynamic position
  156.           debug->AddLine(dynamicPos_,
  157.              Vector3::UP * (targetDistance_ * 0.2f),
  158.              Color(1, 0, 0), false);
  159.        }
  160.     }
  161.  
  162.     }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement