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)
Beispiel #4
0
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))
Beispiel #6
0
    def setUp(self):
        super(OneChunkWorldChunkGeneratorTest, self).setUp()

        self.chunkGenerator = ChunkGenerator(4)
Beispiel #7
0
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)
Beispiel #8
0
    def testConstructor(self):
        chunkAxisLen = 4

        cg = ChunkGenerator(chunkAxisLen)
        self.assertEqual(chunkAxisLen, cg.chunkAxisLen)
Beispiel #9
0
    def setUp(self):
        super(MultipleChunksWorldChunkGeneratorTest, self).setUp()

        self.chunkGenerator = ChunkGenerator(6)
Beispiel #10
0
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))