void PositionMap::InsertNewArea (const csBox2& areaBox)
  {
    float side1 = areaBox.MaxX() - areaBox.MinX();
    float side2 = areaBox.MaxY() - areaBox.MinY();
    float minSide = csMin (side1, side2);

    /* Insert area into bucket with the largest radius smaller or equal
       to minSide */
    for (size_t b = 0; b < buckets.GetSize(); b++)
    {
      Bucket& bucket = buckets[b];
      if (minSide >= bucket.minSide)
      {
	Bucket::Area newArea;
	newArea.area = side1*side2;
	newArea.box = GetBoxAlloc()->Alloc (areaBox);
	size_t index = bucket.freeAreas.Push (newArea);
	if (index > 0)
	{
	  size_t parent = (index-1) / 2;
	  if (bucket.freeAreas[parent].box)
	  {
	    // 'Parent' node is a leaf, turn it into a node
	    bucket.freeAreas.Push (bucket.freeAreas[parent]);
	    bucket.freeAreas[parent].box = nullptr;
	  }
	}
	BubbleAreaIncrease (bucket, index, newArea.area);
	break;
      }
    }
  }
Exemple #2
0
bool csBox3::ProjectBoxAndOutline (const csTransform& trans, float fov,
                                   float sx, float sy, csBox2& sbox, csPoly2D& poly,
                                   float& min_z, float& max_z) const
{
    const csVector3& origin = trans.GetOrigin ();
    int idx = CalculatePointSegment (origin);
    const Outline &ol = outlines[idx];
    int num_array = MIN (ol.num, 6);
    poly.SetVertexCount (num_array);

    min_z = 100000000.0;
    max_z = 0;
    sbox.StartBoundingBox ();
    int i;
    // We go to 8 so that we can calculate the correct min_z/max_z.
    // If we only go to num_array we will only calculate min_z/max_z
    // for the outine vertices.
    for (i = 0 ; i < 8 ; i++)
    {
        csVector3 v = trans * GetCorner (ol.vertices[i]);
        if (v.z > max_z) max_z = v.z;
        if (v.z < min_z) min_z = v.z;
        if (i < num_array)
        {
            if (v.z < .1)
                PerspectiveWrong (v, poly[i], fov, sx, sy);
            else
                Perspective (v, poly[i], fov, sx, sy);
            sbox.AddBoundingVertex (poly[i]);
        }
    }
    return max_z >= .1;
}
Exemple #3
0
bool csIntersect2::SegmentBox (csSegment2& segment, const csBox2& box)
{
  const csVector2& minBox = box.Min ();
  const csVector2& maxBox = box.Max ();

  const csVector2& origin = segment.Start ();
  csVector2 direction = segment.End () - segment.Start ();

  // Check if ray have any chance of going through box
  for (int i = 0; i < 2; ++i)
  {
    if (direction[i] < 0)
    {
      if (origin[i] < minBox[i]) return false;
    }
    else if (direction[i] > 0)
    {
      if (origin[i] > maxBox[i]) return false;
    }
    else
    {
      if (origin[i] < minBox[i] || origin[i] > maxBox[i]) return false;
    }
  }  

  float mint = 0, maxt = direction.Norm ();
  direction /= maxt;

  // Clip a dimension at a time
  for (int i = 0; i < 2; ++i)
  {
    // Ray going "left"
    if (direction[i] < 0)
    {
      float mintp = (maxBox[i] - origin[i]) / direction[i];
      float maxtp = (minBox[i] - origin[i]) / direction[i];
      if (mintp > mint)
        mint = mintp;

      if (maxtp < maxt)
        maxt = maxtp;
    }
    else if (direction[i] > 0) // Ray going "right"
    {
      float mintp = (minBox[i] - origin[i]) / direction[i];
      float maxtp = (maxBox[i] - origin[i]) / direction[i];
      if (mintp > mint)
        mint = mintp;

      if (maxtp < maxt)
        maxt = maxtp;
    }
    if (mint > maxt) return false;
  }

  // Update segment
  segment.SetEnd (origin + maxt*direction);
  segment.SetStart (origin + mint*direction);  
  return true;
}
Exemple #4
0
int csPolygonClipper::ClassifyBox (const csBox2 &box)
{
  if (!ClipBox.Overlap (box)) return -1;
  if (!IsInside (box.GetCorner (0))) return 0;
  if (!IsInside (box.GetCorner (1))) return 0;
  if (!IsInside (box.GetCorner (2))) return 0;
  if (!IsInside (box.GetCorner (3))) return 0;
  return 1;
}
Exemple #5
0
int csBoxClipper::ClassifyBox (const csBox2 &box)
{
  if (!region.Overlap (box)) return -1;
  if (
    box.MinX () >= region.MinX () &&
    box.MaxX () <= region.MaxX () &&
    box.MinY () >= region.MinY () &&
    box.MaxY () <= region.MaxY ())
    return 1;
  return 0;
}
Exemple #6
0
void RenderView::SetFrustumFromBox (const csBox2& box)
{
  float iw = 2.0f/viewWidth;
  float ih = 2.0f/viewHeight;
  float lx_n = csClamp (box.MinX() * iw - 1.0f, 1.0f, -1.0f);
  float rx_n = csClamp (box.MaxX() * iw - 1.0f, 1.0f, -1.0f);
  float ty_n = csClamp (box.MinY() * ih - 1.0f, 1.0f, -1.0f);
  float by_n = csClamp (box.MaxY() * ih - 1.0f, 1.0f, -1.0f);
 
  CS::Math::Matrix4 invMatrix_inv_t =
    ctxt->icamera->GetProjectionMatrix().GetTranspose();

  int n = 0;
  csPlane3 *frustum = ctxt->frustum;
  csPlane3 p;
  // Back plane
  p.Set (0, 0, -1, 1);
  frustum[n] = invMatrix_inv_t * p;
  frustum[n].Normalize();

  n++;
  // Far plane
  /*p.Set (0, 0, -1, 1);
  clipPlanes[n] = invMatrix_inv_t * p;
  clipPlanes[n].Normalize();
  n++;*/
  // Left plane
  p.Set (1, 0, 0, -lx_n);
  frustum[n] = invMatrix_inv_t * p;
  frustum[n].Normalize();
  n++;
  // Right plane
  p.Set (-1, 0, 0, rx_n);
  frustum[n] = invMatrix_inv_t * p;
  frustum[n].Normalize();
  n++;
  // Bottom plane
  p.Set (0, -1, 0, by_n);
  frustum[n] = invMatrix_inv_t * p;
  frustum[n].Normalize();
  n++;
  // Top plane
  p.Set (0, 1, 0, -ty_n);
  frustum[n] = invMatrix_inv_t * p;
  frustum[n].Normalize();
  n++;
}
Exemple #7
0
uint8 csPolygonClipper::Clip (
  csVector2 *InPolygon,
  size_t InCount,
  csVector2 *OutPolygon,
  size_t &OutCount,
  csBox2 &BoundingBox)
{
  if (!ClipBox.Overlap (BoundingBox)) return CS_CLIP_OUTSIDE;

  uint8 rc = Clip (InPolygon, InCount, OutPolygon, OutCount);
  if (rc != CS_CLIP_OUTSIDE)
  {
    BoundingBox.StartBoundingBox (OutPolygon[0]);

    size_t i;
    for (i = 1; i < OutCount; i++)
      BoundingBox.AddBoundingVertexSmart (OutPolygon[i]);
  }

  return rc;
}
Exemple #8
0
uint8 csBoxClipper::Clip (
  csVector2 *InPolygon,
  size_t InCount,
  csVector2 *OutPolygon,
  size_t &OutCount,
  csBox2 &BoundingBox)
{
  if (!region.Overlap (BoundingBox)) return CS_CLIP_OUTSIDE;

  CS::BoxClipper<BoxTestBbox, StatusOutputNone> boxClip
    (BoxTestBbox (BoundingBox, region), StatusOutputNone(), region,
    InPolygon, InCount, OutPolygon);

  uint8 Clipped = boxClip.Clip();
  OutCount = boxClip.GetOutputCount();

  BoundingBox.StartBoundingBox (OutPolygon[0]);
  size_t i;
  for (i = 1; i < OutCount; i++)
    BoundingBox.AddBoundingVertexSmart (OutPolygon[i]);
  return Clipped;
}
Exemple #9
0
 BoxTestBbox (const csBox2& BoundingBox,
   const csBox2& region) : ClipEdges(0), ClipCount (0)
 {
   // Do we need to clip against left x line?
   if (BoundingBox.MinX () < region.MinX ())
     ClipEdges |= 1, ClipCount++;
   // Do we need to clip against right x line?
   if (BoundingBox.MaxX () > region.MaxX ())
     ClipEdges |= 2, ClipCount++;
   // Do we need to clip against bottom y line?
   if (BoundingBox.MinY () < region.MinY ())
     ClipEdges |= 4, ClipCount++;
   // Do we need to clip against top y line?
   if (BoundingBox.MaxY () > region.MaxY ())
     ClipEdges |= 8, ClipCount++;
 }
