Browse Source

Fill out some more core-export stuff

pull/1/head
Adam Johnson 12 years ago
parent
commit
f4f39e2d2f
  1. 101
      korman/exporter.py
  2. 14
      korman/operators/op_export.py
  3. 12
      korman/properties/prop_object.py
  4. 37
      korman/properties/prop_world.py
  5. 4
      korman/ui/ui_object.py
  6. 32
      korman/ui/ui_world.py

101
korman/exporter.py

@ -28,9 +28,26 @@ class Exporter:
self._op = op # Blender operator
# This stuff doesn't need to be static
self._nodes = {}
self._objects = []
self._pages = {}
self.texture_page = True
def add_object(self, pl, bl=None, loc=None):
"""Automates adding a converted Blender object to our Plasma Resource Manager"""
assert (bl or loc)
if loc:
location = loc
else:
location = self._pages[bl.plasma_object.page]
self.mgr.AddObject(location, pl)
node = self._nodes[location]
if node: # All objects must be in the scene node
if isinstance(pl, plSceneObject):
f = node.addSceneObject
else:
f = node.addPoolObject
f(pl.key)
@property
def age_name(self):
@ -56,7 +73,10 @@ class Exporter:
node = plSceneNode("%s_District_%s" % (self.age_name, name))
else:
node = plSceneNode("%s_%s" % (self.age_name, name))
self._nodes[location] = node
self.mgr.AddObject(location, node)
else:
self._nodes[location] = None
return location
def get_textures_page(self, obj):
@ -87,37 +107,37 @@ class Exporter:
self._sanity_check_pages()
self._generate_builtins() # Creates BuiltIn and Textures
# ... todo ...
# Step 3: Export all the things!
self._export_scene_objects()
# ... And finally... Write it all out!
# Step 4: FINALLY. Let's write the PRPs and crap.
self.mgr.WriteAge(self._op.filepath, self._age_info)
dir = os.path.split(self._op.filepath)[0]
for name, loc in self._pages.items():
page = self.mgr.FindPage(loc) # not cached because it's C++ owned
# I know that plAgeInfo has its own way of doing this, but we'd have
# to do some looping and stuff. This is easier.
if self.version <= pvMoul:
chapter = "_District_"
else:
chapter = "_"
f = os.path.join(dir, "%s%s%s.prp" % (self.age_name, chapter, name))
self.mgr.WritePage(f, page)
self._write_fni()
self._write_pages()
def _collect_objects(self):
for obj in bpy.data.objects:
if obj.plasma_object.export:
if obj.plasma_object.enabled:
self._objects.append(obj)
def _grab_age_info(self):
self._age_info = bpy.context.scene.world.plasma_age.export()
age = bpy.context.scene.world.plasma_age
self._age_info = plAgeInfo()
self._age_info.dayLength = age.day_length
self._age_info.lingerTime = 180 # this is fairly standard
self._age_info.name = self.age_name
self._age_info.seqPrefix = age.seq_prefix
self._age_info.startDateTime = age.start_time
self.mgr.AddAge(self._age_info)
def _sanity_check_pages(self):
"""Ensure all objects are in valid pages and create the Default page if used"""
for obj in self._objects:
page = obj.plasma_object.page
if not page in self._pages and page == "":
if page in self._pages:
# good. keep trying.
continue
elif page == "":
# This object is in the default page... Init that.
for loc in self._pages.values():
if not loc.page:
@ -143,11 +163,11 @@ class Exporter:
_s -= 1
# Grunt work...
if self.version <= pvMoul:
if self.version <= pvMoul and self._op.save_state:
builtin = self._create_page("BuiltIn", suffixes[1], True)
pfm = plPythonFileMod("VeryVerySpecialPythonFileMod")
pfm.filename = self.age_name
self.mgr.AddObject(builtin, pfm)
self.mgr.AddObject(builtin, pfm) # add_object has lots of overhead
sdlhook = plSceneObject("AgeSDLHook")
sdlhook.addModifier(pfm.key)
self.mgr.AddObject(builtin, sdlhook)
@ -158,3 +178,46 @@ class Exporter:
self._pages["Textures"] = textures
else:
self._pages["Textures"] = None # probably easier than looping to find it
def _export_scene_objects(self):
for bl_obj in self._objects:
# Normally, we'd pass off to the property for export logic, but we need to
# do meshes here, so let's stay local until it's modifier time
so = plSceneObject(bl_obj.name)
self.add_object(pl=so, bl=bl_obj)
# TODO: export mesh
# TODO: export plasma modifiers
def _write_fni(self):
if self.version <= pvMoul:
enc = plEncryptedStream.kEncXtea
else:
enc = plEncryptedStream.kEncAES
fname = os.path.join(os.path.split(self._op.filepath)[0], "%s.fni" % self.age_name)
stream = plEncryptedStream()
stream.open(fname, fmWrite, enc)
# Write out some stuff
fni = bpy.context.scene.world.plasma_fni
stream.writeLine("Graphics.Renderer.Fog.SetClearColor %f %f %f" % tuple(fni.clear_color))
if fni.fog_method != "none":
stream.writeLine("Graphics.Renderer.Fog.SetDefColor %f %f %f" % tuple(fni.fog_color))
if fni.fog_method == "linear":
stream.writeLine("Graphics.Renderer.Fog.SetDefLinear %f %f %f" % (fni.fog_start, fni.fog_end, fni.fog_density))
elif fni.fog_method == "exp2":
stream.writeLine("Graphics.Renderer.Fog.SetDefExp2 %f %f" % (fni.fog_end, fni.fog_density))
stream.writeLine("Graphics.Renderer.Setyon %f" % fni.yon)
stream.close()
def _write_pages(self):
dir = os.path.split(self._op.filepath)[0]
for name, loc in self._pages.items():
page = self.mgr.FindPage(loc) # not cached because it's C++ owned
# I know that plAgeInfo has its own way of doing this, but we'd have
# to do some looping and stuff. This is easier.
if self.version <= pvMoul:
chapter = "_District_"
else:
chapter = "_"
f = os.path.join(dir, "%s%s%s.prp" % (self.age_name, chapter, name))
self.mgr.WritePage(f, page)

