void TileLayerComponentManager::_fillBuffer(VertexBuffer& buffer, const TileMapSP tileMap, unsigned layer, float tileWidth, float tileHeight, const Matrix4& wt) const { buffer.clear(); unsigned width = tileMap->width (layer); unsigned height = tileMap->height(layer); Vector2i nTiles(tileMap->tileSetHTiles(), tileMap->tileSetVTiles()); for(unsigned y = 0; y < height; ++y) { for(unsigned x = 0; x < width; ++x) { TileMap::TileIndex tile = tileMap->tile(x, y, layer); if(tile == 0) continue; unsigned index = buffer.vertexCount(); Box2 tc = boxView(tileBox(nTiles, tile - 1), Box2(Vector2(0.001, 0.001), Vector2(0.999, 0.999))); for(unsigned vi = 0; vi < 4; ++vi) { unsigned x2 = (vi & 0x01)? 1: 0; unsigned y2 = (vi & 0x02)? 1: 0; Vector4 pos = wt * Vector4(( x + x2) * tileWidth, (height - y - y2) * tileHeight, 0, 1); buffer.addVertex(SpriteVertex{ pos, Vector4::Constant(1), tc.corner(Box2::CornerType(x2 + y2*2)) }); } buffer.addIndex(index + 0); buffer.addIndex(index + 1); buffer.addIndex(index + 2); buffer.addIndex(index + 2); buffer.addIndex(index + 1); buffer.addIndex(index + 3); } } }
void Game::initBlocks() { Box2 paddedBounds = bounds_; paddedBounds.pad(2.0f); for (int i = 0; i < voronoiDiagram_.getPolygonCount(); ++i) { Polygon2 polygon = voronoiDiagram_.getPolygon(i); if (contains(paddedBounds, polygon)) { addActor(actorFactory_->createBlock(polygon)); } } }
bool CollisionComponentManager::hitTest(std::deque<EntityRef>& hits, const Box2& box, unsigned hitMask) { bool found = false; for(int ci = 0; ci < int(nComponents()); ++ci) { CollisionComponent& c = _components[ci]; if(!c.entity().isEnabledRec() || !c.isEnabled() || !c.shape() || c.shape()->type() != SHAPE_ALIGNED_BOX || (hitMask & c.hitMask()) == 0 || (hitMask & c.ignoreMask()) != 0) continue; Box2 cbox = c.worldAlignedBox(); if(!cbox.intersection(box).isEmpty()) { hits.push_back(c.entity()); found = true; } } return found; }
bool Box2::Intersects(const Box2 & box) const { Math::Vertices2 verticesA; Math::Vertices2 verticesB; GetVertices(verticesA); box.GetVertices(verticesB); return Math::Collide(verticesA,verticesB); }
/** Locks the specified region on the surface, returning a lockinfo structure containing data required to access the surface. @param eLockMode Lock access mode @param Region Region to lock @return A structure contaning data about the locked region @todo Does the region have to be of type long ? */ const Surface::LockInfo &DefaultImage::lock(LockMode eLockMode, const Box2<long> &Region) { if(m_LockInfo.pMemory) throw FailedException("Nuclex::Video::DefaultImage::lock()", "Tried to lock image multiple times"); Box2<long> ClippedRegion; if(!Region) ClippedRegion.BR = m_Size; else if((Region.TL.X < 0) || (Region.TL.Y < 0) || (Region.BR.X > static_cast<long>(m_Size.X)) || (Region.BR.Y > static_cast<long>(m_Size.Y))) throw InvalidArgumentException("Nuclex::Video::DefaultImage::lock()", "The locking region must not leave the image area"); m_LockInfo.Size = ClippedRegion.getSize(); m_LockInfo.nPitch = m_Size.X * Surface::bppFromFormat(m_eFormat); m_LockInfo.eFormat = m_eFormat; m_LockInfo.eMode = LM_READWRITE; m_LockInfo.pMemory = &m_Memory[0] + (ClippedRegion.TL.Y * m_LockInfo.nPitch + ClippedRegion.TL.X * Surface::bppFromFormat(m_eFormat)); return m_LockInfo; }
/****************************************************************************** * Determines the range of the construction grid to display. ******************************************************************************/ std::tuple<FloatType, Box2I> ViewportSceneRenderer::determineGridRange(Viewport* vp) { // Determine the area of the construction grid that is visible in the viewport. static const Point2 testPoints[] = { {-1,-1}, {1,-1}, {1, 1}, {-1, 1}, {0,1}, {0,-1}, {1,0}, {-1,0}, {0,1}, {0,-1}, {1,0}, {-1,0}, {-1, 0.5}, {-1,-0.5}, {1,-0.5}, {1,0.5}, {0,0} }; // Compute intersection points of test rays with grid plane. Box2 visibleGridRect; size_t numberOfIntersections = 0; for(size_t i = 0; i < sizeof(testPoints)/sizeof(testPoints[0]); i++) { Point3 p; if(vp->computeConstructionPlaneIntersection(testPoints[i], p, 0.1f)) { numberOfIntersections++; visibleGridRect.addPoint(p.x(), p.y()); } } if(numberOfIntersections < 2) { // Cannot determine visible parts of the grid. return std::tuple<FloatType, Box2I>(0.0f, Box2I()); } // Determine grid spacing adaptively. Point3 gridCenter(visibleGridRect.center().x(), visibleGridRect.center().y(), 0); FloatType gridSpacing = vp->nonScalingSize(vp->gridMatrix() * gridCenter) * 2.0f; // Round to nearest power of 10. gridSpacing = pow((FloatType)10, floor(log10(gridSpacing))); // Determine how many grid lines need to be rendered. int xstart = (int)floor(visibleGridRect.minc.x() / (gridSpacing * 10)) * 10; int xend = (int)ceil(visibleGridRect.maxc.x() / (gridSpacing * 10)) * 10; int ystart = (int)floor(visibleGridRect.minc.y() / (gridSpacing * 10)) * 10; int yend = (int)ceil(visibleGridRect.maxc.y() / (gridSpacing * 10)) * 10; return std::tuple<FloatType, Box2I>(gridSpacing, Box2I(Point2I(xstart, ystart), Point2I(xend, yend))); }
void Game::removeBlocks(Box2 const &box) { for (ActorIterator i = actors_.begin(); i != actors_.end(); ++i) { Actor *actor = &*i; if (isBlock(actor)) { BlockPhysicsComponent *physicsComponent = convert(actor->getPhysicsComponent()); b2Vec2 position = physicsComponent->getBody()->GetPosition(); if (box.containsPoint(Vector2(position.x, position.y))) { int j = i - actors_.begin(); removeActor(actor); i = actors_.begin() + j - 1; } } } }
bool Wml::TestIntersection (const Box2<Real>& rkBox0, const Box2<Real>& rkBox1) { // convenience variables const Vector2<Real>* akA = rkBox0.Axes(); const Vector2<Real>* akB = rkBox1.Axes(); const Real* afEA = rkBox0.Extents(); const Real* afEB = rkBox1.Extents(); // compute difference of box centers, D = C1-C0 Vector2<Real> kD = rkBox1.Center() - rkBox0.Center(); Real aafAbsAdB[2][2], fAbsAdD, fRSum; // axis C0+t*A0 aafAbsAdB[0][0] = Math<Real>::FAbs(akA[0].Dot(akB[0])); aafAbsAdB[0][1] = Math<Real>::FAbs(akA[0].Dot(akB[1])); fAbsAdD = Math<Real>::FAbs(akA[0].Dot(kD)); fRSum = afEA[0] + afEB[0]*aafAbsAdB[0][0] + afEB[1]*aafAbsAdB[0][1]; if ( fAbsAdD > fRSum ) return false; // axis C0+t*A1 aafAbsAdB[1][0] = Math<Real>::FAbs(akA[1].Dot(akB[0])); aafAbsAdB[1][1] = Math<Real>::FAbs(akA[1].Dot(akB[1])); fAbsAdD = Math<Real>::FAbs(akA[1].Dot(kD)); fRSum = afEA[1] + afEB[0]*aafAbsAdB[1][0] + afEB[1]*aafAbsAdB[1][1]; if ( fAbsAdD > fRSum ) return false; // axis C0+t*B0 fAbsAdD = Math<Real>::FAbs(akB[0].Dot(kD)); fRSum = afEB[0] + afEA[0]*aafAbsAdB[0][0] + afEA[1]*aafAbsAdB[1][0]; if ( fAbsAdD > fRSum ) return false; // axis C0+t*B1 fAbsAdD = Math<Real>::FAbs(akB[1].Dot(kD)); fRSum = afEB[1] + afEA[0]*aafAbsAdB[0][1] + afEA[1]*aafAbsAdB[1][1]; if ( fAbsAdD > fRSum ) return false; return true; }
void Game::initVoronoiDiagram() { Box2 vertexBounds = bounds_; vertexBounds.pad(5.0f); Box2 triangulationBounds = vertexBounds; triangulationBounds.pad(5.0f); delauneyTriangulation_ = DelauneyTriangulation(triangulationBounds); int subdivCount = 30; float subdivWidth = float(vertexBounds.getWidth()) / float(subdivCount); float subdivHeight = float(vertexBounds.getHeight()) / float(subdivCount); for (int i = 0; i < subdivCount; ++i) { for (int j = 0; j < subdivCount; ++j) { float x = vertexBounds.p1.x + (float(i) + getRandomFloat()) * subdivWidth; float y = vertexBounds.p1.y + (float(j) + getRandomFloat()) * subdivHeight; delauneyTriangulation_.addVertex(Vector2(x, y)); } } voronoiDiagram_.generate(delauneyTriangulation_); }
//---------------------------------------------------------------------------- bool Mgc::ContOrientedBox (int iQuantity, const Vector2* akPoint, const bool* abValid, Box2& rkBox) { if ( !GaussPointsFit(iQuantity,akPoint,abValid,rkBox.Center(), rkBox.Axes(),rkBox.Extents()) ) { return false; } // Let C be the box center and let U0 and U1 be the box axes. Each input // point is of the form X = C + y0*U0 + y1*U1. The following code // computes min(y0), max(y0), min(y1), and max(y1). The box center is // then adjusted to be // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 // get first valid vertex Vector2 kDiff; Real fY0Min, fY0Max, fY1Min, fY1Max; int i; for (i = 0; i < iQuantity; i++) { if ( abValid[i] ) { kDiff = akPoint[i] - rkBox.Center(); fY0Min = kDiff.Dot(rkBox.Axis(0)); fY0Max = fY0Min; fY1Min = kDiff.Dot(rkBox.Axis(1)); fY1Max = fY1Min; break; } } for (i++; i < iQuantity; i++) { if ( abValid[i] ) { kDiff = akPoint[i] - rkBox.Center(); Real fY0 = kDiff.Dot(rkBox.Axis(0)); if ( fY0 < fY0Min ) fY0Min = fY0; else if ( fY0 > fY0Max ) fY0Max = fY0; Real fY1 = kDiff.Dot(rkBox.Axis(1)); if ( fY1 < fY1Min ) fY1Min = fY1; else if ( fY1 > fY1Max ) fY1Max = fY1; } } rkBox.Center() += (0.5f*(fY0Min+fY0Max))*rkBox.Axis(0) + (0.5f*(fY1Min+fY1Max))*rkBox.Axis(1); rkBox.Extent(0) = 0.5f*(fY0Max - fY0Min); rkBox.Extent(1) = 0.5f*(fY1Max - fY1Min); return true; }
//---------------------------------------------------------------------------- Box2 Mgc::ContOrientedBox (int iQuantity, const Vector2* akPoint) { Box2 kBox; GaussPointsFit(iQuantity,akPoint,kBox.Center(),kBox.Axes(), kBox.Extents()); // Let C be the box center and let U0 and U1 be the box axes. Each input // point is of the form X = C + y0*U0 + y1*U1. The following code // computes min(y0), max(y0), min(y1), and max(y1). The box center is // then adjusted to be // C' = C + 0.5*(min(y0)+max(y0))*U0 + 0.5*(min(y1)+max(y1))*U1 Vector2 kDiff = akPoint[0] - kBox.Center(); Real fY0Min = kDiff.Dot(kBox.Axis(0)), fY0Max = fY0Min; Real fY1Min = kDiff.Dot(kBox.Axis(1)), fY1Max = fY1Min; for (int i = 1; i < iQuantity; i++) { kDiff = akPoint[i] - kBox.Center(); Real fY0 = kDiff.Dot(kBox.Axis(0)); if ( fY0 < fY0Min ) fY0Min = fY0; else if ( fY0 > fY0Max ) fY0Max = fY0; Real fY1 = kDiff.Dot(kBox.Axis(1)); if ( fY1 < fY1Min ) fY1Min = fY1; else if ( fY1 > fY1Max ) fY1Max = fY1; } kBox.Center() += (0.5f*(fY0Min+fY0Max))*kBox.Axis(0) + (0.5f*(fY1Min+fY1Max))*kBox.Axis(1); kBox.Extent(0) = 0.5f*(fY0Max - fY0Min); kBox.Extent(1) = 0.5f*(fY1Max - fY1Min); return kBox; }
ShapeSP Shape::newAlignedBox(const Box2& box) { ShapeSP shape = std::make_shared<Shape>(SHAPE_ALIGNED_BOX); shape->_points.push_back(box.min()); shape->_points.push_back(box.max()); return shape; }