diff --git a/src/mcedit2/rendering/blockmodels.pxd b/src/mcedit2/rendering/blockmodels.pxd index 7358d9a..e6e5f2b 100644 --- a/src/mcedit2/rendering/blockmodels.pxd +++ b/src/mcedit2/rendering/blockmodels.pxd @@ -14,6 +14,9 @@ cdef struct ModelQuadList: int count ModelQuad *quads +cdef class ModelQuadListObj(object): + cdef ModelQuadList quadList + cdef class BlockModels: cdef object resourceLoader cdef object blocktypes @@ -25,6 +28,7 @@ cdef class BlockModels: cdef public object firstTextures cdef object cookedModels cdef ModelQuadList cookedModelsByID[4096][16] + cdef dict cookedModelsByBlockState cdef object cooked cdef object grassImage diff --git a/src/mcedit2/rendering/blockmodels.pyx b/src/mcedit2/rendering/blockmodels.pyx index 015876b..e363d08 100644 --- a/src/mcedit2/rendering/blockmodels.pyx +++ b/src/mcedit2/rendering/blockmodels.pyx @@ -39,6 +39,10 @@ cdef struct ModelQuadList: int count ModelQuad *quads +cdef class ModelQuadListObj(object): + pass # defined in blockmodels.pxd + + cdef class FaceInfo(object): cdef: float x1, y1, z1, x2, y2, z2 @@ -167,6 +171,7 @@ cdef class BlockModels(object): self.modelStateJsons = {} self.quadsByResourcePathVariant = {} self.blockStatesByResourcePathVariant = defaultdict(list) + self.cookedModelsByBlockState = {} self._texturePaths = set() self.firstTextures = {} # first texture found for each block - used for icons (xxx) @@ -246,6 +251,7 @@ cdef class BlockModels(object): log.debug("Model for variant %s#%s previously loaded", resourcePath, resourceVariant) continue + self.blockStatesByResourcePathVariant[resourcePath, resourceVariant].append(nameAndState) internalName, blockState = (nameAndState.split("[") + [""])[:2] # _splitInternalName block = blocktypes.get(internalName, None) if block is None: @@ -502,6 +508,7 @@ cdef class BlockModels(object): cdef unsigned char shade cdef ModelQuadList modelQuads cdef ModelQuadList unknownBlockModel + cdef ModelQuadListObj modelQuadsObj = None cdef list allQuads UNKNOWN_BLOCK = u'MCEDIT_UNKNOWN' @@ -615,6 +622,9 @@ cdef class BlockModels(object): try: ID, meta = self.blocktypes.IDsByState[nameAndState] except KeyError: + modelQuadsObj = ModelQuadListObj() + modelQuadsObj.quadList = modelQuads + self.cookedModelsByBlockState[nameAndState] = modelQuadsObj continue # xxx put models for hidden states where?? # cookedModels[nameAndState] = cookedQuads @@ -631,6 +641,7 @@ cdef class BlockModels(object): self.cookedModels = cookedModels self.cooked = True + # import pprint; pprint.pprint(dict(self.blockStatesByResourcePathVariant)); raise SystemExit self.cookFluidQuads() def cookFluidQuads(self): diff --git a/src/mcedit2/rendering/modelmesh.pyx b/src/mcedit2/rendering/modelmesh.pyx index fefe446..e1b8dfc 100644 --- a/src/mcedit2/rendering/modelmesh.pyx +++ b/src/mcedit2/rendering/modelmesh.pyx @@ -107,6 +107,9 @@ class BlockModelMesh(object): cdef unsigned short stoneSlab2ID = getID("minecraft:stone_slab2") cdef unsigned short woodenSlabID = getID("minecraft:wooden_slab") + cdef unsigned short grassID = getID("minecraft:grass") + cdef unsigned short snowID = getID("minecraft:snow") + cdef unsigned short snowLayerID = getID("minecraft:snow_layer") #cdef char fancyGraphics = self.sectionUpdate.fancyGraphics cdef char fancyGraphics = True @@ -157,6 +160,8 @@ class BlockModelMesh(object): cdef const unsigned char * tintColor cdef char doCull = 0 + cdef char foundActualState + cdef blockmodels.ModelQuadListObj quadListObj if vertexBuffer == NULL: return @@ -170,10 +175,31 @@ class BlockModelMesh(object): if ID == 0: continue meta = areaData[y, z, x] + foundActualState = 0 if renderType[ID] == 3: # model blocks - # xxx cookedModelsByBlockState - quads = blockModels.cookedModelsByID[ID][meta] + # if this block has actualStates, get its actualState + # using its neighbors and look up that state's models + # in blockModels.... ... ... + + # to get its actual state, we need to get its current state from + # its id and meta, parse the state into properties, + # change some property values into others according to + # actualState logic, cram them back into a blockState string, + # then use the new state to look up the model + # ... ... ... + # all without doing a dict lookup for every block... + # + if grassID and (ID == grassID): + if (areaBlocks[y+1, z, x] == snowID + or areaBlocks[y+1, z, x] == snowLayerID): + actualState = "minecraft:grass[snowy=true]" + quadListObj = blockModels.cookedModelsByBlockState[actualState] + quads = quadListObj.quadList + foundActualState = 1 + + if foundActualState == 0: + quads = blockModels.cookedModelsByID[ID][meta] if quads.count == 0: continue