Code Search for Developers
 
 
  

kcamera.cpp from Spatial Knowledge Experiments at Krugle


Show kcamera.cpp syntax highlighted

/*
    Copyright (C) 2003, 2004, 2005 by Luca Cappa
    Written by Luca Cappa groton@users.sourceforge.net
  
    This library is free software; you can redistribute it and/or
    modify it under the terms of the GNU Library General Public
    License as published by the Free Software Foundation; either
    version 2 of the License, or (at your option) any later version.
  
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    Library General Public License for more details.
  
    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"

#include "csutil/sysfunc.h"

#include "cstool/csview.h"
#include "cstool/initapp.h"
#include "cstool/collider.h"

#include "csutil/cmdhelp.h"

#include "ivideo/graph3d.h"
#include "ivideo/graph2d.h"
#include "ivideo/natwin.h"
#include "ivideo/txtmgr.h"
#include "ivideo/fontserv.h"

#include "imesh/sprite2d.h"
#include "imesh/ball.h"
#include "imesh/object.h"

#include "iengine/mesh.h"
#include "iengine/engine.h"
#include "iengine/sector.h"
#include "iengine/camera.h"
#include "iengine/movable.h"
#include "iengine/material.h"
#include "iengine/mesh.h"

#include "imesh/thing.h"


#include "igraphic/imageio.h"

#include "csutil/cscolor.h"
#include "csutil/cmdhelp.h"
#include "csutil/cspmeter.h"
#include "csutil/csstring.h"
#include "csutil/scfstr.h"

#include "iutil/vfs.h"
#include "iutil/eventq.h"
#include "iutil/event.h"
#include "iutil/eventh.h"
#include "iutil/objreg.h"
#include "iutil/csinput.h"
#include "iutil/virtclk.h"
#include "iutil/plugin.h"
#include "iutil/string.h"
#include "iutil/comp.h"

#include "iengine/sector.h"
#include "iengine/engine.h"
#include "iengine/camera.h"
#include "iengine/light.h"
#include "iengine/texture.h"
#include "iengine/mesh.h"
#include "iengine/movable.h"
#include "iengine/material.h"

#include "imesh/thing.h"
#include "imesh/object.h"
#include "imesh/sprite3d.h"

#include "ivideo/graph3d.h"
#include "ivideo/graph2d.h"
#include "ivideo/natwin.h"
#include "ivideo/txtmgr.h"
#include "ivideo/texture.h"
#include "ivideo/material.h"
#include "ivideo/fontserv.h"

#include "igraphic/imageio.h"

#include "imap/loader.h"

#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "ivaria/conout.h"
#include "ivaria/reporter.h"
#include "ivaria/stdrep.h"
#include "ivaria/collider.h"

#include "csgeom/quaterni.h"
#include "csgeom/transfrm.h"
#include "csgeom/math3d_d.h"
#include "csgeom/math3d.h"

#include "igeom/polymesh.h"

#include "imap/loader.h"

#include "iaws/aws.h"
#include "iaws/awscnvs.h"


#include "ske.h"
#include "kutil.h"
#include "kplayer.h"
#include "movement3d.h"

#include "kcamera.h"


KCamera::KCamera () :
  m_pos (0.0f, 1.5f, 0.0f), //?? HARDCODED VALUE!
  m_distance (5.0f),
  mCameraVel (0, 0, 0), m_zoomingIn (false), m_zoomingOut (false),
  mCameraAcc (0, 0, 0)
{
  mEngine = CS_QUERY_REGISTRY (g_objReg, iEngine);
  mG3d = CS_QUERY_REGISTRY (g_objReg, iGraphics3D);

  m_view.AttachNew (new csView (mEngine, mG3d));

  SetPanoramic (false);

  mCamera = m_view->GetCamera ();
  m_kbd = CS_QUERY_REGISTRY (g_objReg, iKeyboardDriver);
  m_joy = CS_QUERY_REGISTRY (g_objReg, iJoystickDriver);

  m_friction = 1.8f;
  m_accK = 6.7f;
  m_xAngle = 0;
  m_yAngle = 0.457f;
  m_zAngle = 0;

  m_zoomingIn = false;
  m_zoomingOut = false;
  m_rotateX = 0;
  m_rotateY = 0;
  m_rotateZ = 0;
}

KCamera::~KCamera ()
{
  //??
}



void KCamera::setViewport (csVector2 const& pPoint, csVector2 const& pSize)
{
  m_view->SetRectangle (pPoint.x, pPoint.y, pSize.x, pSize.y);
  mCamera = m_view->GetCamera ();
}

void KCamera::ZoomIn (bool p_val)
{
  m_zoomingIn = p_val;
}

void KCamera::ZoomOut (bool p_val)
{
  m_zoomingOut = p_val;
}


void KCamera::SetSector (iSector* p_sector)
{
  mCamera->SetSector (p_sector);
}

void KCamera::SetPositionRotation (const csVector3& p_vector,
  const csMatrix3& p_matrix)
{
  csOrthoTransform& l_oT = mCamera->GetTransform ();
  l_oT.SetOrigin (p_vector);
  l_oT.SetT2O (p_matrix);
  mCamera->SetTransform (l_oT);//?? is this needed???
}


//"state" is "THIRD" or "FIRST" person view, "POINTINGBEFOREWALKING",
// or "EDITING";
void KCamera::SetState (int p_state)
{
  m_state = p_state;
}

int KCamera::GetState ()
{
  return m_state;
}

int KCamera::SwitchPersonState ()
{
  switch (m_state)
  {
  case FIRST:
    m_state = THIRD;
    break;
  case THIRD:
    m_state = FIRST;
    break;
  }//switch
  return m_state;
}


iCamera* KCamera::GetCamera ()
{
  return mCamera;
}

void KCamera::MoveForward (bool p_val)
{
  if (p_val)
    mCameraAcc.z = +m_accK;
  else
    mCameraAcc.z = 0;
}

void KCamera::MoveBack (bool p_val)
{
  if (p_val)
    mCameraAcc.z = -m_accK;
  else
    mCameraAcc.z = 0;
}

void KCamera::MoveLeft (bool p_val)
{
  if (p_val)
    mCameraAcc.x = -m_accK;
  else
    mCameraAcc.x = 0;
}

void KCamera::MoveRight (bool p_val)
{
  if (p_val)
    mCameraAcc.x = +m_accK;
  else
    mCameraAcc.x = 0;
}

/**
Clamp an radiant angle.
*/
static inline void AddAndClampAngle (float& p_value, float p_addedValue)
{
  if (p_addedValue > 0)
  {
    p_value += p_addedValue;
    if (p_value > K_2PI)
        p_value = p_value - K_2PI;
  }//if
  else
  {
    p_value += p_addedValue;
    if (p_value < 0.0f)
        p_value = K_2PI + p_value;
  }//else
}


