mirror of
https://github.com/H-uru/korman.git
synced 2025-07-14 22:36:52 +00:00
Fill out some more core-export stuff
This commit is contained in:
@ -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)
|
||||
|
@ -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"}
|
||||
|
@ -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")
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,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")
|
||||
|
Reference in New Issue
Block a user