#[macro_export]
macro_rules! import_objects {
($($token:tt)*) => {
russimp_ng::scene::Scene::from_buffer(
include_bytes!($($token)*),
vec![
russimp_ng::scene::PostProcess::Triangulate,
russimp_ng::scene::PostProcess::GenerateNormals,
],
"",
)
.unwrap()
.meshes
.into_iter()
.map(|mesh| ObjectDescriptor {
transform: Transform::default(),
render_pipeline: 0,
vertices: mesh
.vertices
.into_iter()
.map(|vertex| Vec3::from(vertex))
.collect(),
indices: mesh.faces.into_iter().flat_map(|face| face.0).collect(),
}).collect()
};
}
Model comes out with odd and unpredictable matrix multiplication, vaguely forming a cube like it's supposed to, with some triangles missing.
the macro just forwards the tokens to include_bytes!(), so there's not much to talk about.
this snippet could just be written as a normal function, which makes it easier to debug and examine the intermediate data, e.g. you can single step the code in a debugger and watch the variables.
pub fn import_objects(bytes: &[u8]) -> Vec<ObjectDescriptor> {
//...
}
fn main() {
let objects = import_objects(include_bytes("assets/my_model.obj"));
}
btw, did you try to capture the draw call with renderdoc? maybe your model data was just dumped incorrectly.
Is there any way to make it compile time? And no, I didn't.
Putting it in a macro doesn’t necessarily make everything happen at compile time. Rather… at compile time, that particular macro just spits out the code which makes something happen at runtime.
Making it happen at compile time would involve using const stuff, but const is currently very limited in Rust; in particular, allocation (like vec![some, stuff]) can not yet be made const. Even on nightly, where more stuff can be const, AFAIK we’re still a ways off.
However, maybe you could have one program spit out the transformed data to a file in some usable format, and then have your main program read it (with include_bytes again) to avoid needing to compute it itself?
I think you might have some misunderstanding about macros.
declarative macros won't make your code "execute" at compile time, you need either a const function, or a procedural macro, to be able to do compile time computation. note, even if the algorithm is const compatible, you cannot use heap allocated containers such as Vec in your const function.
Same story. A procedural macro's output is Rust tokens, which are then processed into the final program by the compiler and linker just like the rest of your code. If a procedural macro emits code to load data at runtime, then that data will be loaded at runtime, just as if you'd written the same code by hand.
If russimp_ng supports baking assets into your program at compile time, it's not obvious from the documentation. You might try asking on the project's Github tracker.