jsuarez/extra/embyr_deprecated/embyr/embyr3D.py (201 lines of code) (raw):
from pdb import set_trace as T
import numpy as np
import time
from scipy.misc import imresize, imsave
from enum import Enum
import pygame
from pygame import Surface
from forge.embyr import embyr
from forge.embyr import utils as renderutils
from forge.embyr import render
from forge.embyr.texture import TextureInitializer
from forge.blade.lib.enums import Neon, Color256, Defaults
from forge.blade.action.v2 import Attack
from forge.blade.action import action
from pdb import set_trace as T
import numpy as np
import os
import kivy3
from kivy.app import App
from kivy3 import Scene, Renderer, PerspectiveCamera
from kivy3.loaders import OBJMTLLoader
from kivy.uix.floatlayout import FloatLayout
from kivy.uix.widget import Widget as KivyWidget
from kivy.config import Config
from kivy.graphics import opengl as gl
from kivy.graphics import Mesh as KivyMesh
from kivy3.core.object3d import Object3D
from kivy3.materials import Material
from kivy.core.image import Image
from copy import deepcopy
from forge.embyr.embyr import Application as KivyApp
import pywavefront as pywave
import pytmx
from forge.blade.lib import enums
from forge.embyr.transform import Transform
root = 'forge/embyr/'
Config.set('input', 'mouse', 'mouse,multitouch_on_demand')
shaderf = 'tex/default.glsl'
pi = 3.14159265
NANIM = 4
class MaterialMesh(Object3D):
def __init__(self, mesh, material):
super().__init__()
self._mesh = mesh
self.material = material
self.mtl = material
self.bind(pos = self.update_pos)
self.material.diffuse = material.diffuse[:3]
self.material.specular = material.specular[:3]
self.material.shininess = material.shininess
def retexturef(self, texf):
tex = Image(texf).texture
self.retexture(self, tex)
def retexture(self, tex):
self._mesh.texture = tex
def update_pos(self, x, y, z):
self.pos.x = float(x)
self.pos.y = float(y)
self.pos.z = float(z)
def custom_instructions(self):
yield self.material
yield self._mesh
class OBJ(MaterialMesh):
def __init__(self, objs):
super(MaterialMesh, self).__init__()
for _, obj in objs.items():
mesh, mat = obj
matmesh = MaterialMesh(mesh, mat)
self.add(matmesh)
def custom_instructions(self):
for child in self.children:
for instr in child.custom_instructions():
yield instr
class Block(MaterialMesh):
def __init__(self, tile):
objs = OBJLoader.loadRaw(root+'block.obj',
root+'tex/'+tile+'.png')['Cube']
super().__init__(*objs)
self.block(tile)
def block(self, tile):
if tile == 'lava':
self.pos.y = -0.5
elif tile == 'stone':
self.pos.y = 1
elif tile == 'water':
self.pos.y = -0.33
class Ent(OBJ):
def __init__(self):
objs = OBJLoader.loadRaw(root+'tex/nn.obj')
super().__init__(objs)
class Map:
def __init__(self, scene, path='resource/maps/map1/map.tmx'):
tiled = self.loadTiled(path)
self.blocks = self.load(tiled, scene)
def load(self, tiles, scene, border=8):
blocks, self.shape = {}, tiles.shape
self.R, self.C = tiles.shape
for i in range(border, self.R-border):
for j in range(border, self.C-border):
tile = tiles[i, j]
#Load unit cube
block = Block(tile)
scene.add(block)
blocks[(i, j)] = block
#NEVER set .pos directly.
#It won't do anything
block.pos.x = i
block.pos.z = j
block.x0 = block.pos.x
block.y0 = block.pos.y
block.z0 = block.pos.z
return blocks
def loadTiled(self, fPath):
import pytmx
tm = pytmx.TiledMap(fPath)
assert len(tm.layers) == 1
layer = tm.layers[0]
W, H = layer.width, layer.height
tilemap = np.zeros((H, W), dtype=object)
for w, h, dat in layer.tiles():
f = dat[0]
tex = f.split('/')[-1].split('.')[0]
tilemap[h, w] = tex
return tilemap
class OBJLoader:
def formats(name):
if name == 'T2F_N3F_V3F':
return [
(b'v_tc0', 2, 'float'),
(b'v_normal', 3, 'float'),
(b'v_pos', 3, 'float')]
elif name == 'N3F_V3F':
return [
(b'v_normal', 3, 'float'),
(b'v_pos', 3, 'float')]
def load(objf, texf=None):
raw = OBJLoader.loadRaw(objf, texf)
return OBJ(raw)
def loadRaw(objf, texf=None):
rets, obj = {}, pywave.Wavefront(objf, collect_faces=True)
for name, mesh in obj.meshes.items():
rets[name] = OBJLoader.loadSingle(mesh, texf)
return rets
def loadSingle(obj, texf=None):
assert len(obj.materials) == 1
material = obj.materials[0]
if texf is None:
texf = material.texture.image_name
tex = Image(texf).texture
vertices = material.vertices
nVertex = len(vertices) / material.vertex_size
indices = np.arange(nVertex).astype(int).tolist()
fmt = OBJLoader.formats(material.vertex_format)
kw = {"vertices": vertices, "indices": indices,
"fmt": fmt,
"mode": "triangles",
'texture':tex
}
mesh = KivyMesh(**kw)
mat = Material(tex)
return mesh, mat
class Widget(KivyWidget):
def __init__(self, root, pos=(0, 0), size=(1, 1)):
super().__init__()
self.root = root
w, h = pos
self.pos_hint = {'left':w, 'top':h}
self.size_hint = size
class RS(Widget):
def __init__(self, root, **kwargs):
super().__init__(root)
self.path = 'forge/embyr/'
self.glSetup()
self.camera = PerspectiveCamera(30, 1, 10, 1000)
#self.transform = Transform()
self.transform = Transform(
pos=[8, 20, 8], lookvec=[40, 10, 40])
pos = kwargs.pop('pos', None)
size = kwargs.pop('size', None)
#pos_hint = {'right':ww, 'bottom':hh}
self.renderer = Renderer(shader_file=self.path+shaderf)
#self.renderer.pos_hint = pos_hint
self.scene = Scene()
#self.renderer.size_hint = (0.5, 0.5)
self.transform.size = (0, 0)
self.transform.size_hint = (0, 0)
self.renderer.render(self.scene, self.camera)
self.renderer.bind(size=self._adjust_aspect)
self.renderer.size_hint = size
self.renderer.pos = pos
#self.renderer.pos = (256, 256)
self.root.add_widget(self.renderer)
self.root.add_widget(self.transform)
#self._disabled_count = 0
#self.add_widget(self.renderer)
#self.add_widget(self.transform)
def glSetup(self):
gl.glEnable(gl.GL_CULL_FACE)
gl.glCullFace(gl.GL_BACK)
def add(self, obj):
self.scene.add(obj)
self.renderer.add(obj)
def update(self, dt):
pos, vec = self.transform.update(dt)
self.renderer.camera.look_at(vec)
x, y, z = pos
self.renderer.camera.pos = (-x, -y, -z)
return vec
def _adjust_aspect(self, inst, val):
rsize = self.renderer.size
aspect = rsize[0] / float(rsize[1])
self.renderer.camera.aspect = aspect