Render player models with textures

This commit is contained in:
David Vierra 2016-06-07 13:26:00 -10:00
parent 7bd6a0f022
commit d790e40e5f
5 changed files with 236 additions and 8 deletions

View File

@ -11,6 +11,7 @@ from mcedit2.rendering.chunkmeshes.entity.biped import ModelZombie, ModelSkeleto
ModelPigZombie
from mcedit2.rendering.chunkmeshes.entity.chest import ModelChest, ModelLargeChest
from mcedit2.rendering.chunkmeshes.entity.creeper import ModelCreeper
from mcedit2.rendering.chunkmeshes.entity.player import ModelPlayer
from mcedit2.rendering.chunkmeshes.entity.quadruped import ModelPig, ModelCow, ModelSheep, \
ModelSheepWool
from mcedit2.rendering.chunkmeshes.entity.shulker import ModelShulker
@ -168,6 +169,7 @@ def getTexture(entityID):
model = models.get(entityID)
return model.modelTexture
addModel(ModelPlayer())
addModel(ModelCreeper())
addModel(ModelZombie())
addModel(ModelSkeleton())

View File

@ -0,0 +1,79 @@
"""
player
"""
from __future__ import absolute_import, division, print_function, unicode_literals
import logging
from mcedit2.rendering.chunkmeshes.entity.biped import ModelBiped
from mcedit2.rendering.chunkmeshes.entity.modelrenderer import ModelRenderer
log = logging.getLogger(__name__)
class ModelPlayer(ModelBiped):
id = "MCEDIT_Player"
textureWidth = 64
textureHeight = 64
def __init__(self, expandOffset=0.0, headOffset=0.0, smallArms=False):
super(ModelPlayer, self).__init__(expandOffset, headOffset)
self.smallArms = smallArms
self.bipedCape = ModelRenderer(self, 0, 0)
# self.bipedCape.setTextureSize(64, 32)
self.bipedCape.addBox(-5.0, 0.0, -1.0, 10, 16, 1, expandOffset)
if smallArms:
self.bipedLeftArm = ModelRenderer(self, 32, 48)
self.bipedLeftArm.addBox(-1.0, -2.0, -2.0, 3, 12, 4, expandOffset)
self.bipedLeftArm.setCenterPoint(5.0, 2.5, 0.0)
self.bipedRightArm = ModelRenderer(self, 40, 16)
self.bipedRightArm.addBox(-2.0, -2.0, -2.0, 3, 12, 4, expandOffset)
self.bipedRightArm.setCenterPoint(-5.0, 2.5, 0.0)
self.bipedLeftArmwear = ModelRenderer(self, 48, 48)
self.bipedLeftArmwear.addBox(-1.0, -2.0, -2.0, 3, 12, 4, expandOffset + 0.25)
self.bipedLeftArmwear.setCenterPoint(5.0, 2.5, 0.0)
self.bipedRightArmwear = ModelRenderer(self, 40, 32)
self.bipedRightArmwear.addBox(-2.0, -2.0, -2.0, 3, 12, 4, expandOffset + 0.25)
self.bipedRightArmwear.setCenterPoint(-5.0, 2.5, 10.0)
else:
self.bipedLeftArm = ModelRenderer(self, 32, 48)
self.bipedLeftArm.addBox(-1.0, -2.0, -2.0, 4, 12, 4, expandOffset)
self.bipedLeftArm.setCenterPoint(5.0, 2.0, 0.0)
self.bipedLeftArmwear = ModelRenderer(self, 48, 48)
self.bipedLeftArmwear.addBox(-1.0, -2.0, -2.0, 4, 12, 4, expandOffset + 0.25)
self.bipedLeftArmwear.setCenterPoint(5.0, 2.0, 0.0)
self.bipedRightArmwear = ModelRenderer(self, 40, 32)
self.bipedRightArmwear.addBox(-3.0, -2.0, -2.0, 4, 12, 4, expandOffset + 0.25)
self.bipedRightArmwear.setCenterPoint(-5.0, 2.0, 10.0)
self.bipedLeftLeg = ModelRenderer(self, 16, 48)
self.bipedLeftLeg.addBox(-2.0, 0.0, -2.0, 4, 12, 4, expandOffset)
self.bipedLeftLeg.setCenterPoint(1.9, 12.0, 0.0)
self.bipedLeftLegwear = ModelRenderer(self, 0, 48)
self.bipedLeftLegwear.addBox(-2.0, 0.0, -2.0, 4, 12, 4, expandOffset + 0.25)
self.bipedLeftLegwear.setCenterPoint(1.9, 12.0, 0.0)
self.bipedRightLegwear = ModelRenderer(self, 0, 32)
self.bipedRightLegwear.addBox(-2.0, 0.0, -2.0, 4, 12, 4, expandOffset + 0.25)
self.bipedRightLegwear.setCenterPoint(-1.9, 12.0, 0.0)
self.bipedBodyWear = ModelRenderer(self, 16, 32)
self.bipedBodyWear.addBox(-4.0, 0.0, -2.0, 8, 12, 4, expandOffset + 0.25)
self.bipedBodyWear.setCenterPoint(0.0, 0.0, 0.0)
@property
def parts(self):
return [
self.bipedHead,
self.bipedHeadwear,
self.bipedBody,
self.bipedBodyWear,
self.bipedRightArm,
self.bipedRightArmwear,
self.bipedLeftArm,
self.bipedLeftArmwear,
self.bipedRightLeg,
self.bipedRightLegwear,
self.bipedLeftLeg,
self.bipedLeftLegwear,
]

