Beispiel #1
0
static csVector3 FindBiggestHorizontalMovement (
    const csBox3& box1, const csReversibleTransform& trans1,
    const csBox3& box2, const csReversibleTransform& trans2)
{
  // The origin of the second box in the 3D space of the first box.
  csVector3 o2Tr = trans1.Other2This (trans2.GetOrigin ());
  // Transformed bounding box.
  csBox3 box2Tr;
  box2Tr.StartBoundingBox (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (0))));
  box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (1))));
  box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (2))));
  box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (3))));
  box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (4))));
  box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (5))));
  box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (6))));
  box2Tr.AddBoundingVertexSmart (trans1.Other2ThisRelative (trans2.This2OtherRelative (box2.GetCorner (7))));

  float xr = o2Tr.x - box1.MaxX () + box2Tr.MinX ();
  float xl = box1.MinX () - o2Tr.x - box2Tr.MaxX ();
  float zr = o2Tr.z - box1.MaxZ () + box2Tr.MinZ ();
  float zl = box1.MinZ () - o2Tr.z - box2Tr.MaxZ ();
  csVector3 newpos = trans2.GetOrigin ();
  if (xr >= xl && xr >= zr && xr >= zl)
    newpos = trans1.This2Other (o2Tr + csVector3 (-xr, 0, -o2Tr.z));
  else if (xl >= xr && xl >= zr && xl >= zl)
    newpos = trans1.This2Other (o2Tr + csVector3 (xl, 0, -o2Tr.z));
  else if (zr >= xl && zr >= xr && zr >= zl)
    newpos = trans1.This2Other (o2Tr + csVector3 (-o2Tr.x, 0, -zr));
  else if (zl >= xl && zl >= xr && zl >= zr)
    newpos = trans1.This2Other (o2Tr + csVector3 (-o2Tr.x, 0, zl));
  return newpos;
}
Beispiel #2
0
Datei: box.cpp Projekt: garinh/cs
int csBox3::Adjacent (const csBox3 &other, float epsilon) const
{
    if (AdjacentX (other, epsilon))
    {
        if (other.MaxX () > MaxX ())
            return CS_BOX_SIDE_X;
        else
            return CS_BOX_SIDE_x;
    }

    if (AdjacentY (other, epsilon))
    {
        if (other.MaxY () > MaxY ())
            return CS_BOX_SIDE_Y;
        else
            return CS_BOX_SIDE_y;
    }

    if (AdjacentZ (other, epsilon))
    {
        if (other.MaxZ () > MaxZ ())
            return CS_BOX_SIDE_Z;
        else
            return CS_BOX_SIDE_z;
    }

    return -1;
}
int csBox3::Adjacent (const csBox3& other) const
{
  if (AdjacentX (other))
  {
    if (other.MaxX () > MaxX ()) return BOX_SIDE_X;
    else return BOX_SIDE_x;
  }
  if (AdjacentY (other))
  {
    if (other.MaxY () > MaxY ()) return BOX_SIDE_Y;
    else return BOX_SIDE_y;
  }
  if (AdjacentZ (other))
  {
    if (other.MaxZ () > MaxZ ()) return BOX_SIDE_Z;
    else return BOX_SIDE_z;
  }
  return -1;
}
Beispiel #4
0
void csMeshWrapper::GetFullBBox (csBox3& box)
{
  box = GetObjectModel ()->GetObjectBoundingBox ();
  csMovable* mov = &movable;
  while (mov)
  {
    if (!mov->IsTransformIdentity ())
    {
      const csReversibleTransform& trans = mov->GetTransform ();
      csBox3 b (trans.This2Other (box.GetCorner (0)));
      b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (1)));
      b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (2)));
      b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (3)));
      b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (4)));
      b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (5)));
      b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (6)));
      b.AddBoundingVertexSmart (trans.This2Other (box.GetCorner (7)));
      box = b;
    }
    mov = ((csMovable*)mov)->GetParent ();
  }
}
Beispiel #5
0
csBox3 csReversibleTransform::This2Other (const csBox3 &box) const
{
  if (m_t2o.IsIdentity())
  {
    csBox3 newBox (box);
    newBox.SetCenter (This2Other (box.GetCenter()));
    return newBox;
  }
  else
  {
    const csVector3 minA = box.Min ();
    const csVector3 maxA = box.Max ();

    csVector3 minB (v_o2t);
    csVector3 maxB (v_o2t);

    for (size_t i = 0; i < 3; ++i)
    {
      const csVector3 row = m_t2o.Row (i);
      for (size_t j = 0; j < 3; ++j)
      {
        float a = row[j] * minA[j];
        float b = row[j] * maxA[j];
        if (a < b)
        {
          minB[i] += a;
          maxB[i] += b;
        }
        else
        {
          minB[i] += b;
          maxB[i] += a;
        }
      }
    }

    return csBox3 (minB, maxB);
  }
}
Beispiel #6
0
void csMeshOnTexture::ScaleCamera (iMeshWrapper* mesh, int txtw, int txth)
{
  UpdateView (txtw, txth);
  const csBox3 mesh_box = mesh->GetWorldBoundingBox ();
  const csVector3 mesh_center = mesh_box.GetCenter ();
  const iPerspectiveCamera* camera = view->GetPerspectiveCamera ();
  const float aspect = camera->GetFOV ();
  const float shift_x = camera->GetShiftX ();
  const float shift_y = camera->GetShiftY ();
  int i;
  float maxz = -100000000.0f;
  for (i = 0 ; i < 8 ; i++)
  {
    csVector3 corner = mesh_box.GetCorner (i) - mesh_center;
    float z = (corner.x * aspect) / (1.0f - shift_x);
    if (z < 0) z = (corner.x * aspect) / (float (txtw) - shift_x);
    z += corner.z;
    if (z > maxz) maxz = z;

    z = (corner.y * aspect) / (1.0f - shift_y);
    if (z < 0) z = (corner.y * aspect) / (float (txth) - shift_y);
    z += corner.z;
    if (z > maxz) maxz = z;
  }

  csVector3 cam_pos = mesh_center;
  cam_pos.z -= maxz;
  for (i = 0 ; i < 8 ; i++)
  {
    csVector3 corner = mesh_box.GetCorner (i) - cam_pos;
    csVector2 p = view->GetCamera()->Perspective (corner);
  }

  view->GetCamera()->GetTransform ().Identity ();
  view->GetCamera()->GetTransform ().SetOrigin (cam_pos);
}
bool csBox3::AdjacentZ (const csBox3& other) const
{
  if (ABS (other.MinZ () - MaxZ ()) < SMALL_EPSILON ||
      ABS (other.MaxZ () - MinZ ()) < SMALL_EPSILON)
  {
    if (MaxX () < other.MinX () || MinX () > other.MaxX ()) return false;
    if (MaxY () < other.MinY () || MinY () > other.MaxY ()) return false;
    return true;
  }
  return false;
}
Beispiel #8
0
Datei: box.cpp Projekt: garinh/cs
bool csBox3::AdjacentZ (const csBox3 &other, float epsilon) const
{
    if (
        ABS (other.MinZ () - MaxZ ()) < epsilon ||
        ABS (other.MaxZ () - MinZ ()) < epsilon)
    {
        if (MaxX () < other.MinX () || MinX () > other.MaxX ()) return false;
        if (MaxY () < other.MinY () || MinY () > other.MaxY ()) return false;
        return true;
    }

    return false;
}
Beispiel #9
0
Datei: box.cpp Projekt: garinh/cs
void csBox3::ManhattanDistance (const csBox3 &other, csVector3 &dist) const
{
    if (other.MinX () >= MaxX ())
        dist.x = other.MinX () - MaxX ();
    else if (MinX () >= other.MaxX ())
        dist.x = MinX () - other.MaxX ();
    else
        dist.x = 0;
    if (other.MinY () >= MaxY ())
        dist.y = other.MinY () - MaxY ();
    else if (MinY () >= other.MaxY ())
        dist.y = MinY () - other.MaxY ();
    else
        dist.y = 0;
    if (other.MinZ () >= MaxZ ())
        dist.z = other.MinZ () - MaxZ ();
    else if (MinZ () >= other.MaxZ ())
        dist.z = MinZ () - other.MaxZ ();
    else
        dist.z = 0;
}
Beispiel #10
0
float csHazeMeshObject::GetScreenBoundingBox (long cameranr,
      long movablenr, float fov, float sx, float sy,
      const csReversibleTransform& trans, csBox2& sbox, csBox3& cbox)
{
  csVector2 oneCorner;

  GetTransformedBoundingBox (cameranr, movablenr, trans, cbox);

  // if the entire bounding box is behind the camera, we're done
  if ((cbox.MinZ () < 0) && (cbox.MaxZ () < 0))
  {
    return -1;
  }

  // Transform from camera to screen space.
  if (cbox.MinZ () <= 0)
  {
    // Sprite is very close to camera.
    // Just return a maximum bounding box.
    sbox.Set (-10000, -10000, 10000, 10000);
  }
  else
  {
    Perspective (cbox.Max (), oneCorner, fov, sx, sy);
    sbox.StartBoundingBox (oneCorner);
    csVector3 v (cbox.MinX (), cbox.MinY (), cbox.MaxZ ());
    Perspective (v, oneCorner, fov, sx, sy);
    sbox.AddBoundingVertexSmart (oneCorner);
    Perspective (cbox.Min (), oneCorner, fov, sx, sy);
    sbox.AddBoundingVertexSmart (oneCorner);
    v.Set (cbox.MaxX (), cbox.MaxY (), cbox.MinZ ());
    Perspective (v, oneCorner, fov, sx, sy);
    sbox.AddBoundingVertexSmart (oneCorner);
  }

  return cbox.MaxZ ();
}
/*
 * In order to update the navigation structure, we have to update the navigation meshes for the
 * affected area, as well as the high level graph. When a navmesh gets updated, a path between
 * two portals may be closed or opened, and we have to add or remove edges to the graph to
 * account for this.
 */
