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; } } }
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; }
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; }
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; }
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; }
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++; }
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; }
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; }
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++; }
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 (); }
void csMeshGeneratorGeometry::AddPositionsFromMap (iTerraFormer* map, const csBox2 ®ion, 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; } }
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; }