View File

@ -396,7 +396,7 @@ class ItemFrameMesh(EntityMeshBase):
}
def entityModelNode(ref, model, modelTex, chunk):
def entityModelNode(ref, model, modelTex=None, chunk=None, flip=False):
modelVerts = numpy.array(model.vertices)
modelVerts.shape = modelVerts.shape[0]//4, 4, modelVerts.shape[1]
# scale down
@ -404,19 +404,25 @@ def entityModelNode(ref, model, modelTex, chunk):
modelVerts[..., 1] = -modelVerts[..., 1] + 1.5 + 1/64.
modelVerts[..., 0] = -modelVerts[..., 0]
vertexBuffer = QuadVertexArrayBuffer(len(modelVerts), lights=False, textures=True)
vertexBuffer = QuadVertexArrayBuffer(len(modelVerts), lights=False, textures=modelTex is not None)
vertexBuffer.vertex[:] = modelVerts[..., :3]
if modelTex is not None:
vertexBuffer.texcoord[:] = modelVerts[..., 3:5]
node = VertexNode([vertexBuffer])
pos = ref.Position
if chunk is not None:
pos = pos - (chunk.cx << 4, 0, chunk.cz << 4)
translate = Translate(pos)
node.addState(translate)
rotate = Rotate(ref.Rotation[0], (0., 1., 0.))
node.addState(rotate)
translate = Translate((ref.Position - (chunk.cx << 4, 0, chunk.cz << 4)))
node.addState(translate)
bindTexture = BindTexture(modelTex, (1./model.texWidth, 1./model.texHeight, 1))
if modelTex is not None:
bindTexture = BindTexture(modelTex, (1./model.texWidth, 1./model.texHeight * (-1 if flip else 1), 1))
node.addState(bindTexture)
return node
@ -501,6 +507,7 @@ def chestEntityModelNode(ref, model, modelTex, chunk, facing, largeX, largeZ):
node.addState(bindTexture)
return node
class TileEntityModelRenderer(ChunkMeshBase):
layer = Layer.TileEntities

View File