Exemple #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 ();
}
Exemple #11
0
void csMeshGeneratorGeometry::AddPositionsFromMap (iTerraFormer* map,
	const csBox2 &region, uint resx, uint resy, float value,
	const csStringID & type)
{
  csRef<iTerraSampler> sampler = map->GetSampler (region, resx, resy);
  float stepx = (region.MaxX () - region.MinX ())/resx;
  float stepy = (region.MaxY () - region.MinY ())/resy;

  const float* map_values = sampler->SampleFloat (type);
  float curx = region.MinX (), cury = region.MinY ();
  for (uint i = 0; i < resx; i++)
  {
    for (uint j = 0; j < resy; j++)
    {
      if (map_values[i*resx + j] == value)
      {
        AddPosition (csVector2 (curx, cury));
      }
      curx += stepx;
    }
    curx = region.MinX ();
    cury += stepy;
  }
}
Exemple #12
0
bool csBox3::ProjectBox (const csTransform& trans, float fov,
                         float sx, float sy, csBox2& sbox, float& min_z, float& max_z) const
{
    const csVector3& origin = trans.GetOrigin ();
    int idx = CalculatePointSegment (origin);
    const Outline &ol = outlines[idx];
    int num_array = MIN (ol.num, 6);

    min_z = 100000000.0;
    max_z = 0;
    csBox3 cbox (trans * GetCorner (ol.vertices[0]));
    int i;
    // We go to 8 so that we can calculate the correct min_z/max_z.
    // If we only go to num_array we will only calculate min_z/max_z
    // for the outine vertices.
    for (i = 1; i < 8; i++)
    {
        csVector3 v = trans * GetCorner (ol.vertices[i]);
        if (i < num_array)
        {
            cbox.AddBoundingVertexSmart (v);
            min_z = cbox.MinZ ();
            max_z = cbox.MaxZ ();
        }
        else
        {
            if (v.z < min_z) min_z = v.z;
            if (v.z > max_z) max_z = v.z;
        }
    }

    if (max_z < 0.01) return false;

// @@@ In theory we can optimize here again by calling CalculatePointSegment
// again for the new box and the 0,0,0 point. By doing that we could
// avoid doing four perspective projections.

    // If z < .1 we do conservative clipping. Not correct but it will generate
    // a box that is bigger then the real one which is ok for testing culling.
    csVector2 oneCorner;
    if (cbox.Max ().z < .1)
        PerspectiveWrong (cbox.Max (), oneCorner, fov, sx, sy);
    else
        Perspective (cbox.Max (), oneCorner, fov, sx, sy);
    sbox.StartBoundingBox (oneCorner);

    csVector3 v (cbox.MinX (), cbox.MinY (), cbox.MaxZ ());
    if (v.z < .1)
        PerspectiveWrong (v, oneCorner, fov, sx, sy);
    else
        Perspective (v, oneCorner, fov, sx, sy);
    sbox.AddBoundingVertexSmart (oneCorner);

    if (cbox.Min ().z < .1)
        PerspectiveWrong (cbox.Min (), oneCorner, fov, sx, sy);
    else
        Perspective (cbox.Min (), oneCorner, fov, sx, sy);
    sbox.AddBoundingVertexSmart (oneCorner);

    v.Set (cbox.MaxX (), cbox.MaxY (), cbox.MinZ ());
    if (v.z < .1)
        PerspectiveWrong (v, oneCorner, fov, sx, sy);
    else
        Perspective (v, oneCorner, fov, sx, sy);
    sbox.AddBoundingVertexSmart (oneCorner);

    return true;
}