rbx_loader: use extended instance

This commit is contained in:
Quaternions 2025-04-17 16:46:51 -07:00
parent 0a3825ca2d
commit 04d7694da4
Signed by: Quaternions
GPG Key ID: D0DF5964F79AC131
2 changed files with 33 additions and 36 deletions
lib/rbx_loader/src

@ -1,5 +1,5 @@
use std::io::Read; use std::io::Read;
use rbx_dom_weak::WeakDom; use roblox_emulator::types::WeakDom;
use strafesnet_deferred_loader::deferred_loader::{LoadFailureMode,MeshDeferredLoader,RenderConfigDeferredLoader}; use strafesnet_deferred_loader::deferred_loader::{LoadFailureMode,MeshDeferredLoader,RenderConfigDeferredLoader};
mod rbx; mod rbx;
@ -95,8 +95,8 @@ pub fn read<R:Read>(input:R)->Result<Model,ReadError>{
let mut buf=std::io::BufReader::new(input); let mut buf=std::io::BufReader::new(input);
let peek=std::io::BufRead::fill_buf(&mut buf).map_err(ReadError::Io)?; let peek=std::io::BufRead::fill_buf(&mut buf).map_err(ReadError::Io)?;
match &peek[0..8]{ match &peek[0..8]{
b"<roblox!"=>rbx_binary::from_reader(buf).map(Model::new).map_err(ReadError::RbxBinary), b"<roblox!"=>rbx_binary::from_reader_generic(buf).map(Model::new).map_err(ReadError::RbxBinary),
b"<roblox "=>rbx_xml::from_reader_default(buf).map(Model::new).map_err(ReadError::RbxXml), b"<roblox "=>rbx_xml::from_reader_generic(buf,Default::default()).map(Model::new).map_err(ReadError::RbxXml),
_=>Err(ReadError::UnknownFileFormat), _=>Err(ReadError::UnknownFileFormat),
} }
} }

