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
|
ModelPigZombie
|
||||||
from mcedit2.rendering.chunkmeshes.entity.chest import ModelChest, ModelLargeChest
|
from mcedit2.rendering.chunkmeshes.entity.chest import ModelChest, ModelLargeChest
|
||||||
from mcedit2.rendering.chunkmeshes.entity.creeper import ModelCreeper
|
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, \
|
from mcedit2.rendering.chunkmeshes.entity.quadruped import ModelPig, ModelCow, ModelSheep, \
|
||||||
ModelSheepWool
|
ModelSheepWool
|
||||||
from mcedit2.rendering.chunkmeshes.entity.shulker import ModelShulker
|
from mcedit2.rendering.chunkmeshes.entity.shulker import ModelShulker
|
||||||
@ -168,6 +169,7 @@ def getTexture(entityID):
|
|||||||
model = models.get(entityID)
|
model = models.get(entityID)
|
||||||
return model.modelTexture
|
return model.modelTexture
|
||||||
|
|
||||||
|
addModel(ModelPlayer())
|
||||||
addModel(ModelCreeper())
|
addModel(ModelCreeper())
|
||||||
addModel(ModelZombie())
|
addModel(ModelZombie())
|
||||||
addModel(ModelSkeleton())
|
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 = numpy.array(model.vertices)
|
||||||
modelVerts.shape = modelVerts.shape[0]//4, 4, modelVerts.shape[1]
|
modelVerts.shape = modelVerts.shape[0]//4, 4, modelVerts.shape[1]
|
||||||
# scale down
|
# scale down
|
||||||
@ -404,20 +404,26 @@ def entityModelNode(ref, model, modelTex, chunk):
|
|||||||
modelVerts[..., 1] = -modelVerts[..., 1] + 1.5 + 1/64.
|
modelVerts[..., 1] = -modelVerts[..., 1] + 1.5 + 1/64.
|
||||||
modelVerts[..., 0] = -modelVerts[..., 0]
|
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]
|
vertexBuffer.vertex[:] = modelVerts[..., :3]
|
||||||
vertexBuffer.texcoord[:] = modelVerts[..., 3:5]
|
if modelTex is not None:
|
||||||
|
vertexBuffer.texcoord[:] = modelVerts[..., 3:5]
|
||||||
|
|
||||||
node = VertexNode([vertexBuffer])
|
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.))
|
rotate = Rotate(ref.Rotation[0], (0., 1., 0.))
|
||||||
node.addState(rotate)
|
node.addState(rotate)
|
||||||
|
|
||||||
translate = Translate((ref.Position - (chunk.cx << 4, 0, chunk.cz << 4)))
|
if modelTex is not None:
|
||||||
node.addState(translate)
|
bindTexture = BindTexture(modelTex, (1./model.texWidth, 1./model.texHeight * (-1 if flip else 1), 1))
|
||||||
|
node.addState(bindTexture)
|
||||||
bindTexture = BindTexture(modelTex, (1./model.texWidth, 1./model.texHeight, 1))
|
|
||||||
node.addState(bindTexture)
|
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
||||||
@ -501,6 +507,7 @@ def chestEntityModelNode(ref, model, modelTex, chunk, facing, largeX, largeZ):
|
|||||||
node.addState(bindTexture)
|
node.addState(bindTexture)
|
||||||
return node
|
return node
|
||||||
|
|
||||||
|
|
||||||
class TileEntityModelRenderer(ChunkMeshBase):
|
class TileEntityModelRenderer(ChunkMeshBase):
|
||||||
layer = Layer.TileEntities
|
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.layers import Layer
|
||||||
from mcedit2.rendering import chunkupdate
|
from mcedit2.rendering import chunkupdate
|
||||||
|
from mcedit2.rendering.players import PlayersNode
|
||||||
from mcedit2.rendering.scenegraph import scenenode
|
from mcedit2.rendering.scenegraph import scenenode
|
||||||
from mcedit2.rendering import renderstates
|
from mcedit2.rendering import renderstates
|
||||||
from mcedit2.rendering.chunknode import ChunkNode, ChunkGroupNode
|
from mcedit2.rendering.chunknode import ChunkNode, ChunkGroupNode
|
||||||
@ -229,6 +230,9 @@ class WorldScene(scenenode.Node):
|
|||||||
self.minlod = 0
|
self.minlod = 0
|
||||||
self.bounds = bounds
|
self.bounds = bounds
|
||||||
|
|
||||||
|
self.playersNode = PlayersNode(dimension)
|
||||||
|
self.addChild(self.playersNode)
|
||||||
|
|
||||||
def setTextureAtlas(self, textureAtlas):
|
def setTextureAtlas(self, textureAtlas):
|
||||||
if textureAtlas is not self.textureAtlas:
|
if textureAtlas is not self.textureAtlas:
|
||||||
self.textureAtlas = textureAtlas
|
self.textureAtlas = textureAtlas
|
||||||
|
Reference in New Issue
Block a user