From 04d7694da45643cb0f35cd607deaaf5ccba65bf2 Mon Sep 17 00:00:00 2001 From: Quaternions <krakow20@gmail.com> Date: Thu, 17 Apr 2025 16:46:51 -0700 Subject: [PATCH] rbx_loader: use extended instance --- lib/rbx_loader/src/lib.rs | 6 ++-- lib/rbx_loader/src/rbx.rs | 63 +++++++++++++++++++-------------------- 2 files changed, 33 insertions(+), 36 deletions(-) diff --git a/lib/rbx_loader/src/lib.rs b/lib/rbx_loader/src/lib.rs index 4f320b1..97ca5913 100644 --- a/lib/rbx_loader/src/lib.rs +++ b/lib/rbx_loader/src/lib.rs @@ -1,5 +1,5 @@ use std::io::Read; -use rbx_dom_weak::WeakDom; +use roblox_emulator::types::WeakDom; use strafesnet_deferred_loader::deferred_loader::{LoadFailureMode,MeshDeferredLoader,RenderConfigDeferredLoader}; 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 peek=std::io::BufRead::fill_buf(&mut buf).map_err(ReadError::Io)?; match &peek[0..8]{ - b"<roblox!"=>rbx_binary::from_reader(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_binary::from_reader_generic(buf).map(Model::new).map_err(ReadError::RbxBinary), + b"<roblox "=>rbx_xml::from_reader_generic(buf,Default::default()).map(Model::new).map_err(ReadError::RbxXml), _=>Err(ReadError::UnknownFileFormat), } } diff --git a/lib/rbx_loader/src/rbx.rs b/lib/rbx_loader/src/rbx.rs index 954edae..6413d8d 100644 --- a/lib/rbx_loader/src/rbx.rs +++ b/lib/rbx_loader/src/rbx.rs @@ -2,6 +2,7 @@ use std::collections::HashMap; use crate::loader::MeshIndex; use crate::primitives::{self,CubeFace,CubeFaceDescription,WedgeFaceDescription,CornerWedgeFaceDescription,FaceDescription,Primitives}; use rbx_dom_weak::ustr; +use roblox_emulator::types::{WeakDom,Instance}; use strafesnet_common::aabb::Aabb; use strafesnet_common::map; 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::texture::{RenderConfigs,Texture}; -fn class_is_a(class: &str, superclass: &str) -> bool { - if class==superclass { - return true - } - let class_descriptor=rbx_reflection_database::get().classes.get(class); - if let Some(descriptor) = &class_descriptor { - if let Some(class_super) = &descriptor.superclass { - return class_is_a(&class_super, superclass) - } - } - false -} -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){ - let mut stack=vec![instance]; - while let Some(item)=stack.pop(){ - 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 recursive_collect_superclass( + objects:&mut std::vec::Vec<rbx_dom_weak::types::Ref>, + dom:&WeakDom, + instance:&Instance, + superclass:&str +){ + let instance=instance.as_ref(); + let db=rbx_reflection_database::get(); + let Some(superclass)=db.classes.get(superclass)else{ + return; + }; + objects.extend( + dom.descendants_of(instance.as_ref().referent()).filter_map(|instance|{ + let class=db.classes.get(instance.as_ref().class.as_str())?; + db.has_superclass(class,superclass).then(||instance.as_ref().referent()) + }) + ); } fn planar64_affine3_from_roblox(cf:&rbx_dom_weak::types::CFrame,size:&rbx_dom_weak::types::Vector3)->Planar64Affine3{ Planar64Affine3::new( @@ -405,19 +399,20 @@ fn get_content_url(content:&rbx_dom_weak::types::Content)->Option<&str>{ fn get_texture_description<'a>( temp_objects:&mut Vec<rbx_dom_weak::types::Ref>, render_config_deferred_loader:&mut RenderConfigDeferredLoader<&'a str>, - dom:&'a rbx_dom_weak::WeakDom, - object:&rbx_dom_weak::Instance, + dom:&'a WeakDom, + object:&Instance, size:&rbx_dom_weak::types::Vector3, )->RobloxPartDescription{ //use the biggest one and cut it down later... let mut part_texture_description=RobloxPartDescription::default(); 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{ let Some(decal)=dom.get_by_ref(decal_ref) else{ println!("Decal get_by_ref failed"); continue; }; + let decal=decal.as_ref(); let ( Some(rbx_dom_weak::types::Variant::ContentId(content)), Some(rbx_dom_weak::types::Variant::Enum(normalid)), @@ -521,7 +516,7 @@ struct GetAttributesArgs<'a>{ velocity:Planar64Vec3, } pub fn convert<'a>( - dom:&'a rbx_dom_weak::WeakDom, + dom:&'a WeakDom, render_config_deferred_loader:&mut RenderConfigDeferredLoader<&'a str>, mesh_deferred_loader:&mut MeshDeferredLoader<MeshIndex<'a>>, )->PartialMap1<'a>{ @@ -536,9 +531,10 @@ pub fn convert<'a>( let mut object_refs=Vec::new(); let mut temp_objects=Vec::new(); - recursive_collect_superclass(&mut object_refs, &dom, dom.root(),"BasePart"); - for object_ref in object_refs { - if let Some(object)=dom.get_by_ref(object_ref){ + recursive_collect_superclass(&mut object_refs,dom,dom.root(),"BasePart"); + for object_ref in object_refs{ + if let Some(object_extended)=dom.get_by_ref(object_ref){ + let object=object_extended.as_ref(); if let ( Some(rbx_dom_weak::types::Variant::CFrame(cf)), Some(rbx_dom_weak::types::Variant::Vector3(size)), @@ -561,6 +557,7 @@ pub fn convert<'a>( let mut parent_ref=object.parent(); let mut full_path=object.name.clone(); while let Some(parent)=dom.get_by_ref(parent_ref){ + let parent=parent.as_ref(); full_path=format!("{}.{}",parent.name,full_path); parent_ref=parent.parent(); } @@ -590,7 +587,7 @@ pub fn convert<'a>( let (availability,mesh_id)=match shape{ Shape::Primitive(primitive_shape)=>{ //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" let RobloxPartDescription([ 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")){ 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_id=mesh_deferred_loader.acquire_mesh_id(mesh_index); (MeshAvailability::DeferredUnion(part_texture_description),mesh_id)