@ -2,6 +2,7 @@ use std::collections::HashMap;
use crate::loader::MeshIndex; use crate::loader::MeshIndex;
use crate::primitives::{self,CubeFace,CubeFaceDescription,WedgeFaceDescription,CornerWedgeFaceDescription,FaceDescription,Primitives}; use crate::primitives::{self,CubeFace,CubeFaceDescription,WedgeFaceDescription,CornerWedgeFaceDescription,FaceDescription,Primitives};
use rbx_dom_weak::ustr; use rbx_dom_weak::ustr;
use roblox_emulator::types::{WeakDom,Instance};
use strafesnet_common::aabb::Aabb; use strafesnet_common::aabb::Aabb;
use strafesnet_common::map; use strafesnet_common::map;
use strafesnet_common::model; use strafesnet_common::model;
@ -14,30 +15,23 @@ use strafesnet_deferred_loader::deferred_loader::{RenderConfigDeferredLoader,Mes
use strafesnet_deferred_loader::mesh::Meshes; use strafesnet_deferred_loader::mesh::Meshes;
use strafesnet_deferred_loader::texture::{RenderConfigs,Texture}; use strafesnet_deferred_loader::texture::{RenderConfigs,Texture};
fn class_is_a(class: &str, superclass: &str) -> bool { fn recursive_collect_superclass(
if class==superclass { objects:&mut std::vec::Vec<rbx_dom_weak::types::Ref>,
return true dom:&WeakDom,
} instance:&Instance,
let class_descriptor=rbx_reflection_database::get().classes.get(class); superclass:&str
if let Some(descriptor) = &class_descriptor { ){
if let Some(class_super) = &descriptor.superclass { let instance=instance.as_ref();
return class_is_a(&class_super, superclass) let db=rbx_reflection_database::get();
} let Some(superclass)=db.classes.get(superclass)else{
} return;
false };
} objects.extend(
fn recursive_collect_superclass(objects: &mut std::vec::Vec<rbx_dom_weak::types::Ref>,dom: &rbx_dom_weak::WeakDom, instance: &rbx_dom_weak::Instance, superclass: &str){ dom.descendants_of(instance.as_ref().referent()).filter_map(|instance|{
let mut stack=vec![instance]; let class=db.classes.get(instance.as_ref().class.as_str())?;
while let Some(item)=stack.pop(){ db.has_superclass(class,superclass).then(||instance.as_ref().referent())
for &referent in item.children(){ })
if let Some(c)=dom.get_by_ref(referent){ );
if class_is_a(c.class.as_str(),superclass){
objects.push(c.referent());//copy ref
}
stack.push(c);
}
}
}
} }
fn planar64_affine3_from_roblox(cf:&rbx_dom_weak::types::CFrame,size:&rbx_dom_weak::types::Vector3)->Planar64Affine3{ fn planar64_affine3_from_roblox(cf:&rbx_dom_weak::types::CFrame,size:&rbx_dom_weak::types::Vector3)->Planar64Affine3{
Planar64Affine3::new( Planar64Affine3::new(
@ -405,19 +399,20 @@ fn get_content_url(content:&rbx_dom_weak::types::Content)->Option<&str>{
fn get_texture_description<'a>( fn get_texture_description<'a>(
temp_objects:&mut Vec<rbx_dom_weak::types::Ref>, temp_objects:&mut Vec<rbx_dom_weak::types::Ref>,
render_config_deferred_loader:&mut RenderConfigDeferredLoader<&'a str>, render_config_deferred_loader:&mut RenderConfigDeferredLoader<&'a str>,
dom:&'a rbx_dom_weak::WeakDom, dom:&'a WeakDom,
object:&rbx_dom_weak::Instance, object:&Instance,
size:&rbx_dom_weak::types::Vector3, size:&rbx_dom_weak::types::Vector3,
)->RobloxPartDescription{ )->RobloxPartDescription{
//use the biggest one and cut it down later... //use the biggest one and cut it down later...
let mut part_texture_description=RobloxPartDescription::default(); let mut part_texture_description=RobloxPartDescription::default();
temp_objects.clear(); temp_objects.clear();
recursive_collect_superclass(temp_objects,&dom,object,"Decal"); recursive_collect_superclass(temp_objects,dom,object,"Decal");
for &mut decal_ref in temp_objects{ for &mut decal_ref in temp_objects{
let Some(decal)=dom.get_by_ref(decal_ref) else{ let Some(decal)=dom.get_by_ref(decal_ref) else{
println!("Decal get_by_ref failed"); println!("Decal get_by_ref failed");
continue; continue;
}; };
let decal=decal.as_ref();
let ( let (
Some(rbx_dom_weak::types::Variant::ContentId(content)), Some(rbx_dom_weak::types::Variant::ContentId(content)),
Some(rbx_dom_weak::types::Variant::Enum(normalid)), Some(rbx_dom_weak::types::Variant::Enum(normalid)),
@ -521,7 +516,7 @@ struct GetAttributesArgs<'a>{
velocity:Planar64Vec3, velocity:Planar64Vec3,
} }
pub fn convert<'a>( pub fn convert<'a>(
dom:&'a rbx_dom_weak::WeakDom, dom:&'a WeakDom,
render_config_deferred_loader:&mut RenderConfigDeferredLoader<&'a str>, render_config_deferred_loader:&mut RenderConfigDeferredLoader<&'a str>,
mesh_deferred_loader:&mut MeshDeferredLoader<MeshIndex<'a>>, mesh_deferred_loader:&mut MeshDeferredLoader<MeshIndex<'a>>,
)->PartialMap1<'a>{ )->PartialMap1<'a>{
@ -536,9 +531,10 @@ pub fn convert<'a>(
let mut object_refs=Vec::new(); let mut object_refs=Vec::new();
let mut temp_objects=Vec::new(); let mut temp_objects=Vec::new();
recursive_collect_superclass(&mut object_refs, &dom, dom.root(),"BasePart"); recursive_collect_superclass(&mut object_refs,dom,dom.root(),"BasePart");
for object_ref in object_refs { for object_ref in object_refs{
if let Some(object)=dom.get_by_ref(object_ref){ if let Some(object_extended)=dom.get_by_ref(object_ref){
let object=object_extended.as_ref();
if let ( if let (
Some(rbx_dom_weak::types::Variant::CFrame(cf)), Some(rbx_dom_weak::types::Variant::CFrame(cf)),
Some(rbx_dom_weak::types::Variant::Vector3(size)), Some(rbx_dom_weak::types::Variant::Vector3(size)),
@ -561,6 +557,7 @@ pub fn convert<'a>(
let mut parent_ref=object.parent(); let mut parent_ref=object.parent();
let mut full_path=object.name.clone(); let mut full_path=object.name.clone();
while let Some(parent)=dom.get_by_ref(parent_ref){ while let Some(parent)=dom.get_by_ref(parent_ref){
let parent=parent.as_ref();
full_path=format!("{}.{}",parent.name,full_path); full_path=format!("{}.{}",parent.name,full_path);
parent_ref=parent.parent(); parent_ref=parent.parent();
} }
@ -590,7 +587,7 @@ pub fn convert<'a>(
let (availability,mesh_id)=match shape{ let (availability,mesh_id)=match shape{
Shape::Primitive(primitive_shape)=>{ Shape::Primitive(primitive_shape)=>{
//TODO: TAB TAB //TODO: TAB TAB
let part_texture_description=get_texture_description(&mut temp_objects,render_config_deferred_loader,dom,object,size); let part_texture_description=get_texture_description(&mut temp_objects,render_config_deferred_loader,dom,object_extended,size);
//obscure rust syntax "slice pattern" //obscure rust syntax "slice pattern"
let RobloxPartDescription([ let RobloxPartDescription([
f0,//Cube::Right f0,//Cube::Right
@ -671,7 +668,7 @@ pub fn convert<'a>(
if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&ustr("PhysicsData")){ if let Some(rbx_dom_weak::types::Variant::BinaryString(data))=object.properties.get(&ustr("PhysicsData")){
physics_data=data.as_ref(); physics_data=data.as_ref();
} }
let part_texture_description=get_texture_description(&mut temp_objects,render_config_deferred_loader,dom,object,size); let part_texture_description=get_texture_description(&mut temp_objects,render_config_deferred_loader,dom,object_extended,size);
let mesh_index=MeshIndex::union(content,mesh_data,physics_data,size,part_texture_description.clone()); let mesh_index=MeshIndex::union(content,mesh_data,physics_data,size,part_texture_description.clone());
let mesh_id=mesh_deferred_loader.acquire_mesh_id(mesh_index); let mesh_id=mesh_deferred_loader.acquire_mesh_id(mesh_index);
(MeshAvailability::DeferredUnion(part_texture_description),mesh_id) (MeshAvailability::DeferredUnion(part_texture_description),mesh_id)