Example #1
0
void AIFly::Update()
{
  Assert(m_npc);
  Assert(m_target);

  m_npc->SetAnim("fly"); // why not just in OnActivated?? TODO

  // Accelerate towards point above player's head
  Vec3f a = (m_target->GetPos() + Vec3f(0, 50.0f, 0)) - m_npc->GetPos();
  a.Normalise();
  a *= 50.0f; // TODO CONFIG
  m_npc->SetAcc(a);

  // Cap speed 
  a = m_npc->GetVel();
  float speedSq = a.SqLen();
  const float MAX_SPEED = 50.0f; // TODO CONFIG
  if (speedSq > MAX_SPEED * MAX_SPEED)
  {
    a.Normalise();
    a *= MAX_SPEED;
    m_npc->SetVel(a);
  }

  float degs = RadToDeg(atan2(a.x, a.z));
  m_npc->SetDir(degs);
}
Example #2
0
void Ve1ObjectChar::MoveTo(const Vec3f& newpos)
{
  m_newPos = newpos;
  m_isMoving = true;

  Vec3f dir = GetPos() - newpos;
  float sqLen = dir.SqLen();
  // TODO Check if distance is greater than last time - if so, we have missed the target!

  static const float STOP_DIST = ROConfig()->GetFloat("stop-dist", 10.0f);
  if (sqLen < STOP_DIST)
  {
    SetVel(Vec3f(0, 0, 0));
    m_isMoving = false; // Not sure why this wasn't here
  }
  // TODO enable this when we are reliably resetting sqLenLastTime, otherwise sometimes characters won't move
  /*
  else if (sqLen > sqLenLastTime)
  {
    SetVel(Vec3f(0, 0, 0));
    m_isMoving = false; // Not sure why this wasn't here
  }
  */
  else
  {
    dir.Normalise();
    SetVel(-dir * SPEED);

    // Work out direction to face
    SetDir(RadToDeg(atan2((double)m_vel.x, (double)m_vel.z)));
  }
  sqLenLastTime = sqLen;
}
Example #3
0
void MakeNormal(const Vec3f& v0,
                const Vec3f& v1,
                const Vec3f& v2,
                Vec3f* pResult)
{
  AMJU_CALL_STACK;

  Vec3f cp = CrossProduct(v1 - v0, v2 - v0);
  cp.Normalise();
  *pResult = cp;
}
Example #4
0
// https://en.wikibooks.org/wiki/OpenGL_Programming/Modern_OpenGL_Tutorial_Arcball
void Camera::RotateArcball(float ax, float ay, float bx, float by)
{
  Vec3f a, b;

  Vec2f from(ax, ay);
  Vec2f to(bx, by);

  float az = from.x * from.x + from.y * from.y;
  float bz = to.x * to.x + to.y * to.y;

  // keep the controls stable by rejecting very small movements.
  if(fabsf(az - bz) < 1e-5f)
    return;

  if(az < 1.0f)
  {
    a = Vec3f(from.x, from.y, sqrt(1.0f - az));
  }
  else
  {
    a = Vec3f(from.x, from.y, 0.0f);
    a.Normalise();
  }

  if(bz < 1.0f)
  {
    b = Vec3f(to.x, to.y, sqrt(1.0f - bz));
  }
  else
  {
    b = Vec3f(to.x, to.y, 0.0f);
    b.Normalise();
  }

  float angle = acosf(RDCMIN(1.0f, a.Dot(b)));

  Vec3f axis = a.Cross(b);
  axis.Normalise();

  dirty = true;

  Quatf delta = Quatf::AxisAngle(axis, angle);
  arcrot = arcrot * delta;
}
Example #5
0
void AIChasePet::Update()
{
  AI::Update();
  Assert(m_npc);
  // Head towards target
  Vec3f aim = m_target->GetPos();
  Vec3f vel = aim - m_npc->GetPos();

  static const float MAX_DIST = ROConfig()->GetFloat("dino-chase-dist"); 
  static const float MAX_DIST_SQ = MAX_DIST * MAX_DIST;

  float sqlen = vel.SqLen();
  if (sqlen < 1.0f)
  {
std::cout << "AI chase: " << Describe(m_npc) << " has reached target " <<
  Describe(m_target) << "!\n";

    m_npc->DecideAI();
  }
  else if (sqlen < MAX_DIST_SQ) 
  {
    vel.Normalise();

    static const float SPEED = ROConfig()->GetFloat("dino-chase-speed"); 
    vel *= SPEED;
    Vec3f v = m_npc->GetVel();
    v.x = vel.x;
    v.z = vel.z;
    m_npc->SetVel(v);
    float degs = RadToDeg(atan2(vel.x, vel.z)); 

    m_npc->SetDir(degs);
    m_npc->SetIsControlled(true); 
    m_npc->SetAnim("run");
  }
  else
  {
#ifdef _DEBUG
    std::cout << m_npc->GetTypeName() << " giving up chase\n";
#endif
    m_npc->SetAI(AIIdle::NAME);
  }
}
Example #6
0
void Spring::Update()
{
  // Vector between spring ends
  Vec3f v = m_particles[0]->GetPos() - m_particles[1]->GetPos();
  Vec3f newVec = v;
  // Force along this line proportional to distance
  // == Hooke's Law, springs
  float len = sqrt(v.SqLen());
  if (len < 0.00001f) // TODO
  {
    return; // zero length spring, so do nothing
  }

  //len = std::min(m_maxLength, len);
  v.Normalise();

  // Force at spring ends is proportional to squash/stretch distance
  Vec3f forceAtEnd = v * ((len - m_naturalLength) * m_k);
  m_particles[0]->AddForce(-forceAtEnd);
  m_particles[1]->AddForce(forceAtEnd);

  // If max spring length exceeded, pull ends together
  if (len > m_maxLength)
  {
std::cout << "Spring exceeds max length (" << m_maxLength << ")\n";

    // TODO Take masses into account!
    float dist = (len - m_maxLength) * 0.5f; // move each end this dist
    Vec3f moveVec = v * dist;
    m_particles[0]->Move(-moveVec);
    m_particles[1]->Move(moveVec);
  }
  else if (len < m_minLength)
  {
std::cout << "Spring under min length (" << m_minLength << ")\n";
    // TODO Take masses into account!

    float dist = (len - m_minLength) * 0.5f; // move each end this dist
    Vec3f moveVec = v * dist;
    m_particles[0]->Move(-moveVec);
    m_particles[1]->Move(moveVec);
  }

  /*
  // Set box centre and extents
  Vec3f centre = (m_particles[0]->GetPos() + m_particles[1]->GetPos()) * 0.5f;
  m_box.SetCentre(centre);
  m_box.SetExtents(Vec3f(len * 0.5f, 0.2f, 1.0f));

  // Align box with line seg connecting end points
  Vec3f xAxis = v;
  // Create a zAxis perpendicular to xAxis
  Vec3f up(0, 1.0f, 0);
  // Choose new up vector if xAxis is vertical!
  const float VERTICAL = 0.9f;
  float dot = DotProduct(xAxis, up);
  if (fabs(dot) > VERTICAL)
  {
    up = Vec3f(1.0f, 0, 0); // TODO may face other dir
  }
  Vec3f zAxis = CrossProduct(xAxis, up);
  Vec3f yAxis = CrossProduct(xAxis, zAxis);
  m_box.SetAxes(xAxis, yAxis);
  */

/*
  // Twist spring
  m_oldVec.Normalise();
  newVec.Normalise();
  float theta = acos(DotProduct(m_oldVec, newVec));
  if (fabs(theta) > 0.001f)
  {
    Vec3f axis = CrossProduct(m_oldVec, newVec);
    axis.Normalise();
    Quaternion q(axis, theta);
    q = GetQuat() * q;
    SetQuat(q);
  }
*/
  m_oldVec = newVec;
}
void ThirdPersonCameraBase::Update()
{
  Camera::Update();

  float dt = Engine::Instance()->GetDeltaTime();

  // New for POOL 
  // Zoom in/out, (not using mouse)
  if (m_zoomVel != 0)
  {
#ifdef ZOOM_DEBUG
std::cout << "ZOOM: old zoom vel: " << m_zoomVel << "\n";
#endif

    // Decelerate to zero
    static const float ZOOM_DECEL = Engine::Instance()->GetConfigFloat(
      "pool_cam_zoom_decel");
    Assert(ZOOM_DECEL > 0); 
    if (m_zoomVel > 0)
    {
      m_zoomVel -= ZOOM_DECEL * dt;
      if (m_zoomVel < 0)
      {
        m_zoomVel = 0;
      }
    }
    else if (m_zoomVel < 0)
    {
      m_zoomVel += ZOOM_DECEL * dt;
      if (m_zoomVel > 0)
      {
        m_zoomVel = 0;
      }
    }

#ifdef ZOOM_DEBUG
std::cout << "ZOOM: new zoom vel: " << m_zoomVel << "\n";
#endif

    // Move away or towards the target, at the zoom vel.
    Vec3f v = m_orientation.GetVertex() - m_lookAtPos;
    v.Normalise();
    v *= m_zoomVel * dt;
#ifdef ZOOM_DEBUG
std::cout << "ZOOM add vec: " << ToString(v).c_str() << "\n";
#endif

    Vec3f v0 = m_orientation.GetVertex(); 
    v0 += v;
    m_orientation.SetVertex(v0);
  }

  static float prevRot = m_yRotVel;
  if (m_yRotVel != 0)
  {
    static const float MAX_Y_ROT_VEL = 360.0f;
    //static const float MIN_Y_ROT_VEL = 10.0f;
    m_yRotVel += dt * m_yRotAcc;
    if (fabs(m_yRotVel) > MAX_Y_ROT_VEL)
    {
      m_yRotVel = MAX_Y_ROT_VEL;
      m_yRotAcc = 0;
    }
    if (Sign(m_yRotVel) != Sign(prevRot) && prevRot != 0)
    {
      m_yRotVel = 0;
      m_yRotAcc = 0;
    }
    float yRot = m_yRotVel * dt;
    RotateCameraHoriz(yRot);
  }
  prevRot = m_yRotVel;

  static float prevUp = m_upVel;
  if (m_upVel != 0)
  {
//std::cout << "Up vel: " << m_upVel << " acc: " << m_upAcc;

    float y = GetOrientation()->GetY();
    m_upVel += dt * m_upAcc;
    if (Sign(m_upVel) != Sign(prevUp) && prevUp != 0)
    {
      m_upVel = 0;
      m_upAcc = 0;
    }
    y += m_upVel * dt;

//std::cout << "  new Up vel: " << m_upVel << "\n";

    Orientation o = *(GetOrientation());
    // Never exceed the absolute max camera height.
    if (y > m_maxAbsHeight)
    {
      y = m_maxAbsHeight;
    }
    o.SetY(y);
    SetOrientation(o);
  }
  prevUp = m_upVel;
}