Soft Body rendering from OBJ model (data extraction)

Post Reply
franadam
Posts: 3
Joined: Wed May 01, 2019 9:33 am

Soft Body rendering from OBJ model (data extraction)

Post by franadam »

Hello everyone,

I'm sorry if the answer of my question is already on the forum but i didn't find it.

As part of my master thesis I have to do an softbody simulation.
I'm trying to render softbody, create from Meshes, with Shaders in OpenGL but the object doesnt seem to be rendered (everything renders perfectly except for the sofbody i'm trying to create.).

I attached the Model Class and the main file.
I'm using this class for loading and visualizing model https://learnopengl.com/code_viewer_gh. ... gl/model.h
I need to extract from the softBody some data (nodes indice, position, normal, texCoords, tangent and bitangent) to fill the vertex buffer objects but I don't know where to find most of it... I know that the position and the normals are in the softbody nodes but i can't find the other information needed (nodes indice, texCoords, ..) .

Thank you in advance.

I'm using this function for creating a softBody from my OBJ Liver model :

Code: Select all

		btScalar* verti = new btScalar[3 * (Liver.getMeshes()[0].vertices.size())];
		for (int i = 0; i < Liver.getMeshes()[0].vertices.size(); i++)
		{
			verti[3 * i] = Liver.getMeshes()[0].vertices[i].Position.x;
			verti[3 * i + 1] = Liver.getMeshes()[0].vertices[i].Position.y;
			verti[3 * i + 2] = Liver.getMeshes()[0].vertices[i].Position.z;
		}

		int* indi = new int[Liver.getMeshes()[0].indices.size()];
		for (int i = 0; i < Liver.getMeshes()[0].indices.size(); i++)
		{
			indi[i] = Liver.getMeshes()[0].indices[i];
		}

		btSoftBody* LiverSBody = btSoftBodyHelpers::CreateFromTriMesh(softBodyWorldInfo, verti,
			&indi[0],
			int(Liver.getMeshes()[0].indices.size()) / 3);

		LiverSBody->m_cfg.kVC = 0.5;
		btSoftBody::Material* pSpMat = LiverSBody->appendMaterial();
		//LiverSBody->m_materials[0]->m_kLST = 0.5;
		pSpMat->m_kLST = 1.0;
		LiverSBody->setPose(false, true);

		btTransform trans;
		trans.setIdentity();
		trans.setOrigin(btVector3(0,0,0));
		LiverSBody->transform(trans);

		LiverSBody->generateBendingConstraints(2, pSpMat);
		LiverSBody->m_cfg.piterations = 2;
		LiverSBody->m_cfg.kDF = 1.0;
		LiverSBody->m_cfg.kSRHR_CL = 1;
		LiverSBody->m_cfg.kSR_SPLT_CL = 0;

		LiverSBody->setTotalMass(10, true);
		LiverSBody->scale(btVector3(0.02, 0.02, 0.02));
		LiverSBody->getCollisionShape()->setMargin(0.1);

		float Friction = 0.9;
		float Restitution = 0.5;

		LiverSBody->setFriction(Friction);
		LiverSBody->setRestitution(Restitution);
		
		m_pSoftBodyWorld->addSoftBody(LiverSBody);
	

Code: Select all

//btSoftBody.h
struct Node : Feature
	{
		btVector3 m_x;       // Position
		btVector3 m_q;       // Previous step position
		btVector3 m_v;       // Velocity
		btVector3 m_f;       // Force accumulator
		btVector3 m_n;       // Normal
		btScalar m_im;       // 1/mass
		btScalar m_area;     // Area
		btDbvtNode* m_leaf;  // Leaf data
		int m_battach : 1;   // Attached
	};
Vertex Shader

Code: Select all

#version 330 core

layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;
layout (location = 2) in vec2 aTexCoords;
layout (location = 3) in vec3 aTangent;
layout (location = 4) in vec3 aBitangent;

out VS_OUT {
    vec3 FragPos;
    vec2 TexCoords;
    vec3 TangentLightPos;
    vec3 TangentViewPos;
    vec3 TangentFragPos;
	mat3 TBN;
} vs_out;

uniform mat4 Projection;
uniform mat4 View;
uniform mat4 Model;

