I am making an attempt to import 3D fashions into OpenGL utilizing Rust and GLFT fashions, the issue is that this perform used to work… Now it would not work in any respect!
It is working to load the 3D mannequin, with the feel within the right place, apparently with the normals and tangents additionally right… However after I apply the TBN matrix to the normals to use the traditional map… The render comes out like this:
I do not know easy methods to clarify it, however for some purpose the fitting a part of the mannequin (constructive X is right), however the left half (with unfavorable X) for some purpose the traditional.x and tangent.x values are inverted! Which causes half of the mannequin to have seen strains of the transitions the place the traditional map can be…
Because of this, I spent about 3 days rewriting the code in search of the error in each approach… The issue is that even when I invert the traditional.x and tangent.x values just for the unfavorable facet of X… This creates a brand new downside, as a result of I am unable to determine the place precisely the division between one facet and the opposite is, which creates some unusual issues like…
I assumed the issue was within the 3D mannequin, however in each 3D program I opened it, it was regular and the traditional map labored! So, what’s mistaken with my code?
fn CarregarGltf(tudo : &mut Vec, indice : &mut std::collections::HashMap, modelo : &str){
let local_exe = std::env::current_dir().unwrap();
let native = local_exe.show();
let original_tamanho = tudo.len()/22;
let (gltf, buffers, _) = gltf::import(format!("extras/{}.gltf",modelo)).unwrap();
//println!("Desmontando... "{}":",modelo);
for m in gltf.meshes(){
for p in m.primitives(){
let r = p.reader(|buffer| Some(&buffers[buffer.index()]));
let mut indices = Vec::new();
if let Some(gltf::mesh::util::ReadIndices::U16(gltf::accessor::Iter::Normal(iter))) = r.read_indices(){
for v in iter{
indices.push(v);
}
}
let mut posicao = Vec::new();
if let Some(iter) = r.read_positions(){
for v in iter{
posicao.push(v);
}
}
let mut textura = Vec::new();
if let Some(gltf::mesh::util::ReadTexCoords::F32(gltf::accessor::Iter::Normal(iter))) = r.read_tex_coords(0){
for v in iter{
textura.push(v);
}
}
let mut normais = Vec::new();
if let Some(iter) = r.read_normals(){
for v in iter{
normais.push(v);
}
}
let mut tangentes = Vec::new();
if let Some(iter) = r.read_tangents(){
for v in iter{
tangentes.push(v);
}
}
let mut ossosid = Vec::new();
if let Some(gltf::mesh::util::ReadJoints::U8(gltf::accessor::Iter::Normal(iter))) = r.read_joints(0){
for v in iter{
ossosid.push(v);
}
}
if ossosid.len() == 0{
println!("Cenário");
}else{
println!("Personagem");
}
let mut pesos = Vec::new();
if let Some(gltf::mesh::util::ReadWeights::F32(gltf::accessor::Iter::Normal(iter))) = r.read_weights(0){
for v in iter{
pesos.push(v);
}
}
//println!("Indices : {}, {}", &indices.len()/3, &indices.len());
for q in &indices{
// posição
tudo.push(posicao[*q as usize][0] as f32);
tudo.push(posicao[*q as usize][1] as f32);
tudo.push(posicao[*q as usize][2] as f32);
// textura
tudo.push(textura[*q as usize][0] as f32);
tudo.push(textura[*q as usize][1] as f32);
// Normais
tudo.push(normais[*q as usize][0] as f32);
tudo.push(normais[*q as usize][1] as f32);
tudo.push(normais[*q as usize][2] as f32);
// Tangentes
tudo.push(tangentes[*q as usize][0] as f32);
tudo.push(tangentes[*q as usize][1] as f32);
tudo.push(tangentes[*q as usize][2] as f32);
// ossosid e pesos
if ossosid.len() != 0{
tudo.push(ossosid[*q as usize][0] as f32);
tudo.push(ossosid[*q as usize][1] as f32);
tudo.push(ossosid[*q as usize][2] as f32);
tudo.push(ossosid[*q as usize][3] as f32);
// pesos
let tmp = pesos[*q as usize][0] + pesos[*q as usize][1] + pesos[*q as usize][2] + pesos[*q as usize][3];
tudo.push(pesos[*q as usize][0]/tmp);
tudo.push(pesos[*q as usize][1]/tmp);
tudo.push(pesos[*q as usize][2]/tmp);
tudo.push(pesos[*q as usize][3]/tmp);
}else{
tudo.push(0.0);tudo.push(0.0);tudo.push(0.0);tudo.push(0.0);
tudo.push(0.0);tudo.push(0.0);tudo.push(0.0);tudo.push(0.0);
}
// aoffset
let rx = ((rand::thread_rng().gen_range(0..200000) as f32)/100.0)-1000.0;
let rz = ((rand::thread_rng().gen_range(0..200000) as f32)/100.0)-1000.0;
tudo.push(rx);
tudo.push(0.0);
tudo.push(rz);
}
}
}
indice.insert(modelo.to_string(),(original_tamanho as i32,(tudo.len()/22-original_tamanho) as i32));
println!("Tudo do "{}" : {}, {}", modelo.to_string(), original_tamanho, tudo.len()/22-original_tamanho);
}
replace 1
I found that the error is by some means within the bitangent, I do not know easy methods to clarify it however after I use:
B = cross(NOR,T);
The error seems on the fitting facet of the mannequin.
Once I do the alternative:
B = cross(T,NOR);
The precise facet seems appropriately and the left facet seems incorrect.
How do I repair this? I attempted to change the X place, however it simply tousled the entire scene and though it appeared to repair the left and proper sides it created an error in the course of the mannequin!
I used this snippet within the code:
TBN = mat3(T,cross(NOR,T)*(-outpos1.x/abs(outpos1.x)),NOR);