bool celHNavStruct::Update (const csBox3& boundingBox, iSector* sector)
{
  if (!sector) 
  {
    bool ret;
    csHash<csRef<iCelNavMesh>, csPtrKey<iSector> >::GlobalIterator it = navMeshes.GetIterator();
    csPtrKey<iSector> key;
    while (it.HasNext())
    {
      csRef<iCelNavMesh> navMesh = it.Next(key);
      csBox3 navMeshBoundingBox = navMesh->GetBoundingBox();
      if (boundingBox.Overlap(navMeshBoundingBox))
      {
        ret = Update(boundingBox, key);
        if (!ret)
        {
          return false;
        }
      }
    }
  }

  csPtrKey<iSector> key = sector;
  csRef<iCelNavMesh> navMesh = navMeshes.Get(key, 0);
  navMesh->Update(boundingBox);

  // Update high level graph
  int nNodes = hlGraph->GetNodeCount();
  csArray<csRef<iCelNode> > sameSectorNodes(hlGraph->GetNodeCount());
  uint sectorId = sector->QueryObject()->GetID();
  int sameSectorSize = 0;
  for (int i = 0; i < nNodes; ++i)
  {
    csRef<iCelNode> node = hlGraph->GetNode(i);
    uint nodeSectorId = node->GetMapNode()->GetSector()->QueryObject()->GetID();
    if (nodeSectorId == sectorId)
    {
      sameSectorNodes.Push(node);
      sameSectorSize++;
    }
  }
  for (int i = 0; i < sameSectorSize; ++i)
  {
    csRef<iCelNode> node = sameSectorNodes[i];

    // Check edges from the high level graph that are on the updated sector, to update weights and
    // see if any of them was obstructed.
    int nEdges = node->GetEdgeCount();
    for (int j = nEdges - 1; j > 0; j--)
    {
      csRef<iCelEdge> edge = node->GetEdge(j);
      csRef<iCelNode> node2 = edge->GetSuccessor();
      uint edgeSectorId = node2->GetMapNode()->GetSector()->QueryObject()->GetID();
      if (edgeSectorId == sectorId)
      {
        csRef<iCelNavMeshPath> path = navMesh->ShortestPath(node->GetPosition(), node2->GetPosition(), 256);
        if (path->GetNodeCount() > 0)
        {
          csVector3 last;
          path->GetLast(last);
          csVector3 box = parameters->GetPolygonSearchBox();
          // Check if last calculated point is within reach of the last given point
          if (ABS(last[0] - node2->GetPosition()[0]) <= box[0] && 
              ABS(last[1] - node2->GetPosition()[1]) <= box[1] &&
              ABS(last[2] - node2->GetPosition()[2]) <= box[2]) 
          {
            float length = path->Length();
            edge->SetWeight(length);
          }
          else
          {
            node->RemoveEdge(j);
          }
        }
        else
        {
          node->RemoveEdge(j);
        }
      }
    }

    // Check if any edges need to be added to the high level graph (a path might have opened)
    for (int j = i + 1; j < sameSectorSize; ++j)
    {
      csRef<iCelNode> node2 = sameSectorNodes[j];
      bool found = false;
      for (int k = 0; j < nEdges; ++k)
      {
        if (node2 == node->GetEdge(k)->GetSuccessor())
        {
          found = true;
          break;
        }
      }
      if (!found)
      {
        csRef<iCelNavMeshPath> path = navMesh->ShortestPath(node->GetPosition(), node2->GetPosition(), 256);
        if (path->GetNodeCount() > 0)
        {
          csVector3 last;
          path->GetLast(last);
          csVector3 box = parameters->GetPolygonSearchBox();
          // Check if last calculated point is within reach of the last given point
          if (ABS(last[0] - node2->GetPosition()[0]) <= box[0] && 
              ABS(last[1] - node2->GetPosition()[1]) <= box[1] &&
              ABS(last[2] - node2->GetPosition()[2]) <= box[2]) 
          {
            float length = path->Length();
            hlGraph->AddEdge(node, node2, true, length);
            hlGraph->AddEdge(node2, node, true, length);
          }
        }
      }
    }
  }

  return true;
}
void HeightMapGen::CreateHeightmap (int heightmap_res, iCollideSystem* cdsys, 
                                     iSector* sector, csRGBpixel* hmap_dst, 
                                     float* height_dst, 
                                     const csBox3& box)
{
  csPrintf ("Creating heightmap...\n"); fflush (stdout);

  float dx = (box.MaxX () - box.MinX () - 0.2) / float (heightmap_res-1);
  float dz = (box.MaxZ () - box.MinZ () - 0.2) / float (heightmap_res-1);
  for (int z = 0 ; z < heightmap_res ; z++)
  {
    for (int x = 0 ; x < heightmap_res ; x++)
    {
      csVector3 start, end;
      start.x = box.MinX () + (float)x * dx + 0.1;
      start.y = box.MaxY () + 10.0;
      start.z = box.MinZ () + (heightmap_res-z-1) * dz + 0.1;
      end = start;
      end.y = box.MinY () - 10.0;
      csVector3 isect;
      //mesh->HitBeamObject (start, end, isect, 0, 0);
      csIntersectingTriangle closest_tri;
      csColliderHelper::TraceBeam (cdsys, sector, start, end,
      	false, closest_tri, isect);
      float y = (isect.y - box.MinY ()) / (box.MaxY () - box.MinY ());
      if (y < 0) y = 0;
      else if (y > 0.9999f) y = 0.9999f;
      *height_dst++ = y;
      y *= 256.0;
      hmap_dst->Set (int (y), int (y), int (y));
      hmap_dst++;
    }
  }
}