14
korman/operators/op_export.py

@ -38,15 +38,17 @@ class ExportOperator(bpy.types.Operator):
)
optimize = bpy.props.BoolProperty(name="Optimize Age",
description="Optimizes your age to run faster. This slows down export.")
save_state = bpy.props.BoolProperty(name="Save State",
description="Saves your age's state to the server for subsequent link ins.",
default=True)
use_texture_page = bpy.props.BoolProperty(name="Use Texture Page",
description="Exports all textures to a dedicated Textures page",
default=True)
filepath = bpy.props.StringProperty(subtype="FILE_PATH")
def _set_error(self, value):
self.has_reports = True
self.report = ({"ERROR"}, value)
error = property(fset=_set_error) # Can't use decorators here :(
@property
def has_reports(self):
return hasattr(self.report)
@classmethod
def poll(cls, context):
@ -64,7 +66,7 @@ class ExportOperator(bpy.types.Operator):
try:
os.mkdirs(dir)
except os.error:
self.error = "Failed to create export directory"
self.report({"ERROR"}, "Failed to create export directory")
return {"CANCELLED"}
# Separate blender operator and actual export logic for my sanity
@ -72,7 +74,7 @@ class ExportOperator(bpy.types.Operator):
try:
e.run()
except exporter.ExportError as error:
self.error = str(error)
self.report({"ERROR"}, str(error))
return {"CANCELLED"}
else:
return {"FINISHED"}

12
korman/properties/prop_object.py

@ -17,7 +17,7 @@ import bpy
from bpy.props import *
class PlasmaObject(bpy.types.PropertyGroup):
def _export_changed(self, context):
def _enabled(self, context):
# This makes me sad
if not self.is_inited:
self._init(context)
@ -34,14 +34,14 @@ class PlasmaObject(bpy.types.PropertyGroup):
for page in age.pages:
if page.seq_suffix > num_layers:
continue
if o.layers[page.seq_suffix-1]:
if o.layers[page.seq_suffix - 1]:
o.plasma_object.page = page.name
break
export = BoolProperty(name="Export",
description="Export this as a discrete object",
default=False,
update=_export_changed)
enabled = BoolProperty(name="Export",
description="Export this as a discrete object",
default=False,
update=_enabled)
page = StringProperty(name="Page",
description="Page this object will be exported to")

37
korman/properties/prop_world.py

