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:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user