示例#1
0
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);
		}
	}
}
示例#2
0
文件: game.cpp 项目: elemel/crust
 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));
         }
     }
 }
示例#3
0
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;
}
示例#4
0
文件: Box2.cpp 项目: tlein/Ancona
bool Box2::Intersects(const Box2 & box) const
{
    Math::Vertices2 verticesA;
    Math::Vertices2 verticesB;

    GetVertices(verticesA);
    box.GetVertices(verticesB);

    return Math::Collide(verticesA,verticesB);
}
示例#5
0
/** 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;
}
示例#6
0
/******************************************************************************
* 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)));
}
示例#7
0
文件: game.cpp 项目: elemel/crust
 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;
             }
         }
     }
 }
示例#8
0
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;
}
示例#9
0
文件: game.cpp 项目: elemel/crust
 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_);
 }
示例#10
0
//----------------------------------------------------------------------------
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;
}
示例#11
0
//----------------------------------------------------------------------------
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;
}
示例#12
0
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;
}