Last active
August 29, 2015 14:26
-
-
Save WesleyE/050f8ae6b077c02e8fa9 to your computer and use it in GitHub Desktop.
Houdini Minecraft import (wip) Check http://scripts.wesleyelfring.nl/minecraft-import-script-for-houdini/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"""Houdini Import Script - Work In Progress | |
Check http://scripts.wesleyelfring.nl/minecraft-import-script-for-houdini/ | |
""" | |
import hou,os,sys | |
# Check for the required modules, we need pyyaml and pymclevel in the $JOB/scripts/ folder. | |
job = hou.expandString('$JOB') | |
sys.path.insert(0, os.path.join(job, "scripts", "pymclevel")) | |
sys.path.insert(0, os.path.join(job, "scripts")) | |
sys.path.insert(0, os.path.join(job, "scripts", "pyyaml", "lib")) | |
try: | |
import yaml | |
from pymclevel import mclevel,ChunkNotPresent,BoundingBox | |
except ImportError: | |
raise ImportError("Could not load the required modules. Please read the documentation about downloading MCLevel and PyYAML") | |
node = hou.pwd() | |
geo = node.geometry() | |
class HoudiniMinecraftImport: | |
# Block flags | |
TOP_BLOCKED = 0x01 | |
BOTTOM_BLOCKED = 0x02 | |
LEFT_BLOCKED = 0x04 | |
RIGHT_BLOCKED = 0x08 | |
FRONT_BLOCKED = 0x10 | |
BACK_BLOCKED = 0x20 | |
#Setup full cube | |
full_point_positions = [(0,0,0), (1,0,0), (1,1,0), (0,1,0), (0,0,1), (1,0,1), (1,1,1), (0,1,1)] | |
full_poly_point_indices = [(0,1,2), (2,3,0), (1,5,2), (5,6,2), (5,4,6), (4,7,6), (4,0,7), (0,3,7), (7,3,6), (3,2,6), (5,1,4), (1,0,4)] | |
def __init__(self): | |
self.geo = hou.pwd().geometry() | |
self.node = hou.pwd() | |
#Setup Attributes | |
self.blockIdAttrib = self.geo.addAttrib(hou.attribType.Prim, "blockId", -1) | |
self.blockTypeAttrib = self.geo.addAttrib(hou.attribType.Prim, "blockType", -1) | |
self.blockChunkAttrib = self.geo.addAttrib(hou.attribType.Prim, "blockChunk", -1) | |
self.loadedEntities = set() | |
self.LoadChunks() | |
def LoadChunks(self): | |
level = mclevel.fromFile(node.evalParm("world_folder")) | |
print level.playerSpawnPosition() | |
position = self.node.evalParmTuple("position") | |
size = self.node.evalParmTuple("size") | |
#Try to load the first chunk, if it fails, give a hint to the user | |
with hou.InterruptableOperation( | |
"Loading chunks", open_interrupt_dialog=True) as operation: | |
box = BoundingBox(position, size) | |
print box.origin | |
#hou.ui.displayMessage("Chunk count: " + str(box.chunkCount)) | |
id = 0 | |
for (chunk, slices, point) in level.getChunkSlices(box): | |
self.LoadChunk(chunk, point, id) | |
id = id + 1 | |
percent = float(id) / float(box.chunkCount) | |
operation.updateProgress(percent) | |
def LoadChunk(self, chunk, offset, id): | |
#To be able to cull the bottom and top | |
cullTopBottom = node.evalParmTuple("cull_top_bottom") | |
blocks = chunk.Blocks[:,:,cullTopBottom[0]:cullTopBottom[1]] #:,:,0:180 | |
#Loop over all the blocks, take note that the array is indexed x, z, y | |
x = 0 | |
z = 0 | |
y = 0 | |
for blocksX in blocks: | |
for blocksZ in blocksX: | |
for block in blocksZ: | |
#Check if air | |
if int(block) == 0: | |
y += 1 | |
continue | |
#Calculate the position of this block and check if we already loaded this one | |
#We need to do this since the slices may contain parts of chunks that are already loaded | |
newPos = (x + offset[0], y, z + offset[2]) | |
if newPos in self.loadedEntities: | |
y += 1 | |
continue | |
#Add the block to the loaded entities | |
self.loadedEntities.add(newPos) | |
bitflags = 0x00 | |
bitflags = self.checkNeighbourBlocks(blocks, x, z, y) | |
prims = self.BuildCube((x,z,y), bitflags) | |
for prim in prims: | |
prim.setAttribValue(self.blockTypeAttrib, int(block)) | |
prim.setAttribValue(self.blockChunkAttrib, int(id)) | |
prim.setAttribValue(self.blockIdAttrib, int(x * z * (y + 1))) | |
#self.geo.transformPrims(prims, hou.hmath.buildTranslate(x + offset[0], y, z + offset[2] + 3)) | |
self.geo.transformPrims(prims, hou.hmath.buildTranslate(x + offset[0], y, z + offset[2])) | |
y += 1 | |
y = 0 | |
z += 1 | |
z = 0 | |
x += 1 | |
def BuildCube(self, pos, blockedFlags): | |
#Copy the full box | |
point_positions = list(self.full_point_positions) | |
poly_point_indices = list(self.full_poly_point_indices) | |
if blockedFlags & HoudiniMinecraftImport.LEFT_BLOCKED: | |
#Draw left | |
poly_point_indices.remove((0,1,2)) | |
poly_point_indices.remove((2,3,0)) | |
if blockedFlags & HoudiniMinecraftImport.FRONT_BLOCKED: | |
#Remove front | |
poly_point_indices.remove((1,5,2)) | |
poly_point_indices.remove((5,6,2)) | |
if blockedFlags & HoudiniMinecraftImport.RIGHT_BLOCKED: | |
#Remove right | |
poly_point_indices.remove((5,4,6)) | |
poly_point_indices.remove((4,7,6)) | |
if blockedFlags & HoudiniMinecraftImport.BACK_BLOCKED: | |
#Remove back | |
poly_point_indices.remove((4,0,7)) | |
poly_point_indices.remove((0,3,7)) | |
if blockedFlags & HoudiniMinecraftImport.TOP_BLOCKED: | |
#Remove top | |
poly_point_indices.remove((7,3,6)) | |
poly_point_indices.remove((3,2,6)) | |
if blockedFlags & HoudiniMinecraftImport.BOTTOM_BLOCKED: | |
#Remove bottom | |
poly_point_indices.remove((5,1,4)) | |
poly_point_indices.remove((1,0,4)) | |
#Skip building the block if every side has been blocked | |
if len(poly_point_indices) == 0: | |
return [] | |
# Create all the points. | |
points = [] | |
for position in point_positions: | |
points.append(self.geo.createPoint()) | |
points[-1].setPosition(position) | |
#points[-1].setAttribValue("N", (0, 0, 0)) | |
# Create the polygons | |
cubePolys = [] | |
for point_indices in poly_point_indices: | |
poly = geo.createPolygon() | |
for point_index in point_indices: | |
poly.addVertex(points[point_index]) | |
cubePolys.append(poly) | |
return cubePolys | |
def checkNeighbourBlocks(self, blocks, x, z, y): | |
bitflags = 0b0000 | |
#Check if the top block has air | |
if y+1 < 255: | |
if blocks[x][z][y+1] != 0: | |
bitflags = bitflags | HoudiniMinecraftImport.TOP_BLOCKED | |
#Check bottom block has air | |
if y > 0: | |
if blocks[x][z][y-1] != 0: | |
bitflags = bitflags | HoudiniMinecraftImport.BOTTOM_BLOCKED | |
#Check left block has air | |
if x > 0: | |
if blocks[x-1][z][y] != 0: | |
bitflags = bitflags | HoudiniMinecraftImport.BACK_BLOCKED | |
#Check right block has air | |
if x < 15: | |
if blocks[x+1][z][y] != 0: | |
bitflags = bitflags | HoudiniMinecraftImport.FRONT_BLOCKED | |
#Check front block has air | |
if z < 15: | |
if blocks[x][z+1][y] != 0: | |
bitflags = bitflags | HoudiniMinecraftImport.RIGHT_BLOCKED | |
#Check back block has air | |
if z > 0: | |
if blocks[x][z-1][y] != 0: | |
bitflags = bitflags | HoudiniMinecraftImport.LEFT_BLOCKED | |
return bitflags | |
HoudiniMinecraftImport() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment