csMatrix3 operator/ (const csMatrix3& m, float f)
{
  float inv_f = 1 / f;
  return csMatrix3 (m.m11*inv_f, m.m12*inv_f, m.m13*inv_f,
                    m.m21*inv_f, m.m22*inv_f, m.m23*inv_f,
                    m.m31*inv_f, m.m32*inv_f, m.m33*inv_f);
}
예제 #2
0
void csCameraBase::Correct (int n)
{
  if (n == 0) return;

  csVector3 w1, w2, w3;
  float *vals[5];

  w3 = m_t2o.Col3 ();
  vals[0] = &w3.x;
  vals[1] = &w3.y;
  vals[2] = &w3.z;
  vals[4] = 0;
  Correct (n, vals);  /* perform the snap-to operation on the forward vector */

  /* Maybe w3 should be normalized.  Only necessary if there is
   significant roundoff error: */

  //  w3 = csVector3::unit(w3);

  /* perhaps a snap-to should be performed on one of the other vectors as well */
  w1 = m_t2o.Col2 ();
  w2 = csVector3::Unit (w3 % w1);
  w1 = w2 % w3;

  SetT2O (csMatrix3 (w1.x, w2.x, w3.x, w1.y, w2.y, w3.y, w1.z, w2.z, w3.z));
}
예제 #3
0
파일: ragdoll.cpp 프로젝트: garinh/cs
  void RagdollAnimNode::BlendState (csSkeletalState2* state, float baseWeight)
  {
    if (!isActive)
      return;

    //printf ("RagdollAnimNode::BlendState\n");

    // TODO: use baseWeight
    for (csHash<Bone, BoneID>::GlobalIterator it = bones.GetIterator ();
	 it.HasNext(); )
    {
      Bone bone = it.Next ();
      csOrthoTransform bodyTransform = bone.rigidBody->GetTransform ();

      // TODO: test for deactivation of rigid body
      BoneID parentBoneID = skeleton->GetFactory ()->GetBoneParent (bone.boneID);

      // if this bone is the root of the skeleton
      // TODO: valid also for root of dynamic node?
      if (parentBoneID == InvalidBoneID)
      {
	csQuaternion boneRotation;
	csVector3 boneOffset;
	skeleton->GetFactory ()->GetTransformBoneSpace (bone.boneID, boneRotation,
							boneOffset);
	csOrthoTransform boneTransform (csMatrix3 (boneRotation), boneOffset);
	csOrthoTransform newTransform = boneTransform.GetInverse () * bodyTransform;

	iMovable* movable = sceneNode->GetMovable ();
	movable->SetTransform (newTransform);
	movable->UpdateMove ();

	continue;
      }
      
      // if this bone is inside the ragdoll chain
      if (bones.Contains (parentBoneID))
      {
	Bone nullBone;
	csOrthoTransform parentTransform = bones.Get (parentBoneID, nullBone)
	  .rigidBody->GetTransform ();
	csReversibleTransform relativeTransform =
	  bodyTransform * parentTransform.GetInverse ();

	state->SetBoneUsed (bone.boneID);
	state->GetVector (bone.boneID) = relativeTransform.GetOrigin ();
	csQuaternion quaternion;
	quaternion.SetMatrix (relativeTransform.GetT2O ());
	state->GetQuaternion (bone.boneID) = quaternion;

	continue;
      }

      // else this bone is the root of the ragdoll chain, but not of the skeleton
      else
      {
	// TODO: use kinematic object if not the root of the animesh
      }
    }
  }