uniform vec3 lightPos;
uniform vec3 viewPos;

void main()
{
    vs_out.FragPos = vec3(Model * vec4(0.05 * aPos, 1.0));   
    vs_out.TexCoords = aTexCoords;
    
    mat3 normalMatrix = transpose(inverse(mat3(Model)));
    vec3 T = normalize(normalMatrix * aTangent);
    vec3 N = normalize(normalMatrix * aNormal);
    T = normalize(T - dot(T, N) * N);
    vec3 B = cross(N, T);
    
    vs_out.TBN = transpose(mat3(T, B, N));    
    vs_out.TangentLightPos = vs_out.TBN * lightPos;
    vs_out.TangentViewPos  = vs_out.TBN * viewPos;
    vs_out.TangentFragPos  = vs_out.TBN * vs_out.FragPos;
        
    gl_Position = Projection * View * vec4(vs_out.FragPos, 1.0);
}
Fragment Shader

Code: Select all

#version 330 core
out vec4 FragColor;

in VS_OUT {
    vec3 FragPos;
    vec2 TexCoords;
    vec3 TangentLightPos;
    vec3 TangentViewPos;
    vec3 TangentFragPos;
	mat3 TBN;
} fs_in;

//Material
uniform sampler2D texture_diffuse;
uniform sampler2D texture_normal;

uniform vec3 lightPos;
uniform vec3 viewPos;

void main()
{           
     // obtain normal from normal map in range [0,1]
    vec3 normal = texture(texture_normal, fs_in.TexCoords).rgb;
    // transform normal vector to range [-1,1]
	//normal = fs_in.TBN * normal;
    normal = normalize(normal * 2.0 - 1.0);  // this normal is in tangent space
	//
   
    // get diffuse color
    vec3 color = texture(texture_normal, fs_in.TexCoords).rgb;
    // ambient
    vec3 ambient = 0.3 * color;
    // diffuse
    vec3 lightDir = normalize(fs_in.TangentLightPos - fs_in.TangentFragPos);
    float diff = max(dot(lightDir, normal), 0.0);
    vec3 diffuse = diff * color;
    // specular
    vec3 viewDir = normalize(fs_in.TangentViewPos - fs_in.TangentFragPos);
    vec3 reflectDir = reflect(-lightDir, normal);
    vec3 halfwayDir = normalize(lightDir + viewDir);  
    float spec = pow(max(dot(normal, halfwayDir), 0.0), 32.0);

    vec3 specular = vec3(0.2) * spec;
    FragColor = vec4(ambient + diffuse + specular, 1.0);
}
Attachments
main.cpp
main Class
(26.74 KiB) Downloaded 225 times
Model.hpp
Model Class
(13.91 KiB) Downloaded 216 times
User avatar
drleviathan
Posts: 849
Joined: Tue Sep 30, 2014 6:03 pm
Location: San Francisco

Re: Soft Body rendering from OBJ model (data extraction)

Post by drleviathan »

I started looking at the btSoftBody code to see if I could provide some insight. I don't fully understand it yet but it looks like btSoftBody::m_faces is a btAllignedObjectArray<btSoftBody::Face> and a Face is a "triangle" that has pointers to three Nodes.

Code: Select all

   struct Face : Feature
    {
        Node* m_n[3];        // Node pointers
        btVector3 m_normal;  // Normal
        btScalar m_ra;       // Rest area
        btDbvtNode* m_leaf;  // Leaf data
    };
So most of your mesh data could probably be obtained by walking btSoftBody::m_faces, however since it doesn't have indices to its Nodes you'd have to translate to those... or something. You might be able to compute indices using pointer offset arithmetic from the pointer to the first element of btSoftBody::m_nodes.

There are no texCoords in the btSoftBody. You'll just have to supply your own bogus data for that.
franadam
Posts: 3
Joined: Wed May 01, 2019 9:33 am

Re: Soft Body rendering from OBJ model (data extraction)

Post by franadam »

Thank you for answering !!

Dragonlord told me that I could putt my data in the m_tag Node attribute and I looked at at some Classes, and I found a metode to calculate UV in the btSoftBodyHelpers, I'll try to do something with it.
Great tips for th indices, I'll use pointer offset arithmetic then.

Kind regards,
Post Reply