//
//0 no rotation, +1 clockwise, -1 counterclockwise.
void KCamera::RotateX (int p_val)
{
  m_rotateX = p_val;
}

//
//0 no rotation, +1 clockwise, -1 counterclockwise.
void KCamera::RotateY (int p_val)
{
  m_rotateY = p_val;
}

//
//0 no rotation, +1 clockwise, -1 counterclockwise.
void KCamera::RotateZ (int p_val)
{
  m_rotateZ = p_val;
}

void KCamera::SetDistance (float p_distance)
{
  m_distance = p_distance;
  if(m_distance <= 0.2f)//?? hardcoded value.
    m_distance = 0.2f;
}

void KCamera::SetAngles (float p_xAngle, float p_yAngle, float p_zAngle)
{
  m_xAngle = p_xAngle;
  m_yAngle = p_yAngle;
  m_zAngle = p_zAngle;
}

void KCamera::SetTracked (KPlayer* p_player)
{
  m_tracked = p_player;
}

void KCamera::SetFOVAngle (float p_angle, int p_width)
{
  mCamera->SetFOVAngle (p_angle, p_width);
}

void KCamera::Draw ()
{
  m_view->Draw ();
}


//
//p_timePassed is in msecs.
void KCamera::HandleRotation (float p_timePassed)
{
  static const float s_constant = (1.0f / 10000.0f) * (0.03f * 7.f);
  //
  //handle the 3 angles here.
  float l_incrX = 0.0f, l_incrY = 0.0f, l_incrZ = 0.0f;
  if (m_rotateX == 1)
    l_incrX = (p_timePassed * s_constant);
  if (m_rotateX == -1)
    l_incrX = -(p_timePassed * s_constant);
  AddAndClampAngle (m_xAngle, l_incrX);

  if (m_rotateY == 1)
    l_incrY = (p_timePassed * s_constant);
  if (m_rotateY == -1)
    l_incrY = -(p_timePassed * s_constant);
  AddAndClampAngle (m_yAngle, l_incrY);
  
  if (m_rotateZ == 1)
    l_incrZ = (p_timePassed * s_constant);
  if (m_rotateZ == -1)
    l_incrZ = -(p_timePassed * s_constant);
  AddAndClampAngle (m_zAngle, l_incrZ);
}