@ -0,0 +1,136 @@
"""
playermesh
"""
from __future__ import absolute_import, division, print_function, unicode_literals
import logging
import os
import numpy
from OpenGL import GL
from mcedit2.rendering.chunkmeshes.entity.models import cookedModels
from mcedit2.rendering.chunkmeshes.entitymesh import entityModelNode
from mcedit2.rendering.scenegraph.misc import Enable
from mcedit2.rendering.scenegraph.scenenode import Node
from mcedit2.util import glutils
from mcedit2.util.load_png import loadPNGTexture, loadPNGFile
from mcedit2.util.player_server import PlayerDataCache
log = logging.getLogger(__name__)
class PlayerNode(Node):
def __init__(self, playerRef):
super(PlayerNode, self).__init__()
self.playerRef = playerRef
self.entityNode = None
def _callback(result, error):
if result:
self.texturePath = result['texturePath']
else:
self.texturePath = None
if error:
log.info("Error getting player info: %s", error)
PlayerDataCache.getPlayerInfo(playerRef.UUID, _callback)
_texturePath = None
@property
def texturePath(self):
return self._texturePath
@texturePath.setter
def texturePath(self, value):
self._texturePath = value
if value is not None:
log.info("Got texture path: %s", value)
w, h, modelImage = loadPNGFile(value)
# modelTex = loadPNGTexture(value)
if h == 32:
w, h, modelImage = fixupTextureImage(modelImage)
tex = glutils.Texture(name=os.path.basename(value), image=modelImage.ravel(),
width=w, height=h)
if self.entityNode:
self.removeChild(self.entityNode)
self.entityNode = entityModelNode(self.playerRef, cookedModels['MCEDIT_Player'], tex)
self.entityNode.addState(Enable(GL.GL_ALPHA_TEST))
self.addChild(self.entityNode)
else:
log.info("Did not get texture path.")
def fixupTextureImage(modelImage):
w = 64
h = 64
oh, ow, b = modelImage.shape
newImage = numpy.zeros((h, w, b), dtype='uint8')
newImage[:oh, :ow, :] = modelImage[::-1]
#newImage = newImage[::-1, :, :]
def drawImage(x1, y1, x2, y2, sx1, sy1, sx2, sy2):
def _slice(a, b):
if a > b:
return slice(a-1, b-1, -1)
else:
return slice(a, b)
newImage[_slice(y1, y2), _slice(x1, x2)] = newImage[_slice(sy1, sy2), _slice(sx1, sx2)]
drawImage(24, 48, 20, 52, 4, 16, 8, 20)
drawImage(28, 48, 24, 52, 8, 16, 12, 20)
drawImage(20, 52, 16, 64, 8, 20, 12, 32)
drawImage(24, 52, 20, 64, 4, 20, 8, 32)
drawImage(28, 52, 24, 64, 0, 20, 4, 32)
drawImage(32, 52, 28, 64, 12, 20, 16, 32)
drawImage(40, 48, 36, 52, 44, 16, 48, 20)
drawImage(44, 48, 40, 52, 48, 16, 52, 20)
drawImage(36, 52, 32, 64, 48, 20, 52, 32)
drawImage(40, 52, 36, 64, 44, 20, 48, 32)
drawImage(44, 52, 40, 64, 40, 20, 44, 32)
drawImage(48, 52, 44, 64, 52, 20, 56, 32)
#newImage = newImage[::-1, :, :]
# }
#
# graphics.dispose();
# this.imageData = ((DataBufferInt)bufferedimage.getRaster().getDataBuffer()).getData();
# this.setAreaOpaque(0, 0, 32, 16);
# this.setAreaTransparent(32, 0, 64, 32);
# this.setAreaOpaque(0, 16, 64, 32);
# this.setAreaTransparent(0, 32, 16, 48);
# this.setAreaTransparent(16, 32, 40, 48);
# this.setAreaTransparent(40, 32, 56, 48);
# this.setAreaTransparent(0, 48, 16, 64);
# this.setAreaOpaque(16, 48, 48, 64);
# this.setAreaTransparent(48, 48, 64, 64);
# return bufferedimage;
return w, h, newImage
class PlayersNode(Node):
def __init__(self, dimension):
"""
Parameters
----------
dimension : mceditlib.worldeditor.WorldEditorDimension
"""
super(PlayersNode, self).__init__()
playerNodes = []
if not hasattr(dimension, 'worldEditor'):
# gross, dimension may be a MaskLevel
return
for playerName in dimension.worldEditor.listPlayers():
player = dimension.worldEditor.getPlayer(playerName)
if player.Dimension == dimension.dimNo:
playerNodes.append(PlayerNode(player))
for node in playerNodes:
self.addChild(node)

View File

@ -11,6 +11,7 @@ import numpy
from mcedit2.rendering.layers import Layer
from mcedit2.rendering import chunkupdate
from mcedit2.rendering.players import PlayersNode
from mcedit2.rendering.scenegraph import scenenode
from mcedit2.rendering import renderstates
from mcedit2.rendering.chunknode import ChunkNode, ChunkGroupNode
@ -229,6 +230,9 @@ class WorldScene(scenenode.Node):
self.minlod = 0
self.bounds = bounds
self.playersNode = PlayersNode(dimension)
self.addChild(self.playersNode)
def setTextureAtlas(self, textureAtlas):
if textureAtlas is not self.textureAtlas:
self.textureAtlas = textureAtlas