Refactoring
This commit is contained in:
parent
cc727d900e
commit
0e1695151e
|
@ -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__)
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
|
@ -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__)
|
|
@ -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
89
blender/scene.py
Executable file → Normal 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
16
haxelib.json
Normal 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": ""
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue