Files
SimpleRayTracing/source/Geometry/Mesh.c
Misaki 3de6b83d32 Set C standard to C11 and add new assets
Changed CMakeLists.txt to set the C standard to C11.
Added multiple binary image files for new visual assets.
Added several new image files to enhance rendering capabilities.
Changed stb_image.h to improve support for various image formats.
Changed ray tracing engine to enhance ray creation and intersection.
Changed triangle structure to use a vertex array for better attribute handling.
Changed scene initialization to accommodate new texture management.
2025-04-29 01:43:52 +09:00

149 lines
4.8 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"
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;
aiGetMaterialColor(src, AI_MATKEY_COLOR_DIFFUSE, &base_color);
float smoothness = 0.5f;
aiGetMaterialFloat(src, AI_MATKEY_SHININESS, &smoothness);
texture_t* albedo_texture = NULL;
if (aiGetMaterialTextureCount(src, aiTextureType_DIFFUSE) > 0)
{
struct aiString path;
if (AI_SUCCESS == aiGetMaterialTexture(src, aiTextureType_DIFFUSE, 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);
}
texture_entity_t entity = texture_load(path.data, true, &scene->textures);
if (entity.id != INVALID_TEXTURE_ID)
{
albedo_texture = &scene->textures.buffer[entity.id];
}
}
}
simple_lit_properties_t prop =
{
.albedo = {base_color.r, base_color.g, base_color.b},
.roughness = 1.0f - smoothness,
.metallic = 0.0f,
.albedo_texture = albedo_texture,
};
material_create_simple_lit_default(&prop, &scene->materials);
}
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 index1 = face->mIndices[0];
uint32_t index2 = face->mIndices[1];
uint32_t index3 = face->mIndices[2];
vec3s point1 = {
mesh->mVertices[index1].x,
mesh->mVertices[index1].y,
mesh->mVertices[index1].z
};
vec3s point2 = {
mesh->mVertices[index2].x,
mesh->mVertices[index2].y,
mesh->mVertices[index2].z
};
vec3s point3 = {
mesh->mVertices[index3].x,
mesh->mVertices[index3].y,
mesh->mVertices[index3].z
};
vec2s uv1 = {0.0f, 0.0f};
vec2s uv2 = {0.0f, 0.0f};
vec2s uv3 = {0.0f, 0.0f};
if (has_uv)
{
struct aiVector3D const* tc = mesh->mTextureCoords[0];
uv1.x = tc[index1].x;
uv1.y = tc[index1].y;
uv2.x = tc[index2].x;
uv2.y = tc[index2].y;
uv3.x = tc[index3].x;
uv3.y = tc[index3].y;
}
vec3s normal1 = {
mesh->mNormals[index1].x,
mesh->mNormals[index1].y,
mesh->mNormals[index1].z
};
vec3s normal2 = {
mesh->mNormals[index2].x,
mesh->mNormals[index2].y,
mesh->mNormals[index2].z
};
vec3s normal3 = {
mesh->mNormals[index3].x,
mesh->mNormals[index3].y,
mesh->mNormals[index3].z
};
vertex_t vertex1 = {.position = point1, .normal = normal1, .uv = uv1};
vertex_t vertex2 = {.position = point2, .normal = normal2, .uv = uv2};
vertex_t vertex3 = {.position = point3, .normal = normal3, .uv = uv3};
triangle_create(vertex1, vertex2, vertex3, entity.material_id + mesh->mMaterialIndex, &scene->triangles);
entity.triangle_count++;
}
}
aiReleaseImport(mesh_scene);
return entity;
}