Files
SimpleRayTracing/source/Geometry/Mesh.c
Misaki fb1ff5cac6 Update rendering, material handling, and shading logic
Changed README.md to update rendering settings and build instructions.
Changed BSDF.h to add functions for normal unpacking and tangent transformation.
Changed RayIntersection.h to include tangent vector in hit_result_t.
Changed Common.h to include vec2.h for 2D vector handling.
Changed String.h to add string_copy function and improve is_absolute_path.
Changed GeometryUtilities.h to enhance quad creation with tangent calculations.
Changed Mesh.h to include tangents in the vertex structure.
Changed Triangle.h to add tangents in the vertex structure for better normal mapping.
Changed Light.h to include tangents in the light shading context.
Changed SkyLight.h to introduce a new structure for sky lights.
Changed Material.h to include tangents in the shading context.
Changed SimpleLit.h to add normal and tangent textures for detailed shading.
Changed Texture.h to introduce a new structure for texture assets.
Changed BSDF.c to add functions for unpacking normals and transforming tangents.
Changed PathTracing.c to include tangents in the shading context.
Changed RayIntersection.c to calculate normals and tangents in ray-triangle intersections.
Changed Mesh.c to improve material texture loading and handle tangents.
Changed Material.c to enhance material collection initialization and resizing.
Changed SimpleLit.c to incorporate normal mapping with normal textures.
Changed Texture.c to improve management of texture assets and resources.
2025-04-29 17:58:10 +09:00

119 lines
4.4 KiB
C

#include "Geometry/Mesh.h"
#include "Common/String.h"
#include "Material/SimpleLit.h"
#include "assimp/cimport.h"
#include "assimp/scene.h"
#include "assimp/postprocess.h"
static texture_entity_t load_material_texture(const struct aiMaterial* material, enum aiTextureType type, const char* filename, scene_t* scene)
{
struct aiString path;
if (AI_SUCCESS == aiGetMaterialTexture(material, type, 0, &path, NULL, NULL, NULL, NULL, NULL, NULL))
{
if (!is_absolute_path(path.data))
{
char directory[1024];
get_path_directory(filename, directory, 1024);
char image_path[1024];
memcpy(image_path, path.data, 1024);
string_join(directory, image_path, path.data, 1024);
}
return texture_load(path.data, true, &scene->textures);
}
return invalid_texture_entity();
}
mesh_entity_t mesh_load(const char* filename, scene_t* scene)
{
mesh_entity_t entity = {0};
const struct aiScene* mesh_scene = aiImportFile(filename, aiProcessPreset_TargetRealtime_Quality);
if (mesh_scene == NULL)
{
perror(aiGetErrorString());
return entity;
}
entity.triangle_id = scene->triangles.count;
entity.material_id = scene->materials.count;
for (uint32_t i = 0; i < mesh_scene->mNumMaterials; i++)
{
const struct aiMaterial* src = mesh_scene->mMaterials[i];
struct aiColor4D base_color = {0.73f};
aiGetMaterialColor(src, AI_MATKEY_COLOR_DIFFUSE, &base_color);
float roughness = 0.75f;
aiGetMaterialFloat(src, AI_MATKEY_ROUGHNESS_FACTOR, &roughness);
float metallic = 0.0f;
aiGetMaterialFloat(src, AI_MATKEY_METALLIC_FACTOR, &metallic);
texture_entity_t albedo_entity = load_material_texture(src, aiTextureType_DIFFUSE, filename, scene);
texture_entity_t normal_entity = load_material_texture(src, aiTextureType_NORMALS, filename, scene);
texture_entity_t roughness_entity = load_material_texture(src, aiTextureType_DIFFUSE_ROUGHNESS, filename, scene);
texture_entity_t metallic_entity = load_material_texture(src, aiTextureType_METALNESS, filename, scene);
simple_lit_properties_t prop =
{
.albedo = {base_color.r, base_color.g, base_color.b},
.roughness = roughness,
.metallic = metallic,
.albedo_texture = albedo_entity,
.normal_texture = normal_entity,
.roughness_texture = roughness_entity,
.metallic_texture = metallic_entity,
};
material_create_simple_lit_default(&prop, &scene->materials);
entity.material_count++;
}
for (uint32_t i = 0; i < mesh_scene->mNumMeshes; i++)
{
const struct aiMesh* mesh = mesh_scene->mMeshes[i];
//TODO: Handle all primitive types, not just triangles
if (mesh->mPrimitiveTypes != aiPrimitiveType_TRIANGLE)
{
continue;
}
bool has_uv = mesh->mTextureCoords[0] != NULL && mesh->mNumUVComponents[0] >= 2;
for (uint32_t j = 0; j < mesh->mNumFaces; j++)
{
const struct aiFace* face = &mesh->mFaces[j];
if (face->mNumIndices != 3)
{
continue;
}
uint32_t index0 = face->mIndices[0];
uint32_t index1 = face->mIndices[1];
uint32_t index2 = face->mIndices[2];
vertex_t vertices[3] = {0};
for (uint32_t k = 0; k < 3; k++)
{
vertices[k].position = (vec3s){mesh->mVertices[face->mIndices[k]].x, mesh->mVertices[face->mIndices[k]].y, mesh->mVertices[face->mIndices[k]].z};
vertices[k].normal = (vec3s){mesh->mNormals[face->mIndices[k]].x, mesh->mNormals[face->mIndices[k]].y, mesh->mNormals[face->mIndices[k]].z};
vertices[k].tangent = (vec3s){mesh->mTangents[face->mIndices[k]].x, mesh->mTangents[face->mIndices[k]].y, mesh->mTangents[face->mIndices[k]].z};
if (has_uv)
{
vertices[k].uv = (vec2s){mesh->mTextureCoords[0][face->mIndices[k]].x, mesh->mTextureCoords[0][face->mIndices[k]].y};
}
}
triangle_create(vertices[0], vertices[1], vertices[2], entity.material_id + mesh->mMaterialIndex, &scene->triangles);
entity.triangle_count++;
}
}
aiReleaseImport(mesh_scene);
return entity;
}