void KCamera::UpdatePosition (float p_msecs)
{
  float l_seconds = p_msecs / 1000.0f;
  
  //
  //handle the distance here.
  float l_acc = 0; //acceleration
  if (m_zoomingIn)
    l_acc = -7.8f;  
  else if (m_zoomingOut)
    l_acc = 7.8f;
  SetDistance (m_distance += m_mov1d.GetMovement (l_seconds, l_acc, 1.5f));
  
  switch (m_state)
  {
    case EDITING:
    {
      HandleRotation (p_msecs);

      csVector3 l_movement (0, 0, 0);
      
      KQuaternion l_q2;
      l_q2.SetWithEuler (csVector3 (RAD2DEG (m_xAngle), 
        RAD2DEG (m_yAngle), RAD2DEG (m_zAngle)));//this call requires DEGREE angles.
      l_q2.Normalize();
      
      csVector3 l_zAxis (0, 0, 1.0f);
      csVector3 l_aheadDirection = l_q2.Rotate (l_zAxis);
      l_aheadDirection.y = 0;//Project it to the XZ plane
      l_aheadDirection.Normalize ();
      l_aheadDirection *= mCameraAcc.z;

      csVector3 l_xAxis (1.0f, 0, 0);
      csVector3 l_rightDirection = l_q2.Rotate (l_xAxis);
      l_rightDirection.y = 0;//Project it to the XZ plane
      l_rightDirection.Normalize ();
      l_rightDirection *= mCameraAcc.x;

      csVector3 l_accWorldSpace = l_aheadDirection + l_rightDirection;
      
      float l_accNorm = l_accWorldSpace.Norm ();      
      if (ABS (l_accNorm) < SMALL_EPSILON)//??? WTF
        l_accWorldSpace = 0;
      else
        l_accWorldSpace = l_accWorldSpace.Unit () * l_accNorm;

      mCameraVel.x = mCameraVel.x + l_accWorldSpace.x * l_seconds;//v = v0 + a*t
      mCameraVel.z = mCameraVel.z + l_accWorldSpace.z * l_seconds;//v = v0 + a*t        
      
      if (mCameraVel.Norm() > SMALL_EPSILON)
      {
        csVector3 l_frictionVector = mCameraVel * m_friction * l_seconds;
        if (l_frictionVector.Norm () > mCameraVel.Norm())
          mCameraVel.Set (0,0,0);
        else
          mCameraVel -= l_frictionVector;
      }//if
      else
        mCameraVel.Set (0,0,0);
      
      l_movement.x = mCameraVel.x * l_seconds + 0.5f * 
        l_accWorldSpace.x * l_seconds * l_seconds;//x = v0*t +0.5*a*t*t
      l_movement.z = mCameraVel.z * l_seconds + 0.5f * 
        l_accWorldSpace.z * l_seconds * l_seconds;//x = v0*t +0.5*a*t*t
    
      m_pos += l_movement;

      csVector3 l_v (0, 0, 1.0f);//default viewing is along Z axis.
      csVector3 l_up (0, 1.0f, 0);
      KQuaternion l_q;
      l_q.SetWithEuler (csVector3 (RAD2DEG (m_xAngle), RAD2DEG (m_yAngle), 
        RAD2DEG (m_zAngle)));//this call requires DEGREE angles.
      l_q.Normalize();
      csVector3 l_vRotated = l_q.Rotate (l_v);
      csVector3 l_upRotated = l_q.Rotate (l_up);


      /*printf ("%7.3f,%7.3f,%7.3f     ", l_vRotated.x, l_vRotated.y, l_vRotated.z);
      csVector3 k = l_tr.This2Other (l_v);
      printf ("%7.3f,%7.3f,%7.3f\n", k.x, k.y, k.z);//???*/

      //set the new position and orientation of the camera.
      csVector3 camera_pos (m_pos - m_distance * l_vRotated);
      
      csVector3 look_at_pos (m_pos);
      csOrthoTransform l_oT;
      l_oT.LookAt (look_at_pos - camera_pos, l_upRotated);

      SetPositionRotation (camera_pos, l_oT.GetT2O ());

      //set the FOV on the camera.
      SetFOVAngle (m_tracked->m_FOVAngle, m_tracked->m_FOVWidth);
    }
    break;
    case THIRD:
    { 
      HandleRotation (p_msecs);

      //Set the new position and orientation of the camera.
      //We get the position from the tracked object.
      csVector3 l_pos = m_tracked->GetPosition ();
      l_pos.y += m_tracked->GetHeight ();
      
      KQuaternion l_camQ;
      l_camQ.SetWithEuler (csVector3 (RAD2DEG (m_xAngle), RAD2DEG (m_yAngle), 
        RAD2DEG (m_zAngle)));
      csVector3 l_v = csVector3 (0, 0, 1.0f);//default viewing is along X axis.
      csVector3 l_up = csVector3 (0, 1.0f, 0);
      csVector3 l_vRotated = l_camQ.Rotate (l_v);
      csVector3 l_upRotated = l_camQ.Rotate (l_up);

      csVector3 camera_pos (l_pos - m_distance * l_vRotated);      
      csVector3 look_at_pos (l_pos);
      
      csOrthoTransform l_oT;
      l_oT.LookAt (look_at_pos - camera_pos, l_upRotated);

      SetPositionRotation (camera_pos, l_oT.GetT2O ());




      //set the FOV on the camera.
      //?? use the values used for the players configuration!
      SetFOVAngle (m_tracked->m_FOVAngle, m_tracked->m_FOVWidth);
      
    }//case
    break;
    case FIRST:
    {
      csVector3 l_pos = m_tracked->GetPosition ();
      l_pos.y += m_tracked->GetHeight ();
      csVector3 l_for(0,0,1), l_up(0,1,0);
      l_up = m_tracked->GetHeadAngles ().Rotate (l_up);
      l_up = m_tracked->GetBodyAngle ().Rotate (l_up);
      l_for = m_tracked->GetHeadAngles ().Rotate (l_for);
      l_for = m_tracked->GetBodyAngle ().Rotate (l_for);
      
      csMatrix3 m; 
      csVector3 v(0,0,0);
      csReversibleTransform l_rT (m, v);
      l_rT.LookAt (l_for, l_up);
      SetPositionRotation (l_pos, l_rT.GetT2O ());

      
      //set the FOV on the camera.
      SetFOVAngle (m_tracked->m_FOVAngle, m_tracked->m_FOVWidth);
    }//case
    break;
    case POINTINGBEFOREWALKING:
    {
      //set the new position and orientation of the camera.
      //we get the position from the tracked object.
      csVector3 l_pos = m_tracked->GetPosition ();
      l_pos.y += m_tracked->GetHeight ();
      
      //
      //Set the new position and orientation of the camera.
      
      csVector3 camera_pos (l_pos);      
      
      csMatrix3 l_headM (m_tracked->GetHeadAngles ().GetMatrix ());
      csMatrix3 l_bodyM (m_tracked->GetBodyAngle ().GetMatrix ());
      SetPositionRotation (l_pos, l_bodyM * l_headM);

      //set the FOV on the camera.
      SetFOVAngle (m_tracked->m_FOVAngle, m_tracked->m_FOVWidth);
      break;
    }//case
    default:
    {
      CS_ASSERT(false);
    }//case
  }//switch

}