예제 #4
0
void csReversibleTransform::RotateThis (const csVector3 &v, float angle)
{
  csVector3 u = v;
  float ca, sa, omcaux, omcauy, omcauz, uxsa, uysa, uzsa;
  u = csVector3::Unit (u);
  ca = (float)cos (angle);
  sa = (float)sin (angle);
  omcaux = (1 - ca) * u.x;
  omcauy = (1 - ca) * u.y;
  omcauz = (1 - ca) * u.z;
  uxsa = u.x * sa;
  uysa = u.y * sa;
  uzsa = u.z * sa;

  SetT2O (
    GetT2O () * csMatrix3 (
        u.x * omcaux + ca,
        u.y * omcaux - uzsa,
        u.z * omcaux + uysa,
        u.x * omcauy + uzsa,
        u.y * omcauy + ca,
        u.z * omcauy - uxsa,
        u.x * omcauz - uysa,
        u.y * omcauz + uxsa,
        u.z * omcauz + ca));
}
예제 #5
0
void SelfShadowDemo::Frame ()
{
  csTicks elapsed_time = vc->GetElapsedTicks ();
  float speed = (elapsed_time / 1000.0) * (0.03 * 20);
  float rotateFactor = speed;

  // Translucent objects become dynamic by being rotated
  if (rotateGrass)
  {
    // Search for mesh named 'Hair'
    csRef<iMeshWrapper> objectfact =
      engine->FindMeshObject ("Hair");

    if (objectfact)
    {
      objectfact->GetMovable()->SetTransform(
        objectfact->GetMovable()->GetTransform() *
        csMatrix3(cos(rotateFactor), 0, sin(rotateFactor),
        0, 1, 0, -sin(rotateFactor), 0, cos(rotateFactor)) );
      objectfact->GetMovable()->UpdateMove();
    }
  }

  // Default behavior from DemoApplication
  DemoApplication::Frame ();
}
예제 #6
0
//---------------------------------------------------------------------------
csTransform csTransform::GetReflect (const csPlane3 &pl)
{
  // Suppose that n is the plane normal in the direction of th reflection.
  // Suppose that u is the unit vector in the direction of the reflection
  // normal.  For any vector v, the component of v in the direction of
  // u is equal to (v * u) * u.  Thus, if v is reflected across a plane
  // through the origin with the given normal, the resulting vector is
  //  v' = v - 2 * [ (v * u) * u ] = v - 2 [ (v * n) * n ] / (n * n)
  //
  // x = <1,0,0>  =>  x' = <1,0,0> - 2 ( n.x * n ) / (n*n)
  // y = <0,1,0>  =>  y' = <0,1,0> - 2 ( n.y * n ) / (n*n)
  // z = <0,0,1>  =>  z' = <0,0,1> - 2 ( n.z * n ) / (n*n)
  //
  // 3x3 transformation matrix = [x' y' z']
  float i_normsq = 1 / (pl.norm * pl.norm);
  csVector3 xvec = (-2 * pl.norm.x * i_normsq) * pl.norm;
  csVector3 yvec = (-2 * pl.norm.y * i_normsq) * pl.norm;
  csVector3 zvec = (-2 * pl.norm.z * i_normsq) * pl.norm;
  xvec.x += 1;
  yvec.y += 1;
  zvec.z += 1;

  return csTransform (
      csMatrix3 (
        xvec.x,
        yvec.x,
        zvec.x,
        xvec.y,
        yvec.y,
        zvec.y,
        xvec.z,
        yvec.z,
        zvec.z),
      /* neworig = */(-2 * pl.DD * i_normsq) * pl.norm);
}
예제 #7
0
void psLinearMovement::SetPosition (const csVector3& pos, float yrot,
	const iSector* sector)
{
    if (!sector)
    {
        StackTrace("Setting position without sector");
    }

//    Debug4(LOG_CELPERSIST,0,"DEBUG: psLinearMovement::SetPosition %s current transform: %s scale %f \n", mesh->QueryObject()->GetName(), mesh->GetMovable()->GetTransform().Description().GetData(),scale);

    // Position and Sector
    mesh->GetMovable ()->SetPosition ((iSector *)sector,pos);

    // at first loading scale may not be yet set
    if (scale>0) {
        // Rotation and scale
        csMatrix3 rotMatrix = (csMatrix3) csYRotMatrix3 (yrot);
        csMatrix3 scaleMatrix = csMatrix3 (1/scale,0,0, 0,1/scale,0, 0,0,1/scale);
        mesh->GetMovable ()->GetTransform ().SetO2T (scaleMatrix*rotMatrix);
    } else  {
        // Rotation only
        csMatrix3 rotMatrix = (csMatrix3) csYRotMatrix3 (yrot);
        mesh->GetMovable ()->GetTransform ().SetO2T (rotMatrix);
    }

    mesh->GetMovable ()->UpdateMove ();
}
예제 #8
0
파일: frankie.cpp 프로젝트: crystalspace/CS
void FrankieScene::ResetScene ()
{
  // Reset the position of the animesh
  csRef<iMeshObject> animeshObject = scfQueryInterface<iMeshObject> (animesh);
  animeshObject->GetMeshWrapper ()->QuerySceneNode ()->GetMovable ()->SetTransform
    (csOrthoTransform (csMatrix3 (), csVector3 (0.0f)));
  animeshObject->GetMeshWrapper ()->QuerySceneNode ()->GetMovable ()->UpdateMove ();

  if (hairTest->physicsEnabled)
  {
    // Set the ragdoll state of the 'body' and 'tail' chains as kinematic
    ragdollNode->SetBodyChainState (bodyChain, CS::Animation::STATE_KINEMATIC);
    ragdollNode->SetBodyChainState (tailChain, CS::Animation::STATE_KINEMATIC);
    ragdollNode->SetPlaybackPosition(0);

    // Update the display of the dynamics debugger
    if (hairTest->dynamicsDebugMode == DYNDEBUG_COLLIDER
	|| hairTest->dynamicsDebugMode == DYNDEBUG_MIXED)
      hairTest->dynamicsDebugger->UpdateDisplay ();
  }

  // Reset morphing
  animesh->SetMorphTargetWeight (animeshFactory->FindMorphTarget ("smile.B"), 1.0f);
  animesh->SetMorphTargetWeight (animeshFactory->FindMorphTarget ("eyebrows_down.B"), 1.0f);
  animesh->SetMorphTargetWeight (animeshFactory->FindMorphTarget ("wings_in"), 1.0f);
  animesh->SetMorphTargetWeight (animeshFactory->FindMorphTarget ("eyelids_closed"), 0.0f);

  if (furMesh)
    furMesh->ResetMesh();
}
예제 #9
0
파일: krystal.cpp 프로젝트: crystalspace/CS
void KrystalScene::ResetScene ()
{
  if (hairTest->physicsEnabled)
  {
    // Reset the position of the animesh
    csRef<iMeshObject> animeshObject = scfQueryInterface<iMeshObject> (animesh);

    animeshObject->GetMeshWrapper ()->QuerySceneNode ()->GetMovable ()->SetTransform
      (csOrthoTransform (csMatrix3 (), csVector3 (0.0f)));
    animeshObject->GetMeshWrapper ()->QuerySceneNode ()->GetMovable ()->UpdateMove ();

    // Set the ragdoll state of the 'body' chain as kinematic
    ragdollNode->SetBodyChainState (bodyChain, CS::Animation::STATE_KINEMATIC);
    ragdollNode->SetPlaybackPosition(0);
    // Update the display of the dynamics debugger
    if (hairTest->dynamicsDebugMode == DYNDEBUG_COLLIDER
      || hairTest->dynamicsDebugMode == DYNDEBUG_MIXED)
      hairTest->dynamicsDebugger->UpdateDisplay ();

    // There are still big unlinerarities in the transition of Krystal's animations.
    // These gaps create a bad behavior of the simulation of the hairs, this is
    // better with lower step parameters.
    hairTest->bulletDynamicSystem->SetStepParameters (0.016667f, 1, 10);

    if (furMesh)
      furMesh->ResetMesh ();
  }

  isDead = false;
}
예제 #10
0
파일: krystal.cpp 프로젝트: crystalspace/CS
csVector3 KrystalScene::GetCameraTarget ()
{
  // The target of the camera is the hips of Krystal when we are far away,
  // and the head when we are close
  csQuaternion boneRotation;
  csVector3 boneOffset;
  csRef<iMeshObject> animeshObject = scfQueryInterface<iMeshObject> (animesh);

  // Compute the position of the hips
  animesh->GetSkeleton ()->GetTransformAbsSpace
    (animeshFactory->GetSkeletonFactory ()->FindBone ("Hips"), boneRotation, boneOffset);
  csOrthoTransform hipsTransform (csMatrix3 (boneRotation.GetConjugate ()),
    boneOffset);
  csVector3 hipsPosition = (hipsTransform
    * animeshObject->GetMeshWrapper ()->QuerySceneNode ()
    ->GetMovable ()->GetTransform ()).GetOrigin ();

  // Compute the position of the head
  animesh->GetSkeleton ()->GetTransformAbsSpace
    (animeshFactory->GetSkeletonFactory ()->FindBone ("Head"), boneRotation, boneOffset);
  csOrthoTransform headTransform (csMatrix3 (boneRotation.GetConjugate ()),
    boneOffset);
  csVector3 headPosition = (headTransform
    * animeshObject->GetMeshWrapper ()->QuerySceneNode ()
    ->GetMovable ()->GetTransform ()).GetOrigin ();

  // Compute the distance between the camera and the head
  float distance = (hairTest->view->GetCamera ()->GetTransform ().GetOrigin ()
    - headPosition).Norm ();

  // Compute the camera target
  csVector3 cameraTarget;
  if (distance >= CAMERA_HIPS_DISTANCE)
    cameraTarget = hipsPosition;

  else if (distance <= CAMERA_MINIMUM_DISTANCE)
    cameraTarget = headPosition;

  else
    cameraTarget = hipsPosition + (headPosition - hipsPosition)
    * (CAMERA_HIPS_DISTANCE - distance)
    / (CAMERA_HIPS_DISTANCE - CAMERA_MINIMUM_DISTANCE);

  return cameraTarget;
}
예제 #11
0
void csQuaternion::SetMatrix (const csMatrix3& matrix)
{
  // Ken Shoemake's article in 1987 SIGGRAPH course notes
 
  csMatrix3 mat = csMatrix3( matrix.m11, matrix.m21, matrix.m31,
                          matrix.m12, matrix.m22, matrix.m32,
                          matrix.m13, matrix.m23, matrix.m33);
 
  const float trace = mat.m11 + mat.m22 + mat.m33;
 
  if (trace >= 0.0f)
  {
    // Quick-route
    float s = sqrtf (trace + 1.0f);
    w = 0.5f * s;
    s = 0.5f / s;
    v.x = (mat.m32 - mat.m23) * s;
    v.y = (mat.m13 - mat.m31) * s;
    v.z = (mat.m21 - mat.m12) * s;
  }
  else
  {
    //Check biggest diagonal elmenet
    if (mat.m11 > mat.m22 && mat.m11 > mat.m33)
    {
      //X biggest
      float s = sqrtf (1.0f + mat.m11 - mat.m22 - mat.m33);
      v.x = 0.5f * s;
      s = 0.5f / s;
      w = (mat.m32 - mat.m23) * s;
      v.y = (mat.m12 + mat.m21) * s;
      v.z = (mat.m31 + mat.m13) * s;
    }
    else if (mat.m22 > mat.m33)
    {
      //Y biggest
      float s = sqrtf (1.0f + mat.m22 - mat.m11 - mat.m33);
      v.y = 0.5f * s;
      s = 0.5f / s;
      w = (mat.m13 - mat.m31) * s;
      v.x = (mat.m12 + mat.m21) * s;
      v.z = (mat.m23 + mat.m32) * s;
    }
    else
    {
      //Z biggest
      float s = sqrtf (1.0f + mat.m33 - mat.m11 - mat.m22);
      v.z = 0.5f * s;
      s = 0.5f / s;
      w = (mat.m21 - mat.m12) * s;
      v.x = (mat.m31 + mat.m13) * s;
      v.y = (mat.m23 + mat.m32) * s;
    }
  }
}
예제 #12
0
bool csReversibleTransform::LookAt (
  const csVector3 &v,
  const csVector3 &upNeg)
{
  if (!LookAtZUpY (v, upNeg))
  {
    SetT2O (csMatrix3 ());
    return false;
  }
  return true;
}
csMatrix3 operator* (const csMatrix3& m1, const csMatrix3& m2)
{
  return csMatrix3 (
   m1.m11*m2.m11 + m1.m12*m2.m21 + m1.m13*m2.m31,
   m1.m11*m2.m12 + m1.m12*m2.m22 + m1.m13*m2.m32,
   m1.m11*m2.m13 + m1.m12*m2.m23 + m1.m13*m2.m33,
   m1.m21*m2.m11 + m1.m22*m2.m21 + m1.m23*m2.m31,
   m1.m21*m2.m12 + m1.m22*m2.m22 + m1.m23*m2.m32,
   m1.m21*m2.m13 + m1.m22*m2.m23 + m1.m23*m2.m33,
   m1.m31*m2.m11 + m1.m32*m2.m21 + m1.m33*m2.m31,
   m1.m31*m2.m12 + m1.m32*m2.m22 + m1.m33*m2.m32,
   m1.m31*m2.m13 + m1.m32*m2.m23 + m1.m33*m2.m33 );
}
예제 #14
0
csVector3 psGameObject::DisplaceTargetPos(const iSector* mySector, const csVector3& myPos, const iSector* targetSector, const csVector3& targetPos , float offset, float angle)
{
    csVector3 displace;

    // This prevents NPCs from wanting to occupy the same physical space as something else
    if(mySector == targetSector)
    {
        csVector3 displacement = targetPos - myPos;
        displacement.y = 0;
        
        csTransform transform;
        displacement = csMatrix3 (0.0,1.0,0.0,angle)*displacement;

        displace = offset*displacement.Unit();
    }
    return displace;
}
예제 #15
0
void FrankieScene::ResetScene ()
{
  // Reset the position of the animesh
  csRef<iMeshObject> animeshObject = scfQueryInterface<iMeshObject> (animesh);
  animeshObject->GetMeshWrapper ()->QuerySceneNode ()->GetMovable ()->SetTransform
    (csOrthoTransform (csMatrix3 (), csVector3 (0.0f)));
  animeshObject->GetMeshWrapper ()->QuerySceneNode ()->GetMovable ()->UpdateMove ();

  frankieDead = false;

  if (avatarTest->physicsEnabled)
  {
    // Set the ragdoll state of the 'body' and 'tail' chains as kinematic
    ragdollNode->SetBodyChainState (bodyChain, CS::Animation::STATE_KINEMATIC);
    ragdollNode->SetBodyChainState (tailChain, CS::Animation::STATE_KINEMATIC);

    // Update the display of the dynamics debugger
    if (avatarTest->dynamicsDebugMode == DYNDEBUG_COLLIDER
	|| avatarTest->dynamicsDebugMode == DYNDEBUG_MIXED)
      avatarTest->dynamicsDebugger->UpdateDisplay ();
  }

  // Reset the 'LookAt' animation node
  alwaysRotate = false;
  lookAtNodeFactory->SetAlwaysRotate (alwaysRotate);
  targetMode = LOOKAT_CAMERA;
  lookAtNode->SetTarget (avatarTest->view->GetCamera(), csVector3 (0.0f));
  rotationSpeed = ROTATION_NORMAL;
  lookAtNodeFactory->SetMaximumSpeed (5.0f);
  lookAtNode->Play ();

  // Reset the 'speed' animation node
  currentSpeed = 0;
  speedNode->SetSpeed (((float) currentSpeed) / 10.0f);

  // Reset morphing
  smileWeight = 1.0f;
  animesh->SetMorphTargetWeight (animeshFactory->FindMorphTarget ("smile.B"), 1.0f);
  animesh->SetMorphTargetWeight (animeshFactory->FindMorphTarget ("eyebrows_down.B"), 1.0f);
  animesh->SetMorphTargetWeight (animeshFactory->FindMorphTarget ("wings_in"), 1.0f);
  animesh->SetMorphTargetWeight (animeshFactory->FindMorphTarget ("eyelids_closed"), 0.0f);
}
예제 #16
0
파일: softanim.cpp 프로젝트: yushiming/CS
  void SoftBodyControl::SetSoftBody (CS::Physics::Bullet::iSoftBody* body, bool doubleSided)
  {
    CS_ASSERT (body);

    // Reset the data
    softBody = body;
    this->doubleSided = doubleSided;
    vertices.SetSize (doubleSided ? softBody->GetVertexCount () * 2 : softBody->GetVertexCount ());
    normals.SetSize (doubleSided ? softBody->GetVertexCount () * 2 : softBody->GetVertexCount ());
    anchors.DeleteAll ();

    // Initialize the vertices and mesh position
    meshPosition.Set (0.0f);
    for (size_t i = 0; i < softBody->GetVertexCount (); i++)
      meshPosition += softBody->GetVertexPosition (i);
    meshPosition /= softBody->GetVertexCount ();
    mesh->GetMeshWrapper ()->GetMovable ()->SetTransform (csMatrix3 ());

    Update (0, 0, 0);
  }
