def setUp(self): super(OneChunkWorldChunkGeneratorTest, self).setUp() self.chunkGenerator = ChunkGenerator(4)
def setUp(self): super(MultipleChunksWorldChunkGeneratorTest, self).setUp() self.chunkGenerator = ChunkGenerator(6)
class OneChunkWorldChunkGeneratorTest(AbstractChunkGeneratorTest): def setUp(self): super(OneChunkWorldChunkGeneratorTest, self).setUp() self.chunkGenerator = ChunkGenerator(4) def _generateChunks(self, world): chunks = self.chunkGenerator.generateChunks(world, ((0, 0, 0), (self.chunkGenerator.chunkAxisLen, self.chunkGenerator.chunkAxisLen, self.chunkGenerator.chunkAxisLen))) return self._mapChunksToBlockIds(chunks) def testOneChunkForSmallWorld(self): stoneBlockId = 1 stoneBlockPos = [ (0, 0, 0), (self.chunkGenerator.chunkAxisLen - 1, self.chunkGenerator.chunkAxisLen - 1, self.chunkGenerator.chunkAxisLen - 1) ] world = WorldMock() world.append([(stoneBlockId, pos) for pos in stoneBlockPos]) chunks = self._generateChunks(world) self.assertEqual(1, len(chunks)) self.assertTrue(stoneBlockId in chunks) chunk = chunks[stoneBlockId] self.assertEqual(0, len(chunk.chunks)) self.assertEqual(2, len(chunk.blocks)) for pos in stoneBlockPos: self.assertTrue(pos in chunk.blocks) def _validateChunk(self, chunks, expectedBlockId, expectedBlockPos): self.assertTrue(expectedBlockId in chunks) chunk = chunks[expectedBlockId] self.assertEqual(0, len(chunk.chunks)) self.assertEqual(1, len(chunk.blocks)) self.assertEqual(expectedBlockPos, chunk.blocks[0]) def testMultipleBlockTypesChunksForSmallWorld(self): stoneBlockId = 1 stoneBlockPos = (1, 1, 1) grassBlockId = 2 grassBlockPos = (0, 1, 2) world = WorldMock() world.append([(stoneBlockId, stoneBlockPos), (grassBlockId, grassBlockPos)]) chunks = self._generateChunks(world) self.assertEqual(2, len(chunks)) self._validateChunk(chunks, stoneBlockId, stoneBlockPos) self._validateChunk(chunks, grassBlockId, grassBlockPos)
def render(f, world, extents = None): if extents is None: actualExtents = world.extents else: actualExtents = extents blockDefs = getMinecraftBlocksById() def getBlockDef(blockId): if blockId in blockDefs: return blockDefs[blockId] else: return BlockDef(blockId, 'Default') def getCombineOperator(blockDef): if blockDef.transparent: return 'merge' else: return 'union' def writeBoundedBy(chunk): # for the question: why do we generate bounding boxes? # # from the povray documentation: 'Unbounded unions are always split # into their component parts so that automatic bounding works better.' # # http://www.povray.org/documentation/view/3.6.1/223/#s02_01_02_08_03 cExtents = chunk.extents if cExtents is None: return # TODO use sphere bounding when we got cubic shapes # i guess spheres are faster than boxes? f.write('bounded_by { box { <%s, %s, %s>, <%s, %s, %s> } } \n' % (-cExtents[1][0] + 1, cExtents[0][1], cExtents[0][2], -cExtents[0][0] + 1, cExtents[1][1], cExtents[1][2])) def writeChunk(chunk, combineOperator, blockId): # write chunk subchunks for subChunk in chunk.chunks: chunksLen = len(subChunk.chunks) blocksLen = len(subChunk.blocks) if chunksLen == 0 and blocksLen == 0: continue requireBlock = not ((chunksLen == 0 and blocksLen == 1) or (chunksLen == 1 and blocksLen == 0)) if requireBlock: f.write('%s {\n' % combineOperator) writeChunk(subChunk, combineOperator, blockId) if requireBlock: writeBoundedBy(subChunk) f.write('}\n') # write chunk blocks for blockPos in chunk.blocks: f.write('object{ Block%sObject translate <%s, %s, %s>}\n' % (blockId, -blockPos[0], blockPos[1], blockPos[2])) for blockId, chunk in ChunkGenerator(6).generateChunks(world, actualExtents): blockDef = getBlockDef(blockId) combineOperator = getCombineOperator(blockDef) f.write('// Block%s\n' % blockId) f.write('%s {\n' % combineOperator) writeChunk(chunk, combineOperator, blockId) writeBoundedBy(chunk) f.write('\tmaterial { Block%sMaterial }\n' % blockId) f.write('}\n')
class MultipleChunksWorldChunkGeneratorTest(AbstractChunkGeneratorTest): def setUp(self): super(MultipleChunksWorldChunkGeneratorTest, self).setUp() self.chunkGenerator = ChunkGenerator(6) def _generateChunks(self, world): chunks = self.chunkGenerator.generateChunks(world, ((0, 0, 0), (12, 12, 12))) return self._mapChunksToBlockIds(chunks) def _createWorld(self, blockId, blockPos): world = WorldMock() world.append([(blockId, p) for p in blockPos]) return world def _createChunk(self, blockId, blockPos): world = self._createWorld(blockId, blockPos) chunks = self._generateChunks(world) self.assertTrue(1, len(chunks)) self.assertTrue(blockId in chunks) return chunks[blockId] def _isBlockPosInChunk(self, chunk, blockPos): for b in chunk.blocks: if b == blockPos: return True return False def _validateBlockPosInChunk(self, chunk, blockPos): chunkBlockPos = set() for c in chunk.chunks: self.assertEqual([], c.chunks) blocks = c.blocks self.assertEqual(1, len(blocks)) for b in blocks: chunkBlockPos.add(b) for bp in blockPos: self.assertTrue(bp in chunkBlockPos) def testCubicChunkDistribution(self): blockId = 1 blockPos = [(0, 0, 0), (8, 8, 8)] chunk = self._createChunk(blockId, blockPos) self.assertEqual([], chunk.blocks) self.assertEqual(2, len(chunk.chunks)) self._validateBlockPosInChunk(chunk, blockPos) def testNonCubicChunkDistribution(self): blockId = 1 blockPos = [(0, 0, 0), (8, 0, 8)] chunk = self._createChunk(blockId, blockPos) self.assertEqual([], chunk.blocks) self.assertEqual(2, len(chunk.chunks)) self._validateBlockPosInChunk(chunk, blockPos) def _isCenterBlockRemaining(self, blockDef): # this is something like a '3D cross' blockPos = [(1, 0, 1), (0, 1, 1), (1, 1, 0), (2, 1, 1), (1, 1, 2), (1, 2, 1), (1, 1, 1)] chunk = self._createChunk(blockDef.id, blockPos) # i admit... right now i don't really know why this is necessary # maybe it's a bug? chunk = chunk.chunks[0] return self._isBlockPosInChunk(chunk, (1, 1, 1)) def testDropBlocksWhichAreSurroundedBySolidBlocks(self): blockDef = getBlockByName('Stone') # make sure our block got the expected attributes self.assertTrue(blockDef.cube) self.assertFalse(blockDef.transparent) self.assertFalse(blockDef.invisible) self.assertFalse(self._isCenterBlockRemaining(blockDef)) def testRemainBlocksWhichAreSurroundedByTransparentBlocks(self): blockDef = getBlockByName('Water') # make sure our block got the expected attributes self.assertTrue(blockDef.cube) self.assertTrue(blockDef.transparent) self.assertFalse(blockDef.invisible) self.assertTrue(self._isCenterBlockRemaining(blockDef))
class OneChunkWorldChunkGeneratorTest(AbstractChunkGeneratorTest): def setUp(self): super(OneChunkWorldChunkGeneratorTest, self).setUp() self.chunkGenerator = ChunkGenerator(4) def _generateChunks(self, world): chunks = self.chunkGenerator.generateChunks( world, ((0, 0, 0), (self.chunkGenerator.chunkAxisLen, self.chunkGenerator.chunkAxisLen, self.chunkGenerator.chunkAxisLen))) return self._mapChunksToBlockIds(chunks) def testOneChunkForSmallWorld(self): stoneBlockId = 1 stoneBlockPos = [(0, 0, 0), (self.chunkGenerator.chunkAxisLen - 1, self.chunkGenerator.chunkAxisLen - 1, self.chunkGenerator.chunkAxisLen - 1)] world = WorldMock() world.append([(stoneBlockId, pos) for pos in stoneBlockPos]) chunks = self._generateChunks(world) self.assertEqual(1, len(chunks)) self.assertTrue(stoneBlockId in chunks) chunk = chunks[stoneBlockId] self.assertEqual(0, len(chunk.chunks)) self.assertEqual(2, len(chunk.blocks)) for pos in stoneBlockPos: self.assertTrue(pos in chunk.blocks) def _validateChunk(self, chunks, expectedBlockId, expectedBlockPos): self.assertTrue(expectedBlockId in chunks) chunk = chunks[expectedBlockId] self.assertEqual(0, len(chunk.chunks)) self.assertEqual(1, len(chunk.blocks)) self.assertEqual(expectedBlockPos, chunk.blocks[0]) def testMultipleBlockTypesChunksForSmallWorld(self): stoneBlockId = 1 stoneBlockPos = (1, 1, 1) grassBlockId = 2 grassBlockPos = (0, 1, 2) world = WorldMock() world.append([(stoneBlockId, stoneBlockPos), (grassBlockId, grassBlockPos)]) chunks = self._generateChunks(world) self.assertEqual(2, len(chunks)) self._validateChunk(chunks, stoneBlockId, stoneBlockPos) self._validateChunk(chunks, grassBlockId, grassBlockPos)
def testConstructor(self): chunkAxisLen = 4 cg = ChunkGenerator(chunkAxisLen) self.assertEqual(chunkAxisLen, cg.chunkAxisLen)