bool KCamera::IsPanoramic () const
{
  return mPanoramic;
}

void KCamera::SetPanoramic (bool pPan)
  {
    mPanoramic = pPan;

    if (mPanoramic)
    {
      setViewport (csVector2 (0, mG3d->GetDriver2D ()->GetHeight () / 4), 
        csVector2 (mG3d->GetDriver2D ()->GetWidth (), mG3d->GetDriver2D ()->GetHeight () / 2));
    }//if
    else
    {
      setViewport (csVector2 (0, 0), csVector2
        (mG3d->GetDriver2D ()->GetWidth (), mG3d->GetDriver2D ()->GetHeight ()));
    }//else
  }




See more files for this project here

Spatial Knowledge Experiments

A simulation of 3D virtual worlds for psychological experiments

Project homepage: http://sourceforge.net/projects/ske
Programming language(s): C,C++,Perl
License: other

  isense/
  joystick/
  Jamfile
  KImageCardinalDirection.h
  SKE.cpp
  SKE.h
  eulerangles.c
  eulerangles.h
  ikdraggable.cpp
  ikdraggable.h
  ikdraghandler.h
  ikmission.h
  ikxmlreader.h
  ikxmlwriter.h
  kappstate.cpp
  kappstate.h
  kbasedraggable.cpp
  kbasedraggable.h
  kbasedraghandler.cpp
  kbasedraghandler.h
  kblock.cpp
  kblock.h
  kblockId.h
  kblockid.cpp
  kcamera.cpp
  kcamera.h
  kcollision.cpp
  kcommandprocessor.cpp
  kcommandprocessor.h
  kconstant.cpp
  kconstant.h
  kcursor3d.cpp
  kcursor3d.h
  kdata.cpp
  kdata.h
  kdatalist.cpp
  kdatalist.h
  kdragmanager.cpp
  kdragmanager.h
  keventhandlermanager.cpp
  keventhandlermanager.h
  kflags.cpp
  kflags.h
  kimagecardinaldirection.cpp
  kkeys.cpp
  kkeys.h
  kkeystate.cpp
  kkeystate.h
  klandmark.cpp
  klandmark.h
  klandmarklist.cpp
  klandmarklist.h
  klight.cpp
  klight.h
  klightlist.cpp
  klightlist.h
  kmap.cpp
  kmap.h
  kmission.cpp
  kmission.h
  kmissiontype.cpp
  kmissiontype.h
  kmode.cpp
  kmode.h
  kmousemanager.cpp
  kmousemanager.h
  kobject3d.cpp
  kobject3d.h
  korientation.cpp
  korientation.h
  kpath.cpp
  kpath.h
  kpathfollower.cpp
  kpathfollower.h
  kplayer.cpp
  kplayer.h
  kposition.cpp
  kposition.h
  kquaternion.cpp
  kquaternion.h
  ksaveddatamanager.cpp
  ksaveddatamanager.h
  ksegment3.h
  ksign.cpp
  ksign.h
  ksprite3d.cpp
  ksprite3d.h
  ksprite3dlist.cpp
  ksprite3dlist.h
  kterrain.cpp
  kterrain.h
  kthing.cpp
  kthing.h
  kutil.cpp
  kutil.h
  kwireframe.cpp
  kwireframe.h
  kxmlhelper.h
  movement1d.h
  movement3d.h
  quattypes.h