コード例 #1
0
ファイル: Caves.cpp プロジェクト: ThuGie/MCServer
bool cCaveTunnel::RefineDefPoints(const cCaveDefPoints & a_Src, cCaveDefPoints & a_Dst)
{
	if (a_Src.size() < 2)
	{
		// There are no midpoints, nothing to smooth
		return true;
	}

	// Smoothing: for each line segment, add points on its 1 / 4 lengths
	bool res = false;
	size_t Num = a_Src.size() - 2;  // this many intermediary points
	a_Dst.clear();
	a_Dst.reserve(Num * 2 + 2);
	cCaveDefPoints::const_iterator itr = a_Src.begin() + 1;
	const cCaveDefPoint & Source = a_Src.front();
	a_Dst.push_back(Source);
	int PrevX = Source.m_BlockX;
	int PrevY = Source.m_BlockY;
	int PrevZ = Source.m_BlockZ;
	int PrevR = Source.m_Radius;
	for (size_t i = 0; i <= Num; ++i, ++itr)
	{
		int dx = itr->m_BlockX - PrevX;
		int dy = itr->m_BlockY - PrevY;
		int dz = itr->m_BlockZ - PrevZ;
		if (abs(dx) + abs(dz) + abs(dy) < 6)
		{
			// Too short a segment to smooth-subdivide into quarters
			PrevX = itr->m_BlockX;
			PrevY = itr->m_BlockY;
			PrevZ = itr->m_BlockZ;
			PrevR = itr->m_Radius;
			continue;
		}
		int dr = itr->m_Radius - PrevR;
		int Rad1 = std::max(PrevR + 1 * dr / 4, 1);
		int Rad2 = std::max(PrevR + 3 * dr / 4, 1);
		a_Dst.push_back(cCaveDefPoint(PrevX + 1 * dx / 4, PrevY + 1 * dy / 4, PrevZ + 1 * dz / 4, Rad1));
		a_Dst.push_back(cCaveDefPoint(PrevX + 3 * dx / 4, PrevY + 3 * dy / 4, PrevZ + 3 * dz / 4, Rad2));
		PrevX = itr->m_BlockX;
		PrevY = itr->m_BlockY;
		PrevZ = itr->m_BlockZ;
		PrevR = itr->m_Radius;
		res = true;
	}
	a_Dst.push_back(a_Src.back());
	return res && (a_Src.size() < a_Dst.size());
}
コード例 #2
0
ファイル: Caves.cpp プロジェクト: ThuGie/MCServer
AString cCaveTunnel::ExportAsSVG(int a_Color, int a_OffsetX, int a_OffsetZ) const
{
	AString SVG;
	SVG.reserve(m_Points.size() * 20 + 200);
	AppendPrintf(SVG, "<path style=\"fill:none;stroke:#%06x;stroke-width:1px;\"\nd=\"", a_Color);
	char Prefix = 'M';  // The first point needs "M" prefix, all the others need "L"
	for (cCaveDefPoints::const_iterator itr = m_Points.begin(); itr != m_Points.end(); ++itr)
	{
		AppendPrintf(SVG, "%c %d, %d ", Prefix, a_OffsetX + itr->m_BlockX, a_OffsetZ + itr->m_BlockZ);
		Prefix = 'L';
	}
	SVG.append("\"/>\n");
	return SVG;
}
コード例 #3
0
ファイル: Caves.cpp プロジェクト: ThuGie/MCServer
void cCaveTunnel::Randomize(cNoise & a_Noise)
{
	// Repeat 4 times:
	for (int i = 0; i < 4; i++)
	{
		// For each already present point, insert a point in between it and its predecessor, shifted randomly.
		cCaveDefPoint & Point = m_Points.front();
		int PrevX = Point.m_BlockX;
		int PrevY = Point.m_BlockY;
		int PrevZ = Point.m_BlockZ;
		int PrevR = Point.m_Radius;
		cCaveDefPoints Pts;
		Pts.reserve(m_Points.size() * 2 + 1);
		Pts.push_back(Point);
		for (cCaveDefPoints::const_iterator itr = m_Points.begin() + 1, end = m_Points.end(); itr != end; ++itr)
		{
			int Random = a_Noise.IntNoise3DInt(PrevX, PrevY, PrevZ + i) / 11;
			int len = (PrevX - itr->m_BlockX) * (PrevX - itr->m_BlockX);
			len += (PrevY - itr->m_BlockY) * (PrevY - itr->m_BlockY);
			len += (PrevZ - itr->m_BlockZ) * (PrevZ - itr->m_BlockZ);
			len = 3 * static_cast<int>(sqrt(static_cast<double>(len))) / 4;
			int Rad = std::min(MAX_RADIUS, std::max(MIN_RADIUS, (PrevR + itr->m_Radius) / 2 + (Random % 3) - 1));
			Random /= 4;
			int x = (itr->m_BlockX + PrevX) / 2 + (Random % (len + 1) - len / 2);
			Random /= 256;
			int y = (itr->m_BlockY + PrevY) / 2 + (Random % (len / 2 + 1) - len / 4);
			Random /= 256;
			int z = (itr->m_BlockZ + PrevZ) / 2 + (Random % (len + 1) - len / 2);
			Pts.push_back(cCaveDefPoint(x, y, z, Rad));
			Pts.push_back(*itr);
			PrevX = itr->m_BlockX;
			PrevY = itr->m_BlockY;
			PrevZ = itr->m_BlockZ;
			PrevR = itr->m_Radius;
		}
		std::swap(Pts, m_Points);
	}
}