示例#1
0
float psLinearMovement::GetYRotation () const
{
  // user will get a warning and a nothing if theres no mesh
  if (!mesh)  return 0.0;
  const csMatrix3& transf = mesh->GetMovable ()
    ->GetTransform ().GetT2O ();
  return Matrix2YRot (transf);
}
示例#2
0
void psWorld::GetPosition(iMeshWrapper* pcmesh, csVector3 &pos, float* yrot,iSector* &sector)
{
    pos = pcmesh->GetMovable()->GetPosition();

    // rotation
    if(yrot)
    {
        csMatrix3 transf = pcmesh->GetMovable()->GetTransform().GetT2O();
        *yrot = Matrix2YRot(transf);
    }

    // Sector
    if(pcmesh->GetMovable()->GetSectors()->GetCount())
    {
        sector = pcmesh->GetMovable()->GetSectors()->Get(0);
    }
    else
    {
        sector = NULL;
    }
}
示例#3
0
int psLinearMovement::MoveSprite (float delta)
{
  int ret = PS_MOVE_SUCCEED;

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

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

  float local_max_interval =
  	MIN (MIN ( (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)
        );

  // Compensate for speed
  local_max_interval /= speed;
  // 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 = MAX(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);
        yrot = Matrix2YRot (transf);
        
        // 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 = MIN (MIN ((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));
      // Compensate for speed
      local_max_interval /= speed;
      // 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 = MAX(local_max_interval,0.1F);
    }
  }

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

  return ret;
}