2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-09 01:07:43 +00:00

Work on FRME widgets; initial DSP streaming

This commit is contained in:
Jack Andersen
2017-01-13 18:16:10 -10:00
parent 904166e016
commit 3544cbd278
14 changed files with 547 additions and 116 deletions

View File

@@ -62,6 +62,7 @@ void FRME::Widget::read(athena::io::IStreamReader& __dna_reader)
case SBIG('MODL'): widgetInfo.reset(new MODLInfo); break;
case SBIG('METR'): widgetInfo.reset(new METRInfo); break;
case SBIG('GRUP'): widgetInfo.reset(new GRUPInfo); break;
case SBIG('PANE'): widgetInfo.reset(new PANEInfo); break;
case SBIG('TXPN'): widgetInfo.reset(new TXPNInfo(owner->version)); break;
case SBIG('IMGP'): widgetInfo.reset(new IMGPInfo); break;
case SBIG('TBGP'): widgetInfo.reset(new TBGPInfo); break;
@@ -101,12 +102,14 @@ void FRME::Widget::read(athena::io::IStreamReader& __dna_reader)
void FRME::Widget::write(athena::io::IStreamWriter& __dna_writer) const
{
/* type */
type.write(__dna_writer);
DNAFourCC _type = widgetInfo ? widgetInfo->fourcc() : FOURCC('BWIG');
_type.write(__dna_writer);
/* header */
header.write(__dna_writer);
/* widgetInfo */
widgetInfo->write(__dna_writer);
if (widgetInfo)
widgetInfo->write(__dna_writer);
/* isWorker */
__dna_writer.writeBool(isWorker);
@@ -137,7 +140,8 @@ size_t FRME::Widget::binarySize(size_t __isz) const
{
__isz = type.binarySize(__isz);
__isz = header.binarySize(__isz);
__isz = widgetInfo->binarySize(__isz);
if (widgetInfo)
__isz = widgetInfo->binarySize(__isz);
if (isWorker)
__isz += 4;
return __isz + 67;
@@ -335,22 +339,8 @@ bool FRME::Extract(const SpecBase &dataSpec,
hecl::BlenderConnection::PyOutStream os = conn.beginPythonOut(true);
os << "import bpy, math\n"
os << "import bpy, math, bmesh\n"
"from mathutils import Matrix, Quaternion\n"
"bpy.types.Object.retro_widget_type = bpy.props.StringProperty(name='Retro: FRME Widget Type')\n"
"model_draw_flags = [\n"
" ('RETRO_SHADELESS', 'Shadeless', '', 0),\n"
" ('RETRO_OPAQUE', 'Opaque', '', 1),\n"
" ('RETRO_ALPHA', 'Alpha', '', 2),\n"
" ('RETRO_ADDITIVE', 'Additive', '', 3),\n"
" ('RETRO_ALPHA_ADDITIVE_OVERDRAW', 'Alpha Additive Overdraw', '', 4)]\n"
"bpy.types.Object.retro_widget_parent = bpy.props.StringProperty(name='Retro: FRME Widget Parent', description='Refers to internal frame widgets')\n"
"bpy.types.Object.retro_widget_use_anim_controller = bpy.props.BoolProperty(name='Retro: Use Animiation Conroller')\n"
"bpy.types.Object.retro_widget_default_visible = bpy.props.BoolProperty(name='Retro: Default Visible', description='Sets widget is visible by default')\n"
"bpy.types.Object.retro_widget_default_active = bpy.props.BoolProperty(name='Retro: Default Visible', description='Sets widget is cases by default')\n"
"bpy.types.Object.retro_widget_cull_faces = bpy.props.BoolProperty(name='Retro: Default Visible', description='Enables face culling')\n"
"bpy.types.Object.retro_widget_color = bpy.props.FloatVectorProperty(name='Retro: Color', description='Sets widget color', subtype='COLOR', size=4, min=0.0, max=1.0)\n"
"bpy.types.Object.retro_widget_model_draw_flags = bpy.props.EnumProperty(items=model_draw_flags, name='Retro: Model Draw Flags', default='RETRO_ALPHA')\n"
"# Clear Scene\n"
"for ob in bpy.data.objects:\n"
" if ob.type != 'CAMERA':\n"
@@ -388,8 +378,7 @@ bool FRME::Extract(const SpecBase &dataSpec,
using CAMRInfo = Widget::CAMRInfo;
os.format("cam = bpy.data.cameras.new(name='%s')\n"
"binding = cam\n", w.header.name.c_str());
CAMRInfo* info = static_cast<CAMRInfo*>(w.widgetInfo.get());
if (info)
if (CAMRInfo* info = static_cast<CAMRInfo*>(w.widgetInfo.get()))
{
if (info->projectionType == CAMRInfo::ProjectionType::Orthographic)
{
@@ -402,12 +391,15 @@ bool FRME::Extract(const SpecBase &dataSpec,
CAMRInfo::PerspectiveProjection* proj = static_cast<CAMRInfo::PerspectiveProjection*>(info->projection.get());
os.format("cam.type = 'PERSP'\n"
"cam.lens_unit = 'FOV'\n"
"cam.angle = math.radians(%f)\n"
"cam.clip_start = %f\n"
"cam.clip_end = %f\n"
"bpy.context.scene.render.pixel_aspect_x = %f\n"
"bpy.context.scene.render.pixel_aspect_y = bpy.context.scene.render.pixel_aspect_x\n",
proj->fov, proj->znear, proj->zfar, proj->aspect);
"bpy.context.scene.render.resolution_x = 480 * %f\n",
proj->znear, proj->zfar, proj->aspect);
if (proj->aspect > 1.f)
os.format("cam.angle = math.atan2(%f, 1.0 / math.tan(math.radians(%f / 2.0))) * 2.0\n",
proj->aspect, proj->fov);
else
os.format("cam.angle = math.radians(%f)\n", proj->fov);
}
}
os << "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n";
@@ -415,35 +407,130 @@ bool FRME::Extract(const SpecBase &dataSpec,
else if (w.type == SBIG('LITE'))
{
using LITEInfo = Widget::LITEInfo;
LITEInfo* info = static_cast<LITEInfo*>(w.widgetInfo.get());
if (info)
if (LITEInfo* info = static_cast<LITEInfo*>(w.widgetInfo.get()))
{
switch(info->type)
{
case LITEInfo::ELightType::LocalAmbient:
os.format("bg_node.inputs[0].default_value = (%f,%f,%f,1.0\n"
os.format("bg_node.inputs[0].default_value = (%f,%f,%f,1.0)\n"
"bg_node.inputs[1].default_value = %f\n",
w.header.color.vec[0], w.header.color.vec[1], w.header.color.vec[2],
info->distQ / 8.0);
break;
case LITEInfo::ELightType::Spot:
case LITEInfo::ELightType::Directional:
os << "angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n";
default:
os.format("lamp = bpy.data.lamps.new(name='%s', type='POINT')\n"
"lamp.color = (%f, %f, %f)\n"
"lamp.falloff_type = 'INVERSE_COEFFICIENTS'\n"
"lamp.constant_coefficient = %f\n"
"lamp.linear_coefficient = %f\n"
"lamp.quadratic_coefficient = %f\n"
"lamp.retro_light_angle_constant = %f\n"
"lamp.retro_light_angle_linear = %f\n"
"lamp.retro_light_angle_quadratic = %f\n"
"lamp.retro_light_index = %d\n"
"binding = lamp\n",
w.header.name.c_str(),
w.header.color.vec[0], w.header.color.vec[1], w.header.color.vec[2]);
w.header.color.vec[0], w.header.color.vec[1], w.header.color.vec[2],
info->distC, info->distL, info->distQ,
info->angC, info->angL, info->angQ, info->loadedIdx);
if (info->type == LITEInfo::ELightType::Spot)
os.format("lamp.type = 'SPOT'\n"
"lamp.spot_size = %f\n",
info->cutoff);
else if (info->type == LITEInfo::ELightType::Directional)
os << "lamp.type = 'HEMI'\n";
}
}
}
else if (w.type == SBIG('IMGP'))
{
using IMGPInfo = Widget::IMGPInfo;
if (IMGPInfo* info = static_cast<IMGPInfo*>(w.widgetInfo.get()))
{
std::string texName;
hecl::SystemString resPath;
if (info->texture)
{
texName = pakRouter.getBestEntryName(info->texture);
const nod::Node* node;
const PAKRouter<PAKBridge>::EntryType* texEntry = pakRouter.lookupEntry(info->texture, &node);
hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (txtrPath.isNone())
{
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath);
}
resPath = pakRouter.getResourceRelativePath(entry, info->texture);
}
hecl::SystemUTF8View resPathView(resPath);
os.format("if '%s' in bpy.data.images:\n"
" image = bpy.data.images['%s']\n"
"else:\n"
" image = bpy.data.images.load('''//%s''')\n"
" image.name = '%s'\n"
"material = bpy.data.materials.new('%s')\n"
"material.specular_intensity = 0.0\n"
"tex_slot = material.texture_slots.add()\n"
"tex_slot.texture = bpy.data.textures.new('%s', 'IMAGE')\n"
"tex_slot.texture.image = image\n"
"material.active_texture = tex_slot.texture\n"
"bm = bmesh.new()\n"
"verts = []\n",
texName.c_str(), texName.c_str(),
resPathView.str().c_str(), texName.c_str(),
w.header.name.c_str(), w.header.name.c_str());
for (int i=0 ; i<info->quadCoordCount ; ++i)
{
int ti;
if (i == 2)
ti = 3;
else if (i == 3)
ti = 2;
else
ti = i;
os.format("verts.append(bm.verts.new((%f,%f,%f)))\n",
info->quadCoords[ti].vec[0],
info->quadCoords[ti].vec[1],
info->quadCoords[ti].vec[2]);
}
os << "bm.faces.new(verts)\n"
"bm.loops.layers.uv.new('UV')\n"
"bm.verts.ensure_lookup_table()\n";
for (int i=0 ; i<info->uvCoordCount ; ++i)
{
int ti;
if (i == 2)
ti = 3;
else if (i == 3)
ti = 2;
else
ti = i;
os.format("bm.verts[%d].link_loops[0][bm.loops.layers.uv[0]].uv = (%f,%f)\n", i,
info->uvCoords[ti].vec[0],
info->uvCoords[ti].vec[1]);
}
os.format("binding = bpy.data.meshes.new('%s')\n"
"bm.to_mesh(binding)\n"
"bm.free()\n"
"binding.materials.append(material)\n",
w.header.name.c_str());
}
}
os.format("frme_obj = bpy.data.objects.new(name='%s', object_data=binding)\n"
"parentName = '%s'\n"
"frme_obj.retro_widget_type = '%s'\n"
"frme_obj.retro_widget_type = 'RETRO_%s'\n"
"frme_obj.retro_widget_use_anim_controller = %s\n"
"frme_obj.retro_widget_default_visible = %s\n"
"frme_obj.retro_widget_default_active = %s\n"
"frme_obj.retro_widget_cull_faces = %s\n"
"frme_obj.retro_widget_color = (%f,%f,%f,%f)\n"
"frme_obj.retro_widget_model_draw_flags = model_draw_flags[%i][0]\n"
"frme_obj.retro_widget_model_draw_flags = bpy.types.Object.retro_widget_model_draw_flags[1]['items'][%i][0]\n"
"frme_obj.retro_widget_is_worker = %s\n"
"frme_obj.retro_widget_worker_id = %d\n"
"if parentName not in bpy.data.objects:\n"
" frme_obj.retro_widget_parent = parentName\n"
"else:\n"
@@ -455,50 +542,147 @@ bool FRME::Extract(const SpecBase &dataSpec,
w.header.defaultActive ? "True" : "False",
w.header.cullFaces ? "True" : "False",
w.header.color.vec[0], w.header.color.vec[1], w.header.color.vec[2], w.header.color.vec[3],
w.header.modelDrawFlags);
w.header.modelDrawFlags,
w.isWorker ? "True" : "False",
w.workerId);
if (w.type == SBIG('MODL'))
{
using MODLInfo = FRME::Widget::MODLInfo;
MODLInfo* info = dynamic_cast<MODLInfo*>(w.widgetInfo.get());
MODLInfo* info = static_cast<MODLInfo*>(w.widgetInfo.get());
hecl::ProjectPath modelPath = pakRouter.getWorking(info->model);
const PAKRouter<PAKBridge>::EntryType* cmdlE = pakRouter.lookupEntry(info->model, nullptr, true, true);
os.linkBlend(modelPath.getAbsolutePathUTF8().c_str(),
pakRouter.getBestEntryName(*cmdlE).c_str(), true);
os.format("frme_obj.retro_model_light_mask = %d\n", info->lightMask);
os << "print(obj.name)\n"
"copy_obj = duplicateObject(obj)\n"
"copy_obj.parent = frme_obj\n"
"copy_obj.hide = False\n";
}
else if (w.type == SBIG('IMGP'))
else if (w.type == SBIG('CAMR'))
{
using IMGPInfo = Widget::IMGPInfo;
IMGPInfo* info = dynamic_cast<IMGPInfo*>(w.widgetInfo.get());
if (info && info->texture)
os << "bpy.context.scene.camera = frme_obj\n"
"if 'Camera' in bpy.data.objects:\n"
" cam = bpy.data.objects['Camera']\n"
" bpy.context.scene.objects.unlink(cam)\n"
" bpy.data.objects.remove(cam)\n";
}
else if (w.type == SBIG('PANE'))
{
using PANEInfo = Widget::PANEInfo;
if (PANEInfo* info = static_cast<PANEInfo*>(w.widgetInfo.get()))
{
std::string texName = pakRouter.getBestEntryName(info->texture);
const nod::Node* node;
const PAKRouter<PAKBridge>::EntryType* texEntry = pakRouter.lookupEntry(info->texture, &node);
hecl::ProjectPath txtrPath = pakRouter.getWorking(texEntry);
if (txtrPath.isNone())
{
PAKEntryReadStream rs = texEntry->beginReadStream(*node);
TXTR::Extract(rs, txtrPath);
}
hecl::SystemString resPath = pakRouter.getResourceRelativePath(entry, info->texture);
hecl::SystemUTF8View resPathView(resPath);
os.format("if '%s' in bpy.data.images:\n"
" image = bpy.data.images['%s']\n"
"else:\n"
" image = bpy.data.images.load('''//%s''')\n"
" image.name = '%s'\n"
"frme_obj.empty_draw_type = 'IMAGE'\n"
"frme_obj.data = image\n"
"angle = Quaternion((1.0, 0.0, 0.0), math.radians(90.0))\n",
texName.c_str(), texName.c_str(),
resPathView.str().c_str(), texName.c_str());
os.format("frme_obj.retro_pane_dimensions = (%f,%f)\n"
"frme_obj.retro_pane_scale_center = (%f,%f,%f)\n",
info->xDim, info->zDim,
info->scaleCenter.vec[0],
info->scaleCenter.vec[1],
info->scaleCenter.vec[2]);
}
}
else if (w.type == SBIG('TXPN'))
{
using TXPNInfo = Widget::TXPNInfo;
if (TXPNInfo* info = static_cast<TXPNInfo*>(w.widgetInfo.get()))
{
hecl::ProjectPath fontPath = pakRouter.getWorking(info->font, true);
hecl::ProjectPath jpFontPath;
if (frme.version >= 1)
jpFontPath = pakRouter.getWorking(info->jpnFont, true);
os.format("frme_obj.retro_pane_dimensions = (%f,%f)\n"
"frme_obj.retro_pane_scale_center = (%f,%f,%f)\n"
"frme_obj.retro_textpane_font_path = '%s'\n"
"frme_obj.retro_textpane_word_wrap = %s\n"
"frme_obj.retro_textpane_vertical = %s\n"
"frme_obj.retro_textpane_fill_color = (%f,%f,%f,%f)\n"
"frme_obj.retro_textpane_outline_color = (%f,%f,%f,%f)\n"
"frme_obj.retro_textpane_block_extent = (%f,%f)\n"
"frme_obj.retro_textpane_jp_font_path = '%s'\n"
"frme_obj.retro_textpane_jp_font_scale = (%d,%d)\n"
"frme_obj.retro_textpane_hjustification = bpy.types.Object.retro_textpane_hjustification[1]['items'][%d][0]\n"
"frme_obj.retro_textpane_vjustification = bpy.types.Object.retro_textpane_vjustification[1]['items'][%d][0]\n",
info->xDim, info->zDim,
info->scaleCenter.vec[0],
info->scaleCenter.vec[1],
info->scaleCenter.vec[2],
fontPath.getRelativePathUTF8().c_str(),
info->wordWrap ? "True" : "False",
info->vertical ? "True" : "False",
info->fillColor.vec[0],
info->fillColor.vec[1],
info->fillColor.vec[2],
info->fillColor.vec[3],
info->outlineColor.vec[0],
info->outlineColor.vec[1],
info->outlineColor.vec[2],
info->outlineColor.vec[3],
info->blockExtent.vec[0],
info->blockExtent.vec[1],
jpFontPath.getRelativePathUTF8().c_str(),
info->jpnPointScale[0],
info->jpnPointScale[1],
int(info->justification),
int(info->verticalJustification));
}
}
else if (w.type == SBIG('TBGP'))
{
using TBGPInfo = Widget::TBGPInfo;
if (TBGPInfo* info = static_cast<TBGPInfo*>(w.widgetInfo.get()))
{
os.format("frme_obj.retro_tablegroup_elem_count = %d\n"
"frme_obj.retro_tablegroup_elem_default = %d\n"
"frme_obj.retro_tablegroup_wraparound = %s\n",
info->elementCount, info->defaultSelection,
info->selectWraparound ? "True" : "False");
}
}
else if (w.type == SBIG('GRUP'))
{
using GRUPInfo = Widget::GRUPInfo;
if (GRUPInfo* info = static_cast<GRUPInfo*>(w.widgetInfo.get()))
{
os.format("frme_obj.retro_group_default_worker = %d\n",
info->defaultWorker);
}
}
else if (w.type == SBIG('SLGP'))
{
using SLGPInfo = Widget::SLGPInfo;
if (SLGPInfo* info = static_cast<SLGPInfo*>(w.widgetInfo.get()))
{
os.format("frme_obj.retro_slider_min = %f\n"
"frme_obj.retro_slider_max = %f\n"
"frme_obj.retro_slider_default = %f\n"
"frme_obj.retro_slider_increment = %f\n",
info->min, info->max, info->cur, info->increment);
}
}
else if (w.type == SBIG('ENRG'))
{
using ENRGInfo = Widget::ENRGInfo;
if (ENRGInfo* info = static_cast<ENRGInfo*>(w.widgetInfo.get()))
{
hecl::ProjectPath txtrPath = pakRouter.getWorking(info->texture);
if (txtrPath)
os.format("frme_obj.retro_energybar_texture_path = '%s'\n",
txtrPath.getRelativePathUTF8().c_str());
}
}
else if (w.type == SBIG('METR'))
{
using METRInfo = Widget::METRInfo;
if (METRInfo* info = static_cast<METRInfo*>(w.widgetInfo.get()))
{
os.format("frme_obj.retro_meter_no_round_up = %s\n"
"frme_obj.retro_meter_max_capacity = %d\n"
"frme_obj.retro_meter_worker_count = %d\n",
info->noRoundUp ? "True" : "False",
info->maxCapacity, info->workerCount);
}
}