Refactoring

This commit is contained in:
Lubos Lenco 2015-10-31 00:30:36 +01:00
parent cc727d900e
commit 0e1695151e
7 changed files with 333 additions and 833 deletions

View file

@ -1,194 +0,0 @@
import shutil
import bpy
import os
import json
from bpy.types import Menu, Panel, UIList
from bpy.props import *
class ListItem(bpy.types.PropertyGroup):
# Group of properties representing an item in the list
name = bpy.props.StringProperty(
name="Name",
description="A name for this item",
default="Untitled")
enabled_prop = bpy.props.BoolProperty(
name="",
description="A name for this item",
default=True)
type_prop = bpy.props.EnumProperty(
items = [('Image', 'Image', 'Image'),
('Blob', 'Blob', 'Blob'),
('Sound', 'Sound', 'Sound'),
('Music', 'Music', 'Music'),
('Font', 'Font', 'Font')],
name = "Type")
size_prop = bpy.props.IntProperty(
name="Size",
description="A name for this item",
default=0)
bpy.utils.register_class(ListItem)
class MY_UL_List(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# We could write some code to decide which icon to use here...
custom_icon = 'OBJECT_DATAMODE'
# Make sure your code supports all 3 layout types
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(item, "enabled_prop")
#layout.label(item.name, icon = custom_icon)
layout.prop(item, "name", text="", emboss=False, icon=custom_icon)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon = custom_icon)
bpy.utils.register_class(MY_UL_List)
def initWorldProperties():
bpy.types.World.my_list = bpy.props.CollectionProperty(type = ListItem)
bpy.types.World.list_index = bpy.props.IntProperty(name = "Index for my_list", default = 0)
initWorldProperties()
class LIST_OT_NewItem(bpy.types.Operator):
# Add a new item to the list
bl_idname = "my_list.new_item"
bl_label = "Add a new item"
def execute(self, context):
bpy.data.worlds[0].my_list.add()
return{'FINISHED'}
class LIST_OT_DeleteItem(bpy.types.Operator):
# Delete the selected item from the list
bl_idname = "my_list.delete_item"
bl_label = "Deletes an item"
@classmethod
def poll(self, context):
""" Enable if there's something in the list """
return len(bpy.data.worlds[0].my_list) > 0
def execute(self, context):
list = bpy.data.worlds[0].my_list
index = bpy.data.worlds[0].list_index
list.remove(index)
if index > 0:
index = index - 1
bpy.data.worlds[0].list_index = index
return{'FINISHED'}
class LIST_OT_MoveItem(bpy.types.Operator):
# Move an item in the list
bl_idname = "my_list.move_item"
bl_label = "Move an item in the list"
direction = bpy.props.EnumProperty(
items=(
('UP', 'Up', ""),
('DOWN', 'Down', ""),))
@classmethod
def poll(self, context):
""" Enable if there's something in the list. """
return len(bpy.data.worlds[0].my_list) > 0
def move_index(self):
# Move index of an item render queue while clamping it
index = bpy.data.worlds[0].list_index
list_length = len(bpy.data.worlds[0].my_list) - 1 # (index starts at 0)
new_index = 0
if self.direction == 'UP':
new_index = index - 1
elif self.direction == 'DOWN':
new_index = index + 1
new_index = max(0, min(new_index, list_length))
index = new_index
def execute(self, context):
list = bpy.data.worlds[0].my_list
index = bpy.data.worlds[0].list_index
if self.direction == 'DOWN':
neighbor = index + 1
#queue.move(index,neighbor)
self.move_index()
elif self.direction == 'UP':
neighbor = index - 1
#queue.move(neighbor, index)
self.move_index()
else:
return{'CANCELLED'}
return{'FINISHED'}
#
# Menu in tools region
#
class ToolsAssetsPanel(bpy.types.Panel):
bl_label = "zblend_assets"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "render"
def draw(self, context):
layout = self.layout
scene = bpy.data.worlds[0]
rows = 2
if len(scene.my_list) > 1:
rows = 4
row = layout.row()
row.template_list("MY_UL_List", "The_List", scene, "my_list", scene, "list_index", rows=rows)
col = row.column(align=True)
col.operator("my_list.new_item", icon='ZOOMIN', text="")
col.operator("my_list.delete_item", icon='ZOOMOUT', text="")#.all = False
if len(scene.my_list) > 1:
col.separator()
col.operator("my_list.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("my_list.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
if scene.list_index >= 0 and len(scene.my_list) > 0:
item = scene.my_list[scene.list_index]
#row = layout.row()
#row.prop(item, "name")
row = layout.row()
row.prop(item, "type_prop")
if item.type_prop == 'Font':
row = layout.row()
row.prop(item, "size_prop")
#
# Registration
#
bpy.utils.register_module(__name__)

View file

@ -3,23 +3,14 @@ import webbrowser
import sys
import bpy
import shutil
import subprocess
import platform
def runProject(fp, target, name):
os.chdir(fp)
# OSX
if (target == '0'):
bashCommand = "xcodebuild -project 'build/osx-build/" + name + ".xcodeproj' && open 'build/osx-build/build/Release/" + name + ".app/Contents/MacOS/" + name + "'"
os.system(bashCommand)
# HTML5
elif (target == '3'):
webbrowser.open("http://127.0.0.1:8000/build/html5",new=2)
def openProject(fp, target, name):
os.chdir(fp)
# OSX
if (target == '0'):
bashCommand = "open -a Xcode.app 'build/osx-build/" + name + ".xcodeproj'"
os.system(bashCommand)
if (target == '3'):
webbrowser.open("http://127.0.0.1:8080/build/html5",new=2)
def build():
argv = sys.argv
@ -36,18 +27,29 @@ def build():
build_type = argv[1]
target = argv[2]
os.system(bashCommand)
haxelib_path = "haxelib"
if platform.system() == 'Darwin':
haxelib_path = "/usr/local/bin/haxelib"
output = subprocess.check_output([haxelib_path + " path kha"], shell=True)
output = str(output).split("\\n")[0].split("'")[1]
kha_path = output
node_path = output + "/Tools/nodejs/node-osx"
print(subprocess.check_output([node_path + " " + kha_path + "/make -t html5"], shell=True))
# Copy ammo.js if necessary
if (target == '3'):
if target == '3':
if not os.path.isfile('build/html5/ammo.js'):
shutil.copy('Libraries/haxebullet/js/ammo/ammo.js', 'build/html5')
output = subprocess.check_output([haxelib_path + " path haxebullet"], shell=True)
output = str(output).split("\\n")[0].split("'")[1]
ammojs_path = output + "js/ammo/ammo.js"
shutil.copy(ammojs_path, 'build/html5')
if build_type == '2':
openProject(fp, target, name)
elif build_type == '1':
if build_type == '1':
runProject(fp, target, name)
print("Build done!")
print("Done!")
build()

View file

@ -1,81 +0,0 @@
import os
import bpy
def fetch():
s = bpy.data.filepath.split(os.path.sep)
name = s.pop()
name = name.split(".")
name = name[0]
fp = os.path.sep.join(s)
# Update scripts
os.chdir(fp + "/Libraries/zblend/blender")
os.system("git pull")
# Clone kha
#self.report({'INFO'}, "Fetching Kha...")
os.chdir(fp)
if not os.path.exists('Kha'):
os.system("git clone --depth=1 --recursive https://github.com/ktxsoftware/Kha")
os.chdir(fp + "/Kha")
os.system("git pull && git submodule foreach --recursive git checkout master && git submodule foreach --recursive git pull origin master")
# Create sources directories
os.chdir(fp)
if not os.path.exists('Sources/Shaders'):
os.makedirs('Sources/Shaders')
if not os.path.exists('Libraries/zblend/Sources'):
os.makedirs('Libraries/zblend/Sources')
if not os.path.exists('Libraries/dependencies'):
os.makedirs('Libraries/dependencies')
if not os.path.exists('Assets'):
os.makedirs('Assets')
# Clone dependencies
#self.report({'INFO'}, "Fetching dependencies...")
os.chdir(fp + "/Libraries/dependencies")
if not os.path.exists('Sources'):
os.system("git clone --depth=1 https://github.com/luboslenco/zblend_dependencies Sources")
os.chdir(fp + "/Libraries/dependencies/Sources")
os.system("git pull")
# Clone shaders
#self.report({'INFO'}, "Fetching shaders...")
os.chdir(fp + "/Libraries/zblend/Sources")
if not os.path.exists('Shaders'):
os.system("git clone --depth=1 https://github.com/luboslenco/zblend_shaders Shaders")
os.chdir(fp + "/Libraries/zblend/Sources/Shaders")
os.system("git pull")
# Clone oimo
os.chdir(fp + "/Libraries")
if not os.path.exists('oimo'):
os.system("git clone --depth=1 https://github.com/luboslenco/oimo oimo")
os.chdir(fp + "/Libraries/oimo")
os.system("git pull")
# Clone haxebullet
#self.report({'INFO'}, "Fetching physics...")
os.chdir(fp + "/Libraries")
if not os.path.exists('haxebullet'):
os.system("git clone --depth=1 https://github.com/luboslenco/haxebullet haxebullet")
os.chdir(fp + "/Libraries/haxebullet")
os.system("git pull")
# Clone zblend
#self.report({'INFO'}, "Fetching zblend...")
os.chdir(fp + "/Libraries/zblend/Sources")
if not os.path.exists('zblend'):
os.system("git clone --depth=1 https://github.com/luboslenco/zblend")
os.chdir(fp + "/Libraries/zblend/Sources/zblend")
os.system("git pull")
print("Fetch complete!")
fetch()

View file

@ -1,173 +0,0 @@
import shutil
import bpy
import os
import json
from bpy.types import Menu, Panel, UIList
from bpy.props import *
class LibListItem(bpy.types.PropertyGroup):
# Group of properties representing an item in the list
name = bpy.props.StringProperty(
name="Name",
description="A name for this item",
default="Untitled")
enabled_prop = bpy.props.BoolProperty(
name="",
description="A name for this item",
default=True)
bpy.utils.register_class(LibListItem)
class MY_UL_LibList(bpy.types.UIList):
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
# We could write some code to decide which icon to use here...
custom_icon = 'OBJECT_DATAMODE'
# Make sure your code supports all 3 layout types
if self.layout_type in {'DEFAULT', 'COMPACT'}:
layout.prop(item, "enabled_prop")
#layout.label(item.name, icon = custom_icon)
layout.prop(item, "name", text="", emboss=False, icon=custom_icon)
elif self.layout_type in {'GRID'}:
layout.alignment = 'CENTER'
layout.label("", icon = custom_icon)
bpy.utils.register_class(MY_UL_LibList)
def initWorldProperties():
bpy.types.World.my_liblist = bpy.props.CollectionProperty(type = LibListItem)
bpy.types.World.liblist_index = bpy.props.IntProperty(name = "Index for my_liblist", default = 0)
initWorldProperties()
class LIBLIST_OT_NewItem(bpy.types.Operator):
# Add a new item to the list
bl_idname = "my_liblist.new_item"
bl_label = "Add a new item"
def execute(self, context):
bpy.data.worlds[0].my_liblist.add()
return{'FINISHED'}
class LIBLIST_OT_DeleteItem(bpy.types.Operator):
# Delete the selected item from the list
bl_idname = "my_liblist.delete_item"
bl_label = "Deletes an item"
@classmethod
def poll(self, context):
""" Enable if there's something in the list """
return len(bpy.data.worlds[0].my_liblist) > 0
def execute(self, context):
list = bpy.data.worlds[0].my_liblist
index = bpy.data.worlds[0].liblist_index
list.remove(index)
if index > 0:
index = index - 1
bpy.data.worlds[0].liblist_index = index
return{'FINISHED'}
class LIST_OT_MoveItem(bpy.types.Operator):
# Move an item in the list
bl_idname = "my_liblist.move_item"
bl_label = "Move an item in the list"
direction = bpy.props.EnumProperty(
items=(
('UP', 'Up', ""),
('DOWN', 'Down', ""),))
@classmethod
def poll(self, context):
""" Enable if there's something in the list. """
return len(bpy.data.worlds[0].my_liblist) > 0
def move_index(self):
# Move index of an item render queue while clamping it
index = bpy.data.worlds[0].liblist_index
list_length = len(bpy.data.worlds[0].my_liblist) - 1 # (index starts at 0)
new_index = 0
if self.direction == 'UP':
new_index = index - 1
elif self.direction == 'DOWN':
new_index = index + 1
new_index = max(0, min(new_index, list_length))
index = new_index
def execute(self, context):
list = bpy.data.worlds[0].my_liblist
index = bpy.data.worlds[0].liblist_index
if self.direction == 'DOWN':
neighbor = index + 1
#queue.move(index,neighbor)
self.move_index()
elif self.direction == 'UP':
neighbor = index - 1
#queue.move(neighbor, index)
self.move_index()
else:
return{'CANCELLED'}
return{'FINISHED'}
#
# Menu in tools region
#
class ToolsLibrariesPanel(bpy.types.Panel):
bl_label = "zblend_libraries"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "render"
def draw(self, context):
layout = self.layout
scene = bpy.data.worlds[0]
rows = 2
if len(scene.my_liblist) > 1:
rows = 4
row = layout.row()
row.template_list("MY_UL_LibList", "The_List", scene, "my_liblist", scene, "liblist_index", rows=rows)
col = row.column(align=True)
col.operator("my_liblist.new_item", icon='ZOOMIN', text="")
col.operator("my_liblist.delete_item", icon='ZOOMOUT', text="")#.all = False
if len(scene.my_liblist) > 1:
col.separator()
col.operator("my_liblist.move_item", icon='TRIA_UP', text="").direction = 'UP'
col.operator("my_liblist.move_item", icon='TRIA_DOWN', text="").direction = 'DOWN'
#if scene.liblist_index >= 0 and len(scene.my_liblist) > 0:
#item = scene.my_liblist[scene.liblist_index]
#row = layout.row()
#row.prop(item, "name")
#row = layout.row()
#row.prop(item, "type_prop")
#
# Registration
#
bpy.utils.register_module(__name__)

View file

@ -10,28 +10,18 @@ import webbrowser
def defaultSettings():
wrd = bpy.data.worlds[0]
wrd['TargetZblendVersion'] = "0.1.0"
wrd['TargetVersion'] = "15.10.0"
wrd['TargetEnum'] = 3
wrd['TargetRenderer'] = 0
wrd['TargetProjectName'] = "my_project"
wrd['TargetProjectPackage'] = "my_project"
wrd['TargetProjectName'] = "myproject"
wrd['TargetProjectPackage'] = "myproject"
wrd['TargetProjectWidth'] = 1136
wrd['TargetProjectHeight'] = 640
wrd['TargetProjectScale'] = 1.0
wrd['TargetProjectOrient'] = 0
wrd['TargetScene'] = bpy.data.scenes[0].name
wrd['TargetGravity'] = bpy.data.scenes[0].name
wrd['TargetClear'] = bpy.data.worlds[0].name
wrd['TargetFog'] = (False)
wrd['TargetFogColor'] = (0.5, 0.5, 0.7, 1.0)
wrd['TargetFogDensity'] = (0.04)
wrd['TargetShadowMapping'] = (False)
wrd['TargetShadowMapSize'] = 1024
wrd['TargetShading'] = 0
wrd['TargetShader'] = 0
wrd['TargetAA'] = 1
wrd['TargetPhysics'] = 1
wrd['TargetSSAO'] = (False)
wrd['TargetAutoBuildNodes'] = (True)
wrd['TargetMinimize'] = (True)
# Make sure we are using cycles
@ -41,7 +31,7 @@ def defaultSettings():
# Store properties in the world object
def initWorldProperties():
bpy.types.World.TargetZblendVersion = StringProperty(name = "ZblendVersion")
bpy.types.World.TargetVersion = StringProperty(name = "ZBlendVersion")
bpy.types.World.TargetEnum = EnumProperty(
items = [('OSX', 'OSX', 'OSX'),
('Windows', 'Windows', 'Windows'),
@ -50,37 +40,13 @@ def initWorldProperties():
('iOS', 'iOS', 'iOS'),
('Android', 'Android', 'Android')],
name = "Target")
bpy.types.World.TargetRenderer = EnumProperty(
items = [('OGL', 'OGL', 'OGL'),
('D3D9', 'D3D9', 'D3D9'),
('D3D11', 'D3D11', 'D3D11')],
name = "Renderer")
bpy.types.World.TargetProjectName = StringProperty(name = "Name")
bpy.types.World.TargetProjectPackage = StringProperty(name = "Package")
bpy.types.World.TargetProjectWidth = IntProperty(name = "Width")
bpy.types.World.TargetProjectHeight = IntProperty(name = "Height")
bpy.types.World.TargetProjectScale = FloatProperty(name = "Scale", default=1.0)
bpy.types.World.TargetProjectOrient = EnumProperty(
items = [('Portrait', 'Portrait', 'Portrait'),
('Landscape', 'Landscape', 'Landscape')],
name = "Orient")
bpy.types.World.TargetScene = StringProperty(name = "Scene")
bpy.types.World.TargetGravity = StringProperty(name = "Gravity")
bpy.types.World.TargetClear = StringProperty(name = "Clear")
bpy.types.World.TargetFog = BoolProperty(name = "Fog")
bpy.types.World.TargetFogColor = FloatVectorProperty(name = "Fog Color", default=[0.5,0.5,0.7,1], size=4, subtype="COLOR", min=0, max=1)
bpy.types.World.TargetFogDensity = FloatProperty(name = "Fog Density", min=0, max=1)
bpy.types.World.TargetShadowMapping = BoolProperty(name = "Shadow mapping")
bpy.types.World.TargetShadowMapSize = IntProperty(name = "Shadow map size")
bpy.types.World.TargetShading = EnumProperty(
items = [('Forward', 'Forward', 'Forward'),
('Deferred', 'Deferred', 'Deferred')],
name = "Shading")
bpy.types.World.TargetShader = EnumProperty(
items = [('Physically based', 'Physically based', 'Physically based'),
('Flat', 'Flat', 'Flat'),
('Unlit', 'Unlit', 'Unlit')],
name = "Shader")
bpy.types.World.TargetAA = EnumProperty(
items = [('Disabled', 'Disabled', 'Disabled'),
('2X', '2X', '2X')],
@ -89,13 +55,12 @@ def initWorldProperties():
items = [('Disabled', 'Disabled', 'Disabled'),
('Bullet', 'Bullet', 'Bullet')],
name = "Physics")
bpy.types.World.TargetSSAO = BoolProperty(name = "SSAO")
bpy.types.World.TargetAutoBuildNodes = BoolProperty(name = "Auto-build nodes")
bpy.types.World.TargetMinimize = BoolProperty(name = "Minimize")
# Default settings
# todo: check version
if not 'TargetZblendVersion' in bpy.data.worlds[0]:
if not 'TargetVersion' in bpy.data.worlds[0]:
defaultSettings()
# Make sure we are using nodes for every material
@ -108,7 +73,7 @@ def initWorldProperties():
return
# Store properties in world for now
# Store properties in world
initWorldProperties()
# Info panel play
@ -118,7 +83,7 @@ def draw_play_item(self, context):
# Menu in tools region
class ToolsPanel(bpy.types.Panel):
bl_label = "zblend_project"
bl_label = "ZBlend Project"
bl_space_type = "PROPERTIES"
bl_region_type = "WINDOW"
bl_context = "render"
@ -133,39 +98,17 @@ class ToolsPanel(bpy.types.Panel):
layout.prop(wrd, 'TargetProjectPackage')
layout.prop(wrd, 'TargetProjectWidth')
layout.prop(wrd, 'TargetProjectHeight')
row = layout.row()
row.active = False
row.prop(wrd, 'TargetProjectScale')
layout.prop_search(wrd, "TargetScene", bpy.data, "scenes", "Scene")
layout.prop(wrd, 'TargetEnum')
if wrd['TargetEnum'] == 4 or wrd['TargetEnum'] == 5:
layout.prop(wrd, 'TargetProjectOrient')
row = layout.row()
row.active = False
row.prop(wrd, 'TargetRenderer')
row = layout.row(align=True)
row.alignment = 'EXPAND'
row.operator("zblend.play")
row.operator("zblend.build")
row.operator("zblend.project")
layout.operator("zblend.build")
row = layout.row(align=True)
row.alignment = 'EXPAND'
row.operator("zblend.folder")
row.operator("zblend.clean")
layout.prop_search(wrd, "TargetGravity", bpy.data, "scenes", "Gravity")
layout.prop_search(wrd, "TargetClear", bpy.data, "worlds", "Clear Color")
layout.prop(wrd, 'TargetFog')
if wrd['TargetFog'] == True:
layout.prop(wrd, 'TargetFogColor')
layout.prop(wrd, 'TargetFogDensity')
layout.prop(wrd, 'TargetShadowMapping')
if wrd['TargetShadowMapping'] == True:
layout.prop(wrd, 'TargetShadowMapSize')
layout.prop(wrd, 'TargetShading')
layout.prop(wrd, 'TargetShader')
layout.prop(wrd, 'TargetAA')
layout.prop(wrd, 'TargetPhysics')
layout.prop(wrd, 'TargetSSAO')
row = layout.row()
row.prop(wrd, 'TargetAutoBuildNodes')
if wrd['TargetAutoBuildNodes'] == False:
@ -234,7 +177,7 @@ def exportGameData():
# Export scene data
for scene in bpy.data.scenes:
if scene.name[0] != '.': # Skip hidden scenes
bpy.ops.export_scene.zblend({"scene":scene}, filepath='Assets/' + scene.name + '.json')
bpy.ops.export_scene.lue({"scene":scene}, filepath='Assets/' + scene.name + '.json')
# Move armatures back
for a in armatures:
@ -243,247 +186,240 @@ def exportGameData():
a.armature.location.z = a.z
# Export project file
x = Object()
x.format = 2
x.game = Object()
x.game.name = bpy.data.worlds[0]['TargetProjectName']
x.game.width = bpy.data.worlds[0]['TargetProjectWidth']
x.game.height = bpy.data.worlds[0]['TargetProjectHeight']
if bpy.data.worlds[0]['TargetAA'] == 1:
x.game.antiAliasingSamples = 2
x.libraries = ["zblend", "haxebullet", "dependencies"]
# Defined libraries
for o in bpy.data.worlds[0].my_liblist:
if o.enabled_prop:
x.libraries.append(o.name)
# Assets
x.assets = []
x.rooms = []
# - Data
x.assets.append(createAsset("data.json", "blob"))
# - Scenes
for s in bpy.data.scenes:
x.assets.append(createAsset(s.name + ".json", "blob"))
# - Defined assets
for o in bpy.data.worlds[0].my_list:
if o.enabled_prop:
if (o.type_prop == 'Atlas'):
x.assets.append(createAsset(o.name + "_metadata.json", "blob"))
x.assets.append(createAsset(o.name + "_atlas.png", "image"))
elif (o.type_prop == 'Font'):
asset = createAsset(o.name, "font")
asset.size = o.size_prop
x.assets.append(asset)
else:
typeName = o.type_prop.lower()
x.assets.append(createAsset(o.name, typeName))
# - Rooms
x.rooms.append(createRoom("room1", x.assets))
# Write project file
with open('project.kha', 'w') as f:
f.write(x.to_JSON())
# x = Object()
# x.format = 3
# x.game = Object()
# x.game.name = bpy.data.worlds[0]['TargetProjectName']
# x.game.width = bpy.data.worlds[0]['TargetProjectWidth']
# x.game.height = bpy.data.worlds[0]['TargetProjectHeight']
# if bpy.data.worlds[0]['TargetAA'] == 1:
# x.game.antiAliasingSamples = 2
# x.libraries = ["zblend", "haxebullet"]
# # Defined libraries
# for o in bpy.data.worlds[0].my_liblist:
# if o.enabled_prop:
# x.libraries.append(o.name)
# # Assets
# x.assets = []
# x.rooms = []
# # - Data
# x.assets.append(createAsset("data.json", "blob"))
# # - Scenes
# for s in bpy.data.scenes:
# x.assets.append(createAsset(s.name + ".json", "blob"))
# # - Defined assets
# for o in bpy.data.worlds[0].my_list:
# if o.enabled_prop:
# if (o.type_prop == 'Atlas'):
# x.assets.append(createAsset(o.name + "_metadata.json", "blob"))
# x.assets.append(createAsset(o.name + "_atlas.png", "image"))
# elif (o.type_prop == 'Font'):
# asset = createAsset(o.name, "font")
# asset.size = o.size_prop
# x.assets.append(asset)
# else:
# typeName = o.type_prop.lower()
# x.assets.append(createAsset(o.name, typeName))
# # - Rooms
# x.rooms.append(createRoom("room1", x.assets))
# # Write project file
# with open('project.kha', 'w') as f:
# f.write(x.to_JSON())
# Export scene properties
data = Object()
# # Export scene properties
# data = Object()
# Objects
objs = []
for o in bpy.data.objects:
x = Object()
x.name = o.name
x.traits = []
for t in o.my_traitlist:
# Disabled trait
if t.enabled_prop == False:
continue
# # Objects
# objs = []
# for o in bpy.data.objects:
# x = Object()
# x.name = o.name
# x.traits = []
# for t in o.my_traitlist:
# # Disabled trait
# if t.enabled_prop == False:
# continue
y = Object()
y.type = t.type_prop
# y = Object()
# y.type = t.type_prop
# Script
if y.type == 'Script':
y.class_name = t.class_name_prop
# Custom traits
elif y.type == 'Mesh Renderer':
y.class_name = 'MeshRenderer'
if t.default_material_prop: # Use object material
y.material = ""
else:
y.material = t.material_prop
y.lighting = t.lighting_prop
y.cast_shadow = t.cast_shadow_prop
y.receive_shadow = t.receive_shadow_prop
elif y.type == 'Custom Renderer':
y.class_name = t.class_name_prop
# # Script
# if y.type == 'Script':
# y.class_name = t.class_name_prop
# # Custom traits
# elif y.type == 'Mesh Renderer':
# y.class_name = 'MeshRenderer'
# if t.default_material_prop: # Use object material
# y.material = ""
# else:
# y.material = t.material_prop
# y.lighting = t.lighting_prop
# y.cast_shadow = t.cast_shadow_prop
# y.receive_shadow = t.receive_shadow_prop
# elif y.type == 'Custom Renderer':
# y.class_name = t.class_name_prop
if t.default_material_prop: # Use object material
y.material = ""
else:
y.material = t.material_prop
# if t.default_material_prop: # Use object material
# y.material = ""
# else:
# y.material = t.material_prop
y.shader = t.shader_prop
y.data = t.data_prop
elif y.type == 'Billboard Renderer':
y.type = 'Custom Renderer'
y.class_name = 'BillboardRenderer'
if t.default_material_prop: # Use object material
y.material = ""
else:
y.material = t.material_prop
y.shader = 'billboardshader'
elif y.type == 'Particles Renderer':
y.type = 'Custom Renderer'
y.class_name = 'ParticlesRenderer'
if t.default_material_prop: # Use object material
y.material = ""
else:
y.material = t.material_prop
y.shader = 'particlesshader'
y.data = t.data_prop
# Convert to scripts
elif y.type == 'Nodes':
y.type = 'Script'
y.class_name = t.nodes_name_prop.replace('.', '_')
elif y.type == 'Scene Instance':
y.type = 'Script'
y.class_name = "SceneInstance:'" + t.scene_prop + "'"
elif y.type == 'Animation':
y.type = 'Script'
y.class_name = "Animation:'" + t.start_track_name_prop + "':"
# Names
anim_names = []
anim_starts = []
anim_ends = []
for animt in o.my_animationtraitlist:
if animt.enabled_prop == False:
continue
anim_names.append(animt.name)
anim_starts.append(animt.start_prop)
anim_ends.append(animt.end_prop)
y.class_name += str(anim_names) + ":"
y.class_name += str(anim_starts) + ":"
y.class_name += str(anim_ends)
# Armature offset
for a in armatures:
if o.parent == a.armature:
y.class_name += ":" + str(a.x) + ":" + str(a.y) + ":" + str(a.z)
break
# y.shader = t.shader_prop
# y.data = t.data_prop
# elif y.type == 'Billboard Renderer':
# y.type = 'Custom Renderer'
# y.class_name = 'BillboardRenderer'
# if t.default_material_prop: # Use object material
# y.material = ""
# else:
# y.material = t.material_prop
# y.shader = 'billboardshader'
# elif y.type == 'Particles Renderer':
# y.type = 'Custom Renderer'
# y.class_name = 'ParticlesRenderer'
# if t.default_material_prop: # Use object material
# y.material = ""
# else:
# y.material = t.material_prop
# y.shader = 'particlesshader'
# y.data = t.data_prop
# # Convert to scripts
# elif y.type == 'Nodes':
# y.type = 'Script'
# y.class_name = t.nodes_name_prop.replace('.', '_')
# elif y.type == 'Scene Instance':
# y.type = 'Script'
# y.class_name = "SceneInstance:'" + t.scene_prop + "'"
# elif y.type == 'Animation':
# y.type = 'Script'
# y.class_name = "Animation:'" + t.start_track_name_prop + "':"
# # Names
# anim_names = []
# anim_starts = []
# anim_ends = []
# for animt in o.my_animationtraitlist:
# if animt.enabled_prop == False:
# continue
# anim_names.append(animt.name)
# anim_starts.append(animt.start_prop)
# anim_ends.append(animt.end_prop)
# y.class_name += str(anim_names) + ":"
# y.class_name += str(anim_starts) + ":"
# y.class_name += str(anim_ends)
# # Armature offset
# for a in armatures:
# if o.parent == a.armature:
# y.class_name += ":" + str(a.x) + ":" + str(a.y) + ":" + str(a.z)
# break
elif y.type == 'Camera':
y.type = 'Script'
cam = bpy.data.cameras[t.camera_link_prop]
if cam.type == 'PERSP':
y.class_name = 'PerspectiveCamera'
elif cam.type == 'ORTHO':
y.class_name = 'OrthoCamera'
elif y.type == 'Light':
y.type = 'Script'
y.class_name = 'Light'
elif y.type == 'Rigid Body':
if bpy.data.worlds[0]['TargetPhysics'] == 0:
continue
y.type = 'Script'
# Get rigid body
if t.default_body_prop == True:
rb = o.rigid_body
else:
rb = bpy.data.objects[t.body_link_prop].rigid_body
shape = '0' # BOX
if t.custom_shape_prop == True:
if t.custom_shape_type_prop == 'Terrain':
shape = '7'
elif t.custom_shape_type_prop == 'Static Mesh':
shape = '8'
elif rb.collision_shape == 'SPHERE':
shape = '1'
elif rb.collision_shape == 'CONVEX_HULL':
shape = '2'
elif rb.collision_shape == 'MESH':
shape = '3'
elif rb.collision_shape == 'CONE':
shape = '4'
elif rb.collision_shape == 'CYLINDER':
shape = '5'
elif rb.collision_shape == 'CAPSULE':
shape = '6'
body_mass = 0
if rb.enabled:
body_mass = rb.mass
y.class_name = 'RigidBody:' + str(body_mass) + \
':' + shape + \
":" + str(rb.friction) + \
":" + str(t.shape_size_scale_prop[0]) + \
":" + str(t.shape_size_scale_prop[1]) + \
":" + str(t.shape_size_scale_prop[2])
# elif y.type == 'Camera':
# y.type = 'Script'
# cam = bpy.data.cameras[t.camera_link_prop]
# if cam.type == 'PERSP':
# y.class_name = 'PerspectiveCamera'
# elif cam.type == 'ORTHO':
# y.class_name = 'OrthoCamera'
# elif y.type == 'Light':
# y.type = 'Script'
# y.class_name = 'Light'
# elif y.type == 'Rigid Body':
# if bpy.data.worlds[0]['TargetPhysics'] == 0:
# continue
# y.type = 'Script'
# # Get rigid body
# if t.default_body_prop == True:
# rb = o.rigid_body
# else:
# rb = bpy.data.objects[t.body_link_prop].rigid_body
# shape = '0' # BOX
# if t.custom_shape_prop == True:
# if t.custom_shape_type_prop == 'Terrain':
# shape = '7'
# elif t.custom_shape_type_prop == 'Static Mesh':
# shape = '8'
# elif rb.collision_shape == 'SPHERE':
# shape = '1'
# elif rb.collision_shape == 'CONVEX_HULL':
# shape = '2'
# elif rb.collision_shape == 'MESH':
# shape = '3'
# elif rb.collision_shape == 'CONE':
# shape = '4'
# elif rb.collision_shape == 'CYLINDER':
# shape = '5'
# elif rb.collision_shape == 'CAPSULE':
# shape = '6'
# body_mass = 0
# if rb.enabled:
# body_mass = rb.mass
# y.class_name = 'RigidBody:' + str(body_mass) + \
# ':' + shape + \
# ":" + str(rb.friction) + \
# ":" + str(t.shape_size_scale_prop[0]) + \
# ":" + str(t.shape_size_scale_prop[1]) + \
# ":" + str(t.shape_size_scale_prop[2])
# Append trait
x.traits.append(y)
# # Append trait
# x.traits.append(y)
# Material slots
x.materials = []
if o.material_slots:
for ms in o.material_slots:
x.materials.append(ms.name)
objs.append(x)
# # Material slots
# x.materials = []
# if o.material_slots:
# for ms in o.material_slots:
# x.materials.append(ms.name)
# objs.append(x)
# Materials
mats = []
for m in bpy.data.materials:
# Make sure material is using nodes
if m.node_tree == None:
continue
x = Object()
x.name = m.name
nodes = m.node_tree.nodes
# Diffuse
if 'Diffuse BSDF' in nodes:
x.diffuse = True
dnode = nodes['Diffuse BSDF']
dcol = dnode.inputs[0].default_value
x.diffuse_color = [dcol[0], dcol[1], dcol[2], dcol[3]]
else:
x.diffuse = False
# Glossy
if 'Glossy BSDF' in nodes:
x.glossy = True
gnode = nodes['Glossy BSDF']
gcol = gnode.inputs[0].default_value
x.glossy_color = [gcol[0], gcol[1], gcol[2], gcol[3]]
x.roughness = gnode.inputs[1].default_value
else:
x.glossy = False
# Texture
if 'Image Texture' in nodes:
x.texture = nodes['Image Texture'].image.name.split(".")[0]
else:
x.texture = ''
mats.append(x)
# # Materials
# mats = []
# for m in bpy.data.materials:
# # Make sure material is using nodes
# if m.node_tree == None:
# continue
# x = Object()
# x.name = m.name
# nodes = m.node_tree.nodes
# # Diffuse
# if 'Diffuse BSDF' in nodes:
# x.diffuse = True
# dnode = nodes['Diffuse BSDF']
# dcol = dnode.inputs[0].default_value
# x.diffuse_color = [dcol[0], dcol[1], dcol[2], dcol[3]]
# else:
# x.diffuse = False
# # Glossy
# if 'Glossy BSDF' in nodes:
# x.glossy = True
# gnode = nodes['Glossy BSDF']
# gcol = gnode.inputs[0].default_value
# x.glossy_color = [gcol[0], gcol[1], gcol[2], gcol[3]]
# x.roughness = gnode.inputs[1].default_value
# else:
# x.glossy = False
# # Texture
# if 'Image Texture' in nodes:
# x.texture = nodes['Image Texture'].image.name.split(".")[0]
# else:
# x.texture = ''
# mats.append(x)
# Output data json
data.objects = objs
data.materials = mats
data.orient = bpy.data.worlds[0]['TargetProjectOrient']
data.scene = bpy.data.worlds[0]['TargetScene']
data.packageName = bpy.data.worlds[0]['TargetProjectPackage']
gravityscn = bpy.data.scenes[bpy.data.worlds[0]['TargetGravity']]
if gravityscn.use_gravity:
data.gravity = [gravityscn.gravity[0], gravityscn.gravity[1], gravityscn.gravity[2]]
else:
data.gravity = [0.0, 0.0, 0.0]
clearwrd = bpy.data.worlds[bpy.data.worlds[0]['TargetClear']]
# Only 'Background' surface for now
clearcol = clearwrd.node_tree.nodes['Background'].inputs[0].default_value
data.clear = [clearcol[0], clearcol[1], clearcol[2], clearcol[3]]
data.fog = bpy.data.worlds[0]['TargetFog']
data.fogColor = [bpy.data.worlds[0]['TargetFogColor'][0], bpy.data.worlds[0]['TargetFogColor'][1], bpy.data.worlds[0]['TargetFogColor'][2], bpy.data.worlds[0]['TargetFogColor'][3]]
data.fogDensity = bpy.data.worlds[0]['TargetFogDensity']
data.shadowMapping = bpy.data.worlds[0]['TargetShadowMapping']
data.shadowMapSize = bpy.data.worlds[0]['TargetShadowMapSize']
data.physics = bpy.data.worlds[0]['TargetPhysics']
data.ssao = bpy.data.worlds[0]['TargetSSAO']
with open('Assets/data.json', 'w') as f:
f.write(data.to_JSON())
# # Output data json
# data.objects = objs
# data.materials = mats
# data.scene = bpy.data.worlds[0]['TargetScene']
# data.packageName = bpy.data.worlds[0]['TargetProjectPackage']
# gravityscn = bpy.data.scenes[bpy.data.worlds[0]['TargetGravity']]
# if gravityscn.use_gravity:
# data.gravity = [gravityscn.gravity[0], gravityscn.gravity[1], gravityscn.gravity[2]]
# else:
# data.gravity = [0.0, 0.0, 0.0]
# clearwrd = bpy.data.worlds[bpy.data.worlds[0]['TargetClear']]
# # Only 'Background' surface for now
# clearcol = clearwrd.node_tree.nodes['Background'].inputs[0].default_value
# data.clear = [clearcol[0], clearcol[1], clearcol[2], clearcol[3]]
# data.physics = bpy.data.worlds[0]['TargetPhysics']
# with open('Assets/data.json', 'w') as f:
# f.write(data.to_JSON())
# Write Main.hx
# TODO: move to separate file
@ -552,37 +488,36 @@ def buildProject(self, build_type=0):
bpy.ops.wm.save_mainfile()
# Export
#self.report({'INFO'}, "Exporting game data...")
exportGameData()
# Set build command
if (bpy.data.worlds[0]['TargetEnum'] == 0):
bashCommand = "Kha/make.js -t osx"
bashCommand = "-t osx"
elif (bpy.data.worlds[0]['TargetEnum'] == 1):
bashCommand = "Kha/make.js -t windows"
bashCommand = "-t windows"
elif (bpy.data.worlds[0]['TargetEnum'] == 2):
bashCommand = "Kha/make.js -t linux"
bashCommand = "-t linux"
elif (bpy.data.worlds[0]['TargetEnum'] == 3):
bashCommand = "Kha/make.js -t html5"
bashCommand = "-t html5"
elif (bpy.data.worlds[0]['TargetEnum'] == 4):
bashCommand = "Kha/make.js -t ios"
bashCommand = "-t ios"
elif (bpy.data.worlds[0]['TargetEnum'] == 5):
bashCommand = "Kha/make.js -t android"
bashCommand = "-t android_native"
# Build
prefix = "node "
if (platform.system() == "Darwin"):
prefix = "/usr/local/bin/node "
elif (platform.system() == "Linux"):
prefix = "nodejs "
#p = Process(target=build_process, args=(prefix + bashCommand, open, run, fp, bpy.data.worlds[0]['TargetEnum'], name,))
#p.start()
#atexit.register(p.terminate)
haxelib_path = "haxelib"
if platform.system() == 'Darwin':
haxelib_path = "/usr/local/bin/haxelib"
prefix = haxelib_path + " run kha "
output = subprocess.check_output([haxelib_path + " path zblend"], shell=True)
output = str(output).split("\\n")[0].split("'")[1]
scripts_path = output + "blender/"
blender_path = bpy.app.binary_path
blend_path = bpy.data.filepath
p = subprocess.Popen([blender_path, blend_path, '-b', '-P', fp + '/Libraries/zblend/blender/zblend_build.py', '--', prefix + bashCommand, str(build_type), str(bpy.data.worlds[0]['TargetEnum'])])
p = subprocess.Popen([blender_path, blend_path, '-b', '-P', scripts_path + 'build.py', '--', prefix + bashCommand, str(build_type), str(bpy.data.worlds[0]['TargetEnum'])])
atexit.register(p.terminate)
self.report({'INFO'}, "Building, see console...")
@ -607,7 +542,7 @@ def cleanProject(self):
node_group_name = node_group.name.replace('.', '_')
os.remove(path + node_group_name + '.hx')
self.report({'INFO'}, "Clean done")
self.report({'INFO'}, "Done")
# Play
class OBJECT_OT_PLAYButton(bpy.types.Operator):
@ -627,15 +562,6 @@ class OBJECT_OT_BUILDButton(bpy.types.Operator):
buildProject(self, 0)
return{'FINISHED'}
# Open project
class OBJECT_OT_PROJECTButton(bpy.types.Operator):
bl_idname = "zblend.project"
bl_label = "Project"
def execute(self, context):
buildProject(self, 2)
return{'FINISHED'}
# Open project folder
class OBJECT_OT_FOLDERButton(bpy.types.Operator):
bl_idname = "zblend.folder"
@ -686,7 +612,6 @@ class OBJECT_OT_DEFAULTSETTINGSButton(bpy.types.Operator):
def buildNodeTrees():
# Set dir
s = bpy.data.filepath.split(os.path.sep)
s.pop()
fp = os.path.sep.join(s)

89
blender/scene.py Executable file → Normal file
View file

@ -15,20 +15,20 @@
#
# http://creativecommons.org/licenses/by-sa/3.0/deed.en_US
#
# Adapted to ZBlend framework
# http://zblend.org/
# Adapted to Lue Rendering Engine
# http://lue3d.org/
# by Lubos Lenco
#
# =============================================================
bl_info = {
"name": "ZBlend format (.json)",
"description": "ZBlend Exporter",
"author": "Lubos Lenco",
"name": "Lue format (.json)",
"description": "Lue Exporter",
"author": "Eric Lengyel & Lubos Lenco",
"version": (1, 0, 0, 0),
"location": "File > Import-Export",
"wiki_url": "http://zblend.org/",
"wiki_url": "http://lue3d.org/",
"category": "Import-Export"}
@ -103,16 +103,16 @@ class ExportVertex:
class Object:
def to_JSON(self):
if bpy.data.worlds[0]['TargetMinimize'] == True:
return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':'))
else:
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)
#if bpy.data.worlds[0]['TargetMinimize'] == True:
# return json.dumps(self, default=lambda o: o.__dict__, separators=(',',':'))
#else:
return json.dumps(self, default=lambda o: o.__dict__, sort_keys=True, indent=4)
class ZBlendExporter(bpy.types.Operator, ExportHelper):
"""Export to ZBlend format"""
bl_idname = "export_scene.zblend"
bl_label = "Export ZBlend"
class LueExporter(bpy.types.Operator, ExportHelper):
"""Export to Lue format"""
bl_idname = "export_scene.lue"
bl_label = "Export Lue"
filename_ext = ".json"
option_export_selection = bpy.props.BoolProperty(name = "Export Selection Only", description = "Export only selected objects", default = False)
@ -336,9 +336,9 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
@staticmethod
def AnimationPresent(fcurve, kind):
if (kind != kAnimationBezier):
return (ZBlendExporter.AnimationKeysDifferent(fcurve))
return (LueExporter.AnimationKeysDifferent(fcurve))
return ((ZBlendExporter.AnimationKeysDifferent(fcurve)) or (ZBlendExporter.AnimationTangentsNonzero(fcurve)))
return ((LueExporter.AnimationKeysDifferent(fcurve)) or (LueExporter.AnimationTangentsNonzero(fcurve)))
@staticmethod
@ -529,7 +529,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
for i in range(len(exportVertexArray)):
ev = exportVertexArray[i]
bucket = ev.hash & (bucketCount - 1)
index = ZBlendExporter.FindExportVertex(hashTable[bucket], exportVertexArray, ev)
index = LueExporter.FindExportVertex(hashTable[bucket], exportVertexArray, ev)
if (index < 0):
indexTable.append(len(unifiedVertexArray))
unifiedVertexArray.append(ev)
@ -591,7 +591,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
for i in range(self.beginFrame, self.endFrame):
scene.frame_set(i)
m2 = node.matrix_local
if (ZBlendExporter.MatricesDifferent(m1, m2)):
if (LueExporter.MatricesDifferent(m1, m2)):
animationFlag = True
break
@ -637,7 +637,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
for i in range(self.beginFrame, self.endFrame):
scene.frame_set(i)
m2 = poseBone.matrix
if (ZBlendExporter.MatricesDifferent(m1, m2)):
if (LueExporter.MatricesDifferent(m1, m2)):
animationFlag = True
break
@ -713,49 +713,49 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
action = node.animation_data.action
if (action):
for fcurve in action.fcurves:
kind = ZBlendExporter.ClassifyAnimationCurve(fcurve)
kind = LueExporter.ClassifyAnimationCurve(fcurve)
if (kind != kAnimationSampled):
if (fcurve.data_path == "location"):
for i in range(3):
if ((fcurve.array_index == i) and (not posAnimCurve[i])):
posAnimCurve[i] = fcurve
posAnimKind[i] = kind
if (ZBlendExporter.AnimationPresent(fcurve, kind)):
if (LueExporter.AnimationPresent(fcurve, kind)):
posAnimated[i] = True
elif (fcurve.data_path == "delta_location"):
for i in range(3):
if ((fcurve.array_index == i) and (not deltaPosAnimCurve[i])):
deltaPosAnimCurve[i] = fcurve
deltaPosAnimKind[i] = kind
if (ZBlendExporter.AnimationPresent(fcurve, kind)):
if (LueExporter.AnimationPresent(fcurve, kind)):
deltaPosAnimated[i] = True
elif (fcurve.data_path == "rotation_euler"):
for i in range(3):
if ((fcurve.array_index == i) and (not rotAnimCurve[i])):
rotAnimCurve[i] = fcurve
rotAnimKind[i] = kind
if (ZBlendExporter.AnimationPresent(fcurve, kind)):
if (LueExporter.AnimationPresent(fcurve, kind)):
rotAnimated[i] = True
elif (fcurve.data_path == "delta_rotation_euler"):
for i in range(3):
if ((fcurve.array_index == i) and (not deltaRotAnimCurve[i])):
deltaRotAnimCurve[i] = fcurve
deltaRotAnimKind[i] = kind
if (ZBlendExporter.AnimationPresent(fcurve, kind)):
if (LueExporter.AnimationPresent(fcurve, kind)):
deltaRotAnimated[i] = True
elif (fcurve.data_path == "scale"):
for i in range(3):
if ((fcurve.array_index == i) and (not sclAnimCurve[i])):
sclAnimCurve[i] = fcurve
sclAnimKind[i] = kind
if (ZBlendExporter.AnimationPresent(fcurve, kind)):
if (LueExporter.AnimationPresent(fcurve, kind)):
sclAnimated[i] = True
elif (fcurve.data_path == "delta_scale"):
for i in range(3):
if ((fcurve.array_index == i) and (not deltaSclAnimCurve[i])):
deltaSclAnimCurve[i] = fcurve
deltaSclAnimKind[i] = kind
if (ZBlendExporter.AnimationPresent(fcurve, kind)):
if (LueExporter.AnimationPresent(fcurve, kind)):
deltaSclAnimated[i] = True
elif ((fcurve.data_path == "rotation_axis_angle") or (fcurve.data_path == "rotation_quaternion") or (fcurve.data_path == "delta_rotation_quaternion")):
sampledAnimation = True
@ -1102,7 +1102,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
def ProcessNode(self, node):
if ((self.exportAllFlag) or (node.select)):
type = ZBlendExporter.GetNodeType(node)
type = LueExporter.GetNodeType(node)
self.nodeArray[node] = {"nodeType" : type, "structName" : "node" + str(len(self.nodeArray) + 1)}
if (node.parent_type == "BONE"):
@ -1182,6 +1182,9 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
# object reference, material references (for geometries), and transform.
# Subnodes are then exported recursively.
if (node.name[0] == "."):
return; # Do not export nodes prefixed with '.'
nodeRef = self.nodeArray.get(node)
if (nodeRef):
type = nodeRef["nodeType"]
@ -1206,7 +1209,8 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
if (type == kNodeTypeGeometry):
if (not object in self.geometryArray):
self.geometryArray[object] = {"structName" : "geometry" + str(len(self.geometryArray) + 1), "nodeTable" : [node]}
#self.geometryArray[object] = {"structName" : "geometry" + str(len(self.geometryArray) + 1), "nodeTable" : [node]}
self.geometryArray[object] = {"structName" : node.name, "nodeTable" : [node]}
else:
self.geometryArray[object]["nodeTable"].append(node)
@ -1216,7 +1220,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
for i in range(len(node.material_slots)):
self.ExportMaterialRef(node.material_slots[i].material, i, o)
shapeKeys = ZBlendExporter.GetShapeKeys(object)
shapeKeys = LueExporter.GetShapeKeys(object)
#if (shapeKeys):
# self.ExportMorphWeights(node, shapeKeys, scene, o)
# TODO
@ -1264,6 +1268,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
parento.nodes.append(o)
o.traits = [] # TODO: export only for geometry nodes and nodes
if not hasattr(o, 'nodes'):
o.nodes = []
for subnode in node.children:
@ -1403,7 +1408,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
showOnlyShapeKey = node.show_only_shape_key
currentMorphValue = []
shapeKeys = ZBlendExporter.GetShapeKeys(mesh)
shapeKeys = LueExporter.GetShapeKeys(mesh)
if (shapeKeys):
node.active_shape_key_index = 0
node.show_only_shape_key = True
@ -1464,11 +1469,11 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
# Triangulate mesh and remap vertices to eliminate duplicates.
materialTable = []
exportVertexArray = ZBlendExporter.DeindexMesh(exportMesh, materialTable)
exportVertexArray = LueExporter.DeindexMesh(exportMesh, materialTable)
triangleCount = len(materialTable)
indexTable = []
unifiedVertexArray = ZBlendExporter.UnifyVertices(exportVertexArray, indexTable)
unifiedVertexArray = LueExporter.UnifyVertices(exportVertexArray, indexTable)
vertexCount = len(unifiedVertexArray)
# Write the position array.
@ -1629,7 +1634,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
bpy.data.meshes.remove(exportMesh)
o.mesh = om
self.output.geometry_objects.append(o)
self.output.geometry_resources.append(o)
def ExportLight(self, objectRef):
@ -1769,7 +1774,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
self.IndentWrite(B"}\n")
'''
self.output.light_objects.append(o)
self.output.light_resources.append(o)
def ExportCamera(self, objectRef):
@ -1799,7 +1804,7 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
p3.value = self.WriteFloat(object.clip_end)
o.params.append(p3)
self.output.camera_objects.append(o)
self.output.camera_resources.append(o)
def ExportMaterials(self):
@ -1927,13 +1932,13 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
if (not object.parent):
self.ExportNode(object, scene)
self.output.geometry_objects = [];
self.output.light_objects = [];
self.output.camera_objects = [];
self.output.geometry_resources = [];
self.output.light_resources = [];
self.output.camera_resources = [];
self.ExportObjects(scene)
self.output.materials = []
self.ExportMaterials()
#self.ExportMaterials()
if (self.restoreFrame):
@ -1948,15 +1953,15 @@ class ZBlendExporter(bpy.types.Operator, ExportHelper):
def menu_func(self, context):
self.layout.operator(ZBlendExporter.bl_idname, text = "ZBlend (.json)")
self.layout.operator(LueExporter.bl_idname, text = "Lue (.json)")
def register():
bpy.utils.register_class(ZBlendExporter)
bpy.utils.register_class(LueExporter)
bpy.types.INFO_MT_file_export.append(menu_func)
def unregister():
bpy.types.INFO_MT_file_export.remove(menu_func)
bpy.utils.unregister_class(ZBlendExporter)
bpy.utils.unregister_class(LueExporter)
if __name__ == "__main__":
register()

16
haxelib.json Normal file
View file

@ -0,0 +1,16 @@
{
"name": "zblend",
"url" : "https://github.com/luboslenco/zblend/",
"license": "MIT",
"tags": ["kha", "3d"],
"description": "Blender game engine",
"version": "15.10.0",
"classPath": "",
"releasenote": "Initial release.",
"contributors": ["Lubos"],
"dependencies": {
"kha": "",
"lue": "",
"haxebullet": ""
}
}