예제 #17
0
csMatrix3 csQuaternion::GetMatrix () const
{
  const float x2 = v.x*2.0f;
  const float y2 = v.y*2.0f;
  const float z2 = v.z*2.0f;

  const float xx2 = v.x*x2;
  const float xy2 = v.y*x2;
  const float xz2 = v.z*x2;
  const float xw2 = w*x2;

  const float yy2 = v.y*y2;
  const float yz2 = v.z*y2;
  const float yw2 = w*y2;

  const float zz2 = v.z*z2;
  const float zw2 = w*z2;

  
  return csMatrix3 (
    1.0f - (yy2+zz2), xy2 - zw2,        xz2 + yw2,
    xy2 + zw2,        1.0f - (xx2+zz2), yz2 - xw2,
    xz2 - yw2,        yz2 + xw2,        1.0f - (xx2+yy2));
}
예제 #18
0
int psLinearMovement::MoveSprite (float delta)
{
  int ret = PS_MOVE_SUCCEED;

  csReversibleTransform fulltransf = mesh->GetMovable ()
  	->GetFullTransform ();
  //  const csMatrix3& transf = fulltransf.GetT2O ();

  // Calculate the total velocity (body and world) in OBJECT space.
  csVector3 bodyVel (fulltransf.Other2ThisRelative (velWorld) + velBody);

  float local_max_interval =
     csMin(csMin((bodyVel.y==0.0f) ? MAX_CD_INTERVAL : ABS (intervalSize.y/bodyVel.y),
               (bodyVel.x==0.0f) ? MAX_CD_INTERVAL : ABS (intervalSize.x/bodyVel.x)
             ),(bodyVel.z==0.0f) ? MAX_CD_INTERVAL : ABS (intervalSize.z/bodyVel.z)
        );

  // Err on the side of safety (95% error margin)
  local_max_interval *= 0.95f;

  //printf("local_max_interval=%f, bodyVel is %1.2f, %1.2f, %1.2f\n",local_max_interval, bodyVel.x, bodyVel.y, bodyVel.z);
  //printf("velWorld is %1.2f, %1.2f, %1.2f\n", velWorld.x, velWorld.y, velWorld.z);
  //printf("velBody is %1.2f, %1.2f, %1.2f\n", velBody.x, velBody.y, velBody.z);

  // Sanity check on time interval here.  Something is messing it up. -KWF
  //local_max_interval = csMax(local_max_interval, 0.1F);

  if (colldet)
  {
    while (delta > local_max_interval)
    {

        csVector3 oldpos(mesh->GetMovable ()->GetFullTransform ().GetOrigin());
        
        // Perform brutal optimisation here for falling with no obstacles
        if(velWorld.y < -20.0f && mesh->GetMovable()->GetSectors()->GetCount() > 0)
        {
            csVector3 worldVel (fulltransf.This2OtherRelative (velBody) + velWorld);
            bool hit = false;
            
            // We check for other meshes at the start and end of the box with radius * 2 to be on the safe side
            {
                csRef<iMeshWrapperIterator> objectIter = engine->GetNearbyMeshes(mesh->GetMovable()->GetSectors()->Get(0), 
                                                                             oldpos + boundingBox.GetCenter(), boundingBox.GetSize().Norm() * 2);
                if(objectIter->HasNext())
                    hit = true;
            }
            if(!hit)
            {
                csRef<iMeshWrapperIterator> objectIter = engine->GetNearbyMeshes(mesh->GetMovable()->GetSectors()->Get(0), 
                                                                                 oldpos + worldVel * delta + boundingBox.GetCenter(), boundingBox.GetSize().Norm() * 2);
                if(objectIter->HasNext())
                    hit = true;
            }
            if(!hit)
            {
                csOrthoTransform transform_newpos(csMatrix3(), oldpos + worldVel * delta);
                csBox3 fullBox(fulltransf.This2OtherRelative(boundingBox.Min()), fulltransf.This2OtherRelative(boundingBox.Max()));
                csBox3 newBox( transform_newpos.This2OtherRelative(boundingBox.Min()), transform_newpos.This2OtherRelative(boundingBox.Max()));

                
                fullBox.AddBoundingBox(newBox);
                csRef<iMeshWrapperIterator> objectIter = engine->GetNearbyMeshes(mesh->GetMovable()->GetSectors()->Get(0), fullBox);
                if(objectIter->HasNext())
                    hit = true;
            }
            if(!hit)
                local_max_interval = delta;
        }

        ret = MoveV (local_max_interval);

        csVector3 displacement(fulltransf.GetOrigin() - oldpos);
        
        displacement = fulltransf.Other2ThisRelative(displacement);
        
        // Check the invariants still hold otherwise we may jump walls
        if(!(fabs(displacement.x) <= intervalSize.x))
        {
        	printf("X (%g) out of bounds when performing CD > %g!\n", fabs(displacement.x), intervalSize.x);
        	CS_ASSERT(false);
        }
        if(!(fabs(displacement.z) <= intervalSize.z))
        {
            printf("Z (%g) out of bounds when performing CD > %g!\n", fabs(displacement.y), intervalSize.y);
            CS_ASSERT(false);
        }
        if(!(fabs(displacement.y) <= intervalSize.y))
        {
            printf("Y (%g) out of bounds when performing CD > %g!\n", fabs(displacement.z), intervalSize.z);
            CS_ASSERT(false);
        }

        RotateV (local_max_interval);
        
        // We must update the transform after every rotation!
        fulltransf = mesh->GetMovable ()->GetFullTransform ();

      if (ret == PS_MOVE_FAIL)
          return ret;

      // The velocity may have changed by now
      bodyVel = fulltransf.Other2ThisRelative(velWorld) + velBody;

      delta -= local_max_interval;
      local_max_interval = csMin(csMin((bodyVel.y==0.0f)
      	? MAX_CD_INTERVAL
      	: ABS (intervalSize.y/bodyVel.y), (bodyVel.x==0.0f)
      	? MAX_CD_INTERVAL
      	: ABS (intervalSize.x/bodyVel.x)), (bodyVel.z==0.0f)
      	? MAX_CD_INTERVAL
      	: ABS (intervalSize.z/bodyVel.z));
      // Err on the side of safety (95% error margin)
      local_max_interval *= 0.95f;

      // Sanity check on time interval here.  Something is messing it up. -KWF
      // local_max_interval = csMax(local_max_interval, 0.1F);
    }
  }

  if (!colldet || delta)
  {
    ret = MoveV (delta);
    RotateV(delta);
  }

  return ret;
}
예제 #19
0
csMatrix3 psEffectObj::BuildRotMatrix(const csVector3 &up) const
{
    csVector3 forward = csVector3(0, 0, 1);
    csVector3 right = up % forward;
    return csMatrix3(right.x, right.y, right.z, up.x, up.y, up.z, forward.x, forward.y, forward.z);
}
예제 #20
0
bool SelfShadowDemo::OnKeyboard (iEvent &ev)
{
  // Default behavior from csDemoApplication
  DemoApplication::OnKeyboard (ev);
  // First get elapsed time from the virtual clock.
  csTicks elapsed_time = vc->GetElapsedTicks ();
  float speed = (elapsed_time / 1000.0) * (0.03 * 20);

  // Only moves the first light
  csRef<iLight> light = engine->GetSectors()->Get(0)->GetLights()->Get(0);

  float moveFactor = 0;
  csMatrix3 rotateMatrix = csMatrix3();
  float rotateFactor = speed;

  csKeyEventType eventtype = csKeyEventHelper::GetEventType(&ev);
  if (eventtype == csKeyEventTypeDown)
  {
    if (csKeyEventHelper::GetCookedCode (&ev) == 'w')
    {
      rotateMatrix = csMatrix3(1, 0, 0, 0, cos(rotateFactor), 
        -sin(rotateFactor), 0, sin(rotateFactor), cos(rotateFactor));
    }
    else if (csKeyEventHelper::GetCookedCode (&ev) == 's')
    {
      rotateMatrix = csMatrix3(1, 0, 0, 0, cos(rotateFactor), 
        sin(rotateFactor), 0, -sin(rotateFactor), cos(rotateFactor));
    }
    else if (csKeyEventHelper::GetCookedCode (&ev) == 'a')
    {
      rotateMatrix = csMatrix3(cos(rotateFactor), -sin(rotateFactor), 
        0, sin(rotateFactor), cos(rotateFactor), 0, 0, 0, 1);
    }
    else if (csKeyEventHelper::GetCookedCode (&ev) == 'd')
    {
      rotateMatrix = csMatrix3(cos(rotateFactor), sin(rotateFactor), 
        0, -sin(rotateFactor), cos(rotateFactor), 0, 0, 0, 1);
    }
    // Recomputed the split ratio
    else if (csKeyEventHelper::GetCookedCode (&ev) == 'r')
    {
      rm_dbg->DebugCommand("reset_split_ratio");
      return true;
    }
    // Switch between showing the render textures
    else if (csKeyEventHelper::GetCookedCode (&ev) == 't')
    {
      rm_dbg->DebugCommand("show_render_textures");
      return true;
    }
    // Load next scene
    else if (csKeyEventHelper::GetCookedCode (&ev) == 'n')
    {
      sceneNumber = ( sceneNumber + 1 ) % numberOfScenes;
      CreateScene();
      return true;
    }
    // Load previous scene
    else if (csKeyEventHelper::GetCookedCode (&ev) == 'p')
    {
      sceneNumber = ( sceneNumber - 1 );
      if (sceneNumber < 0)
        sceneNumber += numberOfScenes;
      CreateScene();
      return true;
    }
    // Start dynamic scene
    else if (csKeyEventHelper::GetCookedCode (&ev) == 'g')
    {
      rotateGrass = !rotateGrass;
      return true;
    }

    // Rotate light
    light->GetMovable()->Transform(rotateMatrix);

    csVector3 oldDirection = light->GetMovable()->GetPosition();
    float oldLength = oldDirection.Norm();
    oldDirection.Normalize();

    csVector3 newDirection = (rotateMatrix * oldDirection);
    float newLength = oldLength + moveFactor;
    newDirection.Normalize();

    csVector3 position = newDirection * newLength;
    light->GetMovable()->SetPosition(position);
    light->GetMovable()->UpdateMove();

    return true;
  }

  return false;
}
예제 #21
0
파일: ragdoll.cpp 프로젝트: garinh/cs
  bool RagdollAnimNode::CreateRigidBodyNode (iBodyChainNode* node,
					     iRigidBody* parentBody)
  {
    iBodyBone* bodyBone = node->GetBodyBone ();

    // check availability of collider
    if (!bodyBone->GetBoneColliderCount ())
    {
      factory->manager->Report (CS_REPORTER_SEVERITY_ERROR,
			"No colliders for bone %i while creating ragdoll chain.\n",
			bodyBone->GetAnimeshBone ());
      return false;
    }

    // check availability of joint
    if (parentBody && !bodyBone->GetBoneJoint ())
    {
      factory->manager->Report (CS_REPORTER_SEVERITY_ERROR,
			"No joint for bone %i while creating ragdoll chain.\n",
			bodyBone->GetAnimeshBone ());
      return false;
    }

    // create bone reference
    Bone bone;
    bone.boneID = bodyBone->GetAnimeshBone ();

    // create rigid body
    csRef<iRigidBody> rigidBody = factory->dynSys->CreateBody ();
    bone.rigidBody = rigidBody;

    // set body position
    csQuaternion rotation;
    csVector3 offset;
    skeleton->GetTransformAbsSpace (bone.boneID, rotation, offset);
    // TODO: we shouldn't have to use the conjugate of the quaternion, isn't it?
    csOrthoTransform boneTransform (csMatrix3 (rotation.GetConjugate ()), offset);
    csOrthoTransform animeshTransform = sceneNode->GetMovable ()->GetTransform ();
    csOrthoTransform bodyTransform = boneTransform * animeshTransform;
    rigidBody->SetTransform (bodyTransform);

    // set body properties if they are defined
    // (with the Bullet plugin, it is more efficient to define it before the colliders)
    iBodyBoneProperties* properties = bodyBone->GetBoneProperties ();
    if (properties)
      rigidBody->SetProperties (properties->GetMass (),
				properties->GetCenter (),
				properties->GetInertia ());

    // attach bone colliders
    for (uint index = 0; index < bodyBone->GetBoneColliderCount (); index++)
    {
      iBodyBoneCollider* collider = bodyBone->GetBoneCollider (index);

      switch (collider->GetGeometryType ())
	{
	case BOX_COLLIDER_GEOMETRY:
	  {
	    csVector3 boxSize;
	    collider->GetBoxGeometry (boxSize);
	    rigidBody->AttachColliderBox
	      (boxSize, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case CYLINDER_COLLIDER_GEOMETRY:
	  {
	    float length, radius;
	    collider->GetCylinderGeometry (length, radius);
	    rigidBody->AttachColliderCylinder
	      (length, radius, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case CAPSULE_COLLIDER_GEOMETRY:
	  {
	    float length, radius;
	    collider->GetCapsuleGeometry (length, radius);
	    rigidBody->AttachColliderCapsule
	      (length, radius, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case CONVEXMESH_COLLIDER_GEOMETRY:
	  {
	    iMeshWrapper* mesh;
	    collider->GetConvexMeshGeometry (mesh);
	    rigidBody->AttachColliderConvexMesh
	      (mesh, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case TRIMESH_COLLIDER_GEOMETRY:
	  {
	    iMeshWrapper* mesh;
	    collider->GetMeshGeometry (mesh);
	    rigidBody->AttachColliderMesh
	      (mesh, collider->GetTransform (), collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case PLANE_COLLIDER_GEOMETRY:
	  {
	    csPlane3 plane;
	    collider->GetPlaneGeometry (plane);
	    // TODO: add transform
	    rigidBody->AttachColliderPlane
	      (plane, collider->GetFriction (),
	       collider->GetDensity (), collider->GetElasticity (),
	       collider->GetSoftness ());
	    break;
	  }

	case SPHERE_COLLIDER_GEOMETRY:
	  {
	    csSphere sphere;
	    collider->GetSphereGeometry (sphere);
	    rigidBody->AttachColliderSphere
	      (sphere.GetRadius (),
	       sphere.GetCenter () + collider->GetTransform ().GetOrigin (),
	       collider->GetFriction (), collider->GetDensity (),
	       collider->GetElasticity (), collider->GetSoftness ());
	    break;
	  }

	default:
	  factory->manager->Report (CS_REPORTER_SEVERITY_ERROR,
	    "No geometry for collider in bone %i while creating ragdoll chain.\n",
				    bodyBone->GetAnimeshBone ());
	  return false;
	}
    }

    // TODO: remove bodies if problem

    // create dynamic joint
    if (parentBody)
      bone.joint = CreateDynamicJoint (bodyBone->GetBoneJoint (),
				       parentBody, rigidBody);

    // store bone
    bones.Put (bone.boneID, bone);

    // create child nodes
    for (uint i = 0; i < node->GetChildCount (); i++)
      if (!CreateRigidBodyNode (node->GetChild (i), rigidBody))
      {
	factory->manager->Report (CS_REPORTER_SEVERITY_ERROR,
				  "Problem creating ragdoll body for bone %i\n",
				  bodyBone->GetAnimeshBone ());
	return false;
      }

    return true;
  }
csMatrix3 operator+ (const csMatrix3& m1, const csMatrix3& m2) 
{
  return csMatrix3 (m1.m11+m2.m11, m1.m12+m2.m12, m1.m13+m2.m13,
                    m1.m21+m2.m21, m1.m22+m2.m22, m1.m23+m2.m23,
                    m1.m31+m2.m31, m1.m32+m2.m32, m1.m33+m2.m33);
}
예제 #23
0
  void IKPhysicalNode::AddConstraint (CS::Animation::EffectorID effectorID,
					  ConstraintData& constraint)
  {
    // Find the effector data
    EffectorData* effector = factory->effectors[effectorID];

    // Check if this chain has already some constraints
    ChainData chainData;
    if (!chains.Contains (effector->chain))
    {
      // Create a new entry for the chain
      chainData.previousState = ragdollNode->GetBodyChainState (effector->chain);
      chainData.constraintCount = 1;
      chains.Put (effector->chain, chainData);

      // Set the chain as dynamic
      ragdollNode->SetBodyChainState (effector->chain, CS::Animation::STATE_DYNAMIC);
    }

    else
    {
      chainData = chains.Get (effector->chain, chainData);
      chainData.constraintCount++;
    }

    // Compute the world transform of the effector
    csQuaternion boneRotation;
    csVector3 boneOffset;
    skeleton->GetTransformAbsSpace (effector->bone, boneRotation, boneOffset);
    csOrthoTransform boneTransform (csMatrix3 (boneRotation.GetConjugate ()), boneOffset);
    csOrthoTransform effectorTransform =
      effector->transform * boneTransform * sceneNode->GetMovable ()->GetFullTransform ();

    // Compute the world transform of the constraint target
    csOrthoTransform targetTransform;
    switch (constraint.type)
    {
    case CONSTRAINT_FIXED:
      targetTransform = constraint.offset;
      break;

    case CONSTRAINT_MOVABLE:
      targetTransform = constraint.offset * constraint.movable->GetFullTransform ();
      break;

    case CONSTRAINT_CAMERA:
      targetTransform = constraint.offset * constraint.camera->GetTransform ();
      break;

    default:
      break;
    }

    // Create a pivot joint
    constraint.dragJoint = bulletDynamicSystem->CreatePivotJoint ();
    constraint.dragJoint->Attach (ragdollNode->GetBoneRigidBody (effector->bone),
				  effectorTransform.GetOrigin ());
    constraint.dragJoint->SetPosition (targetTransform.GetOrigin ());

    constraints.PutUnique (effectorID, constraint);
  }
csMatrix3 operator- (const csMatrix3& m1, const csMatrix3& m2)
{
  return csMatrix3 (m1.m11-m2.m11, m1.m12-m2.m12, m1.m13-m2.m13,
                    m1.m21-m2.m21, m1.m22-m2.m22, m1.m23-m2.m23,
                    m1.m31-m2.m31, m1.m32-m2.m32, m1.m33-m2.m33);
}
csMatrix3 operator* (float f, const csMatrix3& m)
{
  return csMatrix3 (m.m11*f, m.m12*f, m.m13*f,
                    m.m21*f, m.m22*f, m.m23*f,
                    m.m31*f, m.m32*f, m.m33*f);
}