Render player models with textures
This commit is contained in:
parent
7bd6a0f022
commit
d790e40e5f
@ -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())
|
||||
|
79
src/mcedit2/rendering/chunkmeshes/entity/player.py
Normal file
79
src/mcedit2/rendering/chunkmeshes/entity/player.py
Normal 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,
|
||||
]
|
@ -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
|
||||
|
||||
|
136
src/mcedit2/rendering/players.py
Normal file
136
src/mcedit2/rendering/players.py
Normal 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)
|
@ -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
|
||||
|
Reference in New Issue
Block a user