@ -22,8 +22,24 @@ class PlasmaFni(bpy.types.PropertyGroup):
fog_color = FloatVectorProperty(name="Fog Color",
description="The default fog color used in your age",
default=(0.3, 0.2, 0.05),
default=(0.4, 0.3, 0.1),
subtype="COLOR")
fog_method = EnumProperty(name="Fog Type",
items=[
("linear", "Linear", "Linear Fog"),
("exp2", "Exponential", "Exponential Fog"),
("none", "None", "Use fog from the previous age")
])
fog_start = FloatProperty(name="Start",
description="",
default= -1500.0)
fog_end = FloatProperty(name="End",
description="",
default=20000.0)
fog_density = FloatProperty(name="Density",
description="",
default=1.0,
min=0.0)
clear_color = FloatVectorProperty(name="Clear Color",
description="The default background color rendered in your age",
subtype="COLOR")
@ -32,7 +48,6 @@ class PlasmaFni(bpy.types.PropertyGroup):
default=100000,
soft_min=100,
min=1)
# TODO: density
class PlasmaPage(bpy.types.PropertyGroup):
def _check_suffix(self, context):
@ -86,6 +101,9 @@ class PlasmaPage(bpy.types.PropertyGroup):
auto_load = BoolProperty(name="Auto Load",
description="Load this page on link-in",
default=True)
local_only = BoolProperty(name="Local Only",
description="This page should not synchronize with the server",
default=False)
# Implementation details...
last_name = StringProperty(description="INTERNAL: Cached page name",
@ -100,9 +118,14 @@ class PlasmaPage(bpy.types.PropertyGroup):
class PlasmaAge(bpy.types.PropertyGroup):
day_length = FloatProperty(name="Day Length",
description="Length of a day (in hours) on this age",
default=24.0,
default=30.230000,
soft_min=0.1,
min=0.0)
start_time = IntProperty(name="Start Time",
description="Seconds from 1/1/1970 until the first day on this age",
subtype="UNSIGNED",
default=672211080,
min=0)
seq_prefix = IntProperty(name="Sequence Prefix",
description="A unique numerical ID for this age",
soft_min=0, # Negative indicates global--advanced users only
@ -113,11 +136,3 @@ class PlasmaAge(bpy.types.PropertyGroup):
# Implementation details
active_page_index = IntProperty(name="Active Page Index")
def export(self):
age = plAgeInfo()
age.dayLength = self.day_length
age.seqPrefix = self.seq_prefix
# Pages are added to the ResManager in the main exporter
return age

4
korman/ui/ui_object.py

@ -29,12 +29,12 @@ class PlasmaObjectPanel(ObjectButtonsPanel, bpy.types.Panel):
bl_label = "Plasma Object"
def draw_header(self, context):
self.layout.prop(context.object.plasma_object, "export", text="")
self.layout.prop(context.object.plasma_object, "enabled", text="")
def draw(self, context):
layout = self.layout
pl_obj = context.object.plasma_object
pl_age = context.scene.world.plasma_age
layout.active = pl_obj.export
layout.active = pl_obj.enabled
layout.prop_search(pl_obj, "page", pl_age, "pages", icon="BOOKMARKS")

32
korman/ui/ui_world.py

@ -32,9 +32,6 @@ class PlasmaAgePanel(AgeButtonsPanel, bpy.types.Panel):
layout = self.layout
age = context.world.plasma_age
# Core age settings
# ...
# We want a list of pages and an editor below that
row = layout.row()
row.template_list(age, "pages", age, "active_page_index", rows=2)
@ -42,14 +39,23 @@ class PlasmaAgePanel(AgeButtonsPanel, bpy.types.Panel):
col.operator("world.plasma_page_add", icon="ZOOMIN", text="")
col.operator("world.plasma_page_remove", icon="ZOOMOUT", text="")
# name/id editor for current selection
# Page Properties
if age.active_page_index < len(age.pages):
active_page = age.pages[age.active_page_index]
split = layout.split(percentage=0.65)
split = layout.box().split()
col = split.column()
col.prop(active_page, "name")
col.prop(active_page, "name", text="")
col.prop(active_page, "auto_load")
col = split.column()
col.prop(active_page, "seq_suffix")
col.prop(active_page, "local_only")
# Core settings
row = layout.row()
row.prop(age, "day_length")
row.prop(age, "seq_prefix", text="ID")
layout.prop(age, "start_time")
class PlasmaEnvironmentPanel(AgeButtonsPanel, bpy.types.Panel):
@ -59,11 +65,23 @@ class PlasmaEnvironmentPanel(AgeButtonsPanel, bpy.types.Panel):
layout = self.layout
fni = context.world.plasma_fni
# Column-ize the colors
# basic colors
split = layout.split()
col = split.column()
col.prop(fni, "fog_color")
col = split.column()
col.prop(fni, "clear_color")
# fog box
split = layout.box()
row = split.row().split(percentage=0.50)
row.column().prop_menu_enum(fni, "fog_method")
if fni.fog_method == "linear":
row.column().prop(fni, "fog_start")
if fni.fog_method != "none":
row = split.row()
row.prop(fni, "fog_density")
row.prop(fni, "fog_end")
# tacked on: draw distance
layout.prop(fni, "yon")

Loading…
Cancel
Save