efl/src/lib/evas/common3d/save_load/evas_model_load_save_common.c

231 lines
10 KiB
C

#include "evas_model_load_save_common.h"
# define SAVE_MESH_INDICES_COPY \
if (header.indices_count) \
{ \
data->indices = malloc(header.indices_count \
* sizeof(unsigned short)); \
if (pd->index_format == EVAS_CANVAS3D_INDEX_FORMAT_UNSIGNED_BYTE) \
{ \
for (i = 0; i < header.indices_count; i++) \
data->indices[i] = ((unsigned char*)(pd->indices))[i]; \
} \
else \
{ \
for (i = 0; i < header.indices_count; i++) \
data->indices[i] = ((unsigned short*)(pd->indices))[i]; \
} \
} \
else \
{ \
data->indices = malloc(header.vertices_count * 3 \
* sizeof(unsigned short)); \
for (i = 0; i < header.vertices_count * 3; i++) \
data->indices[i] = (unsigned short)i; \
}
/* create new header */
Evas_Model_Load_Save_Header
evas_model_load_save_header_new(void)
{
Evas_Model_Load_Save_Header header;
header.vertices_count = 0;
header.indices_count = 0;
header.existence_of_positions = EINA_FALSE;
header.existence_of_normals = EINA_FALSE;
header.existence_of_tex_coords = EINA_FALSE;
header.existence_of_colors = EINA_FALSE;
return header;
}
void
evas_model_load_vertex_data_unmap(Evas_Canvas3D_Mesh *mesh,
int frame,
Evas_Model_Load_Save_Header header)
{
#define UNMAP_IF_EXIST(existence, vertex_data_type) \
if (existence) \
{ \
evas_canvas3d_mesh_frame_vertex_data_unmap(mesh, frame, \
vertex_data_type); \
}
UNMAP_IF_EXIST(header.existence_of_positions, EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION)
UNMAP_IF_EXIST(header.existence_of_normals, EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL)
UNMAP_IF_EXIST(header.existence_of_tex_coords, EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD)
UNMAP_IF_EXIST(header.existence_of_colors, EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR)
#undef UNMAP_IF_EXIST
}
void
evas_model_load_save_data_free(Evas_Model_Load_Save_Header header,
Evas_Model_Load_Save_Data *data)
{
if (header.existence_of_positions) free(data->positions);
if (header.existence_of_normals) free(data->normals);
if (header.existence_of_tex_coords) free(data->tex_coords);
if (header.existence_of_colors) free(data->colors);
free(data->indices);
}
void
evas_model_load_vertex_data_to_mesh(Evas_Canvas3D_Mesh *mesh,
Evas_Model_Load_Save_Header header,
Evas_Model_Load_Save_Data data,
Evas_Model_Load_Save_Stride *stride)
{
Evas_Model_Load_Save_Data map;
int i, j;
evas_canvas3d_mesh_vertex_count_set(mesh, header.vertices_count);
evas_canvas3d_mesh_vertex_assembly_set(mesh, EVAS_CANVAS3D_VERTEX_ASSEMBLY_TRIANGLES);
evas_canvas3d_mesh_frame_add(mesh, 0);
#define VERTEX_DATA_MAP(name, vertex_data_type, default_size) \
if (header.existence_of_##name) \
{ \
evas_canvas3d_mesh_frame_vertex_data_copy_set(mesh, 0, vertex_data_type, 0, NULL); \
map.name = (float *)evas_canvas3d_mesh_frame_vertex_data_map(mesh, 0, vertex_data_type); \
stride->name = evas_canvas3d_mesh_frame_vertex_stride_get(mesh, 0, vertex_data_type); \
if (stride->name == 0) stride->name = sizeof(float) * default_size; \
}
VERTEX_DATA_MAP(positions, EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION, 3)
VERTEX_DATA_MAP(normals, EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL, 3)
VERTEX_DATA_MAP(tex_coords, EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD, 2)
VERTEX_DATA_MAP(colors, EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR, 4)
#undef VERTEX_DATA_MAP
for (i = 0; i < header.vertices_count; i++)
{
Evas_Model_Load_Save_Data current_pointer;
#define FILL_VERTEX_DATA(name, size) \
if (header.existence_of_##name) \
{ \
current_pointer.name = (float *)((char *)map.name + stride->name * i); \
for (j = 0; j < size; j++) \
current_pointer.name[j] = ARRAY_2D(data.name, i, j, size); \
}
FILL_VERTEX_DATA(positions, 3)
FILL_VERTEX_DATA(normals, 3)
FILL_VERTEX_DATA(tex_coords, 2)
FILL_VERTEX_DATA(colors, 3)
#undef FILL_VERTEX_DATA
if (header.existence_of_colors) current_pointer.colors[3] = 1.0;
}
}
void
evas_model_load_indices_data_to_mesh(Evas_Canvas3D_Mesh *mesh,
Evas_Model_Load_Save_Header header,
Evas_Model_Load_Save_Data data)
{
evas_canvas3d_mesh_index_data_copy_set(mesh, EVAS_CANVAS3D_INDEX_FORMAT_UNSIGNED_SHORT, header.indices_count, data.indices);
}
Eina_Bool
evas_model_load_allocate_data_due_to_header(Evas_Model_Load_Save_Header header,
Evas_Model_Load_Save_Data *data)
{
if (header.existence_of_positions)
data->positions = malloc(header.vertices_count * 3 * sizeof(float));
if (header.existence_of_normals)
data->normals = malloc(header.vertices_count * 3 * sizeof(float));
if (header.existence_of_tex_coords)
data->tex_coords = malloc(header.vertices_count * 2 * sizeof(float));
if (header.existence_of_colors)
data->colors = malloc(header.vertices_count * 3 * sizeof(float));
data->indices = malloc(header.indices_count * sizeof(unsigned short));
if ((header.existence_of_positions && (data->positions == NULL)) ||
(header.existence_of_normals && (data->normals == NULL)) ||
(header.existence_of_tex_coords && (data->tex_coords == NULL)) ||
(header.existence_of_colors && (data->colors == NULL)) ||
(data->indices == NULL))
{
free(data->positions);
free(data->normals);
free(data->tex_coords);
free(data->colors);
free(data->indices);
return EINA_FALSE;
}
return EINA_TRUE;
}
void
evas_model_load_aabb_add_to_frame(Evas_Canvas3D_Mesh *mesh,
int frame,
Evas_Model_Load_Save_Stride stride)
{
Evas_Canvas3D_Mesh_Data *pd;
pd = efl_data_scope_get(mesh, EVAS_CANVAS3D_MESH_CLASS);
if (!evas_canvas3d_mesh_aabb_add_to_frame(pd, frame, stride.positions))
{
ERR("Axis-Aligned Bounding Box wasn't added in frame %d ", 0);
}
}
Eina_Bool
evas_model_save_header_from_mesh(Evas_Canvas3D_Mesh_Data *pd,
Evas_Canvas3D_Mesh_Frame *f,
Evas_Model_Load_Save_Header *header)
{
header->indices_count = pd->index_count;
if (header->indices_count % 3 != 0)
{
printf("Index count is %d. It cannot be divided to triangles correctly.\n",
header->indices_count);
return EINA_FALSE;
}
header->existence_of_positions = (f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION].data != NULL);
header->existence_of_normals = (f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL].data != NULL);
header->existence_of_tex_coords = (f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD].data != NULL);
header->existence_of_colors = (f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR].data != NULL);
header->vertices_count = pd->vertex_count;
return EINA_TRUE;
}
void
evas_model_save_data_from_mesh(Evas_Canvas3D_Mesh_Data *pd,
Evas_Canvas3D_Mesh_Frame *f,
Evas_Model_Load_Save_Header header,
Evas_Model_Load_Save_Data *data)
{
int i;
if (header.existence_of_positions)
data->positions = (float*)(&f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION])->data;
if (header.existence_of_normals)
data->normals = (float*)(&f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL])->data;
if (header.existence_of_tex_coords)
data->tex_coords = (float*)(&f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD])->data;
if (header.existence_of_colors)
data->colors = (float*)(&f->vertices[EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR])->data;
SAVE_MESH_INDICES_COPY
}
void
evas_model_save_data_copy_from_mesh(Evas_Canvas3D_Mesh_Data *pd,
Evas_Canvas3D_Mesh_Frame *f,
Evas_Model_Load_Save_Header header,
Evas_Model_Load_Save_Data *data)
{
int i;
#define SAVE_MESH_VERTICES_COPY(name, vertex_data_type) \
if (header.existence_of_##name) \
memcpy(data->name, \
(&f->vertices[vertex_data_type])->data, \
header.vertices_count);
SAVE_MESH_VERTICES_COPY(positions, EVAS_CANVAS3D_VERTEX_ATTRIB_POSITION)
SAVE_MESH_VERTICES_COPY(normals, EVAS_CANVAS3D_VERTEX_ATTRIB_NORMAL)
SAVE_MESH_VERTICES_COPY(tex_coords, EVAS_CANVAS3D_VERTEX_ATTRIB_TEXCOORD)
SAVE_MESH_VERTICES_COPY(colors, EVAS_CANVAS3D_VERTEX_ATTRIB_COLOR)
#undef SAVE_MESH_VERTICES_COPY
SAVE_MESH_INDICES_COPY
}