Model_save_load. Step 2. Replace and rename savers/loaders.

This commit is contained in:
Bogdan Devichev 2014-11-27 13:27:01 +02:00
parent 7183fb6555
commit 2f502b7f0e
15 changed files with 1786 additions and 1790 deletions

View File

@ -188,15 +188,18 @@ lib/evas/canvas/evas_3d_camera.c \
lib/evas/canvas/evas_3d_light.c \
lib/evas/canvas/evas_3d_mesh.c \
lib/evas/canvas/evas_3d_texture.c \
lib/evas/canvas/evas_3d_material.c \
lib/evas/canvas/evas_3d_mesh_loader_md2.c \
lib/evas/canvas/evas_3d_mesh_loader_obj.c \
lib/evas/canvas/evas_3d_mesh_saver_obj.c \
lib/evas/canvas/evas_3d_mesh_loader_eet.c \
lib/evas/canvas/evas_3d_mesh_saver_eet.c \
lib/evas/canvas/evas_3d_eet.c \
lib/evas/canvas/evas_3d_mesh_loader_ply.c \
lib/evas/canvas/evas_3d_mesh_saver_ply.c
lib/evas/canvas/evas_3d_material.c
# Model savers/loaders (will be replaced to modules in next commits)
lib_evas_libevas_la_SOURCES += \
modules/evas/model_loaders/eet/evas_model_load_eet.c \
modules/evas/model_loaders/md2/evas_model_load_md2.c \
modules/evas/model_loaders/obj/evas_model_load_obj.c \
modules/evas/model_loaders/ply/evas_model_load_ply.c \
modules/evas/model_savers/eet/evas_model_save_eet.c \
modules/evas/model_savers/obj/evas_model_save_obj.c \
modules/evas/model_savers/ply/evas_model_save_ply.c \
lib/evas/canvas/evas_3d_eet.c
# Engine
lib_evas_libevas_la_SOURCES += \

View File

@ -1,131 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <Eo.h>
#include <stdio.h>
#include "evas_common_private.h"
#include "evas_private.h"
extern Evas_3D_File_Eet* eet_file;
extern const char EVAS_3D_FILE_CACHE_FILE_ENTRY[];
extern Eet_Data_Descriptor *_file_descriptor;
void
_set_geometry_to_mesh_from_eet_file(Evas_3D_Mesh *mesh,
Evas_3D_Mesh_Eet *eet_mesh)
{
float *pos, *nor, *tex;
int stride_pos, stride_nor, stride_tex, j;
eo_do(mesh,
evas_3d_mesh_vertex_count_set(eet_mesh->geometries->vertices_count),
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES),
evas_3d_mesh_frame_add(0),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_POSITION, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
pos = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_POSITION),
nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION),
stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL),
stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD));
if (stride_pos == 0) stride_pos = sizeof(float) * 3;
if (stride_nor == 0) stride_nor = sizeof(float) * 3;
if (stride_tex == 0) stride_tex = sizeof(float) * 2;
/* set data to vertex buffer */
for (j = 0; j < eet_mesh->geometries->vertices_count; j++)
{
float *p, *n, *t;
p = (float *)((char *)pos + stride_pos * j);
n = (float *)((char *)nor + stride_nor * j);
t = (float *)((char *)tex + stride_tex * j);
p[0] = eet_mesh->geometries->vertices[j].position.x;
p[1] = eet_mesh->geometries->vertices[j].position.y;
p[2] = eet_mesh->geometries->vertices[j].position.z;
n[0] = eet_mesh->geometries->vertices[j].normal.x;
n[1] = eet_mesh->geometries->vertices[j].normal.y;
n[2] = eet_mesh->geometries->vertices[j].normal.z;
t[0] = eet_mesh->geometries->vertices[j].texcoord.x;
t[1] = eet_mesh->geometries->vertices[j].texcoord.y;
}
/* unmap vertex buffer */
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD));
}
void
_set_material_to_mesh_from_eet_file(Evas_3D_Mesh *mesh,
Evas_3D_Mesh_Eet *eet_mesh)
{
Evas_3D_Object_Data *pd = eo_data_scope_get(mesh, EVAS_3D_OBJECT_CLASS);
Eo *material = NULL;
material = eo_add(EVAS_3D_MATERIAL_CLASS, pd->evas);
eo_do(material,
evas_3d_material_enable_set(EVAS_3D_MATERIAL_AMBIENT,
!!(eet_mesh->materials->colors[0].a > 0)),
evas_3d_material_enable_set(EVAS_3D_MATERIAL_DIFFUSE,
!!(eet_mesh->materials->colors[1].a > 0)),
evas_3d_material_enable_set(EVAS_3D_MATERIAL_SPECULAR,
!!(eet_mesh->materials->colors[2].a > 0)),
evas_3d_material_enable_set(EVAS_3D_MATERIAL_NORMAL, EINA_TRUE),
evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT,
eet_mesh->materials->colors[0].r,
eet_mesh->materials->colors[0].g,
eet_mesh->materials->colors[0].b,
eet_mesh->materials->colors[0].a),
evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE,
eet_mesh->materials->colors[1].r,
eet_mesh->materials->colors[1].g,
eet_mesh->materials->colors[1].b,
eet_mesh->materials->colors[1].a),
evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR,
eet_mesh->materials->colors[2].r,
eet_mesh->materials->colors[2].g,
eet_mesh->materials->colors[2].b,
eet_mesh->materials->colors[2].a),
evas_3d_material_shininess_set(eet_mesh->materials->shininess));
eo_do(mesh, evas_3d_mesh_frame_material_set(0, material));
}
void
evas_3d_mesh_file_eet_set(Evas_3D_Mesh *mesh, const char *file)
{
Eet_File *ef;
_evas_3d_eet_file_init();
ef = eet_open(file, EET_FILE_MODE_READ);
eet_file = eet_data_read(ef,
_file_descriptor,
EVAS_3D_FILE_CACHE_FILE_ENTRY);
eet_close(ef);
if ((eet_file->mesh == NULL) || (eet_file->header == NULL))
{
ERR("Reading of file is failed.");
_evas_3d_eet_file_free();
return;
}
_set_geometry_to_mesh_from_eet_file(mesh, eet_file->mesh);
_set_material_to_mesh_from_eet_file(mesh, eet_file->mesh);
_evas_3d_eet_file_free();
}

View File

@ -1,446 +0,0 @@
#include "evas_common_private.h"
#include "evas_private.h"
#define PACKED __attribute__((__packed__))
#define MD2_MAGIC_NUMBER 844121161
#define MD2_VERSION 8
#define MD2_FRAME_SCALE 256
/* Structures for reading data from file. */
typedef struct _MD2_Header MD2_Header;
typedef struct _MD2_Vertex MD2_Vertex;
typedef struct _MD2_Frame MD2_Frame;
typedef struct _MD2_Triangle MD2_Triangle;
typedef struct _MD2_Texcoord MD2_Texcoord;
struct PACKED _MD2_Header
{
int magic;
int version;
int skin_width;
int skin_height;
int frame_size;
int skins_count;
int vertex_count;
int texcoord_count;
int triangle_count;
int glcmd_count;
int frame_count;
int offset_skins;
int offset_texcoords;
int offset_triangles;
int offset_frames;
int offset_glcmds;
int offset_end;
};
struct PACKED _MD2_Vertex
{
unsigned char pos[3];
unsigned char normal_idx;
};
struct PACKED _MD2_Frame
{
float scale[3];
float trans[3];
char name[16];
MD2_Vertex vertices[1];
};
struct PACKED _MD2_Triangle
{
unsigned short vertex_idx[3];
unsigned short texcoord_idx[3];
};
struct PACKED _MD2_Texcoord
{
short s;
short t;
};
typedef struct _MD2_Loader
{
Eina_File *file;
char *map;
int size;
int skin_width;
int skin_height;
int frame_count;
int frame_size;
char *frames;
int vertex_count;
int triangle_count;
int texcoord_count;
MD2_Triangle *triangles;
MD2_Texcoord *texcoords;
} MD2_Loader;
static const float normal_table[162][3] =
{
{-0.525731f, 0.000000f, 0.850651f},
{-0.442863f, 0.238856f, 0.864188f},
{-0.295242f, 0.000000f, 0.955423f},
{-0.309017f, 0.500000f, 0.809017f},
{-0.162460f, 0.262866f, 0.951056f},
{ 0.000000f, 0.000000f, 1.000000f},
{ 0.000000f, 0.850651f, 0.525731f},
{-0.147621f, 0.716567f, 0.681718f},
{ 0.147621f, 0.716567f, 0.681718f},
{ 0.000000f, 0.525731f, 0.850651f},
{ 0.309017f, 0.500000f, 0.809017f},
{ 0.525731f, 0.000000f, 0.850651f},
{ 0.295242f, 0.000000f, 0.955423f},
{ 0.442863f, 0.238856f, 0.864188f},
{ 0.162460f, 0.262866f, 0.951056f},
{-0.681718f, 0.147621f, 0.716567f},
{-0.809017f, 0.309017f, 0.500000f},
{-0.587785f, 0.425325f, 0.688191f},
{-0.850651f, 0.525731f, 0.000000f},
{-0.864188f, 0.442863f, 0.238856f},
{-0.716567f, 0.681718f, 0.147621f},
{-0.688191f, 0.587785f, 0.425325f},
{-0.500000f, 0.809017f, 0.309017f},
{-0.238856f, 0.864188f, 0.442863f},
{-0.425325f, 0.688191f, 0.587785f},
{-0.716567f, 0.681718f, -0.147621f},
{-0.500000f, 0.809017f, -0.309017f},
{-0.525731f, 0.850651f, 0.000000f},
{ 0.000000f, 0.850651f, -0.525731f},
{-0.238856f, 0.864188f, -0.442863f},
{ 0.000000f, 0.955423f, -0.295242f},
{-0.262866f, 0.951056f, -0.162460f},
{ 0.000000f, 1.000000f, 0.000000f},
{ 0.000000f, 0.955423f, 0.295242f},
{-0.262866f, 0.951056f, 0.162460f},
{ 0.238856f, 0.864188f, 0.442863f},
{ 0.262866f, 0.951056f, 0.162460f},
{ 0.500000f, 0.809017f, 0.309017f},
{ 0.238856f, 0.864188f, -0.442863f},
{ 0.262866f, 0.951056f, -0.162460f},
{ 0.500000f, 0.809017f, -0.309017f},
{ 0.850651f, 0.525731f, 0.000000f},
{ 0.716567f, 0.681718f, 0.147621f},
{ 0.716567f, 0.681718f, -0.147621f},
{ 0.525731f, 0.850651f, 0.000000f},
{ 0.425325f, 0.688191f, 0.587785f},
{ 0.864188f, 0.442863f, 0.238856f},
{ 0.688191f, 0.587785f, 0.425325f},
{ 0.809017f, 0.309017f, 0.500000f},
{ 0.681718f, 0.147621f, 0.716567f},
{ 0.587785f, 0.425325f, 0.688191f},
{ 0.955423f, 0.295242f, 0.000000f},
{ 1.000000f, 0.000000f, 0.000000f},
{ 0.951056f, 0.162460f, 0.262866f},
{ 0.850651f, -0.525731f, 0.000000f},
{ 0.955423f, -0.295242f, 0.000000f},
{ 0.864188f, -0.442863f, 0.238856f},
{ 0.951056f, -0.162460f, 0.262866f},
{ 0.809017f, -0.309017f, 0.500000f},
{ 0.681718f, -0.147621f, 0.716567f},
{ 0.850651f, 0.000000f, 0.525731f},
{ 0.864188f, 0.442863f, -0.238856f},
{ 0.809017f, 0.309017f, -0.500000f},
{ 0.951056f, 0.162460f, -0.262866f},
{ 0.525731f, 0.000000f, -0.850651f},
{ 0.681718f, 0.147621f, -0.716567f},
{ 0.681718f, -0.147621f, -0.716567f},
{ 0.850651f, 0.000000f, -0.525731f},
{ 0.809017f, -0.309017f, -0.500000f},
{ 0.864188f, -0.442863f, -0.238856f},
{ 0.951056f, -0.162460f, -0.262866f},
{ 0.147621f, 0.716567f, -0.681718f},
{ 0.309017f, 0.500000f, -0.809017f},
{ 0.425325f, 0.688191f, -0.587785f},
{ 0.442863f, 0.238856f, -0.864188f},
{ 0.587785f, 0.425325f, -0.688191f},
{ 0.688191f, 0.587785f, -0.425325f},
{-0.147621f, 0.716567f, -0.681718f},
{-0.309017f, 0.500000f, -0.809017f},
{ 0.000000f, 0.525731f, -0.850651f},
{-0.525731f, 0.000000f, -0.850651f},
{-0.442863f, 0.238856f, -0.864188f},
{-0.295242f, 0.000000f, -0.955423f},
{-0.162460f, 0.262866f, -0.951056f},
{ 0.000000f, 0.000000f, -1.000000f},
{ 0.295242f, 0.000000f, -0.955423f},
{ 0.162460f, 0.262866f, -0.951056f},
{-0.442863f, -0.238856f, -0.864188f},
{-0.309017f, -0.500000f, -0.809017f},
{-0.162460f, -0.262866f, -0.951056f},
{ 0.000000f, -0.850651f, -0.525731f},
{-0.147621f, -0.716567f, -0.681718f},
{ 0.147621f, -0.716567f, -0.681718f},
{ 0.000000f, -0.525731f, -0.850651f},
{ 0.309017f, -0.500000f, -0.809017f},
{ 0.442863f, -0.238856f, -0.864188f},
{ 0.162460f, -0.262866f, -0.951056f},
{ 0.238856f, -0.864188f, -0.442863f},
{ 0.500000f, -0.809017f, -0.309017f},
{ 0.425325f, -0.688191f, -0.587785f},
{ 0.716567f, -0.681718f, -0.147621f},
{ 0.688191f, -0.587785f, -0.425325f},
{ 0.587785f, -0.425325f, -0.688191f},
{ 0.000000f, -0.955423f, -0.295242f},
{ 0.000000f, -1.000000f, 0.000000f},
{ 0.262866f, -0.951056f, -0.162460f},
{ 0.000000f, -0.850651f, 0.525731f},
{ 0.000000f, -0.955423f, 0.295242f},
{ 0.238856f, -0.864188f, 0.442863f},
{ 0.262866f, -0.951056f, 0.162460f},
{ 0.500000f, -0.809017f, 0.309017f},
{ 0.716567f, -0.681718f, 0.147621f},
{ 0.525731f, -0.850651f, 0.000000f},
{-0.238856f, -0.864188f, -0.442863f},
{-0.500000f, -0.809017f, -0.309017f},
{-0.262866f, -0.951056f, -0.162460f},
{-0.850651f, -0.525731f, 0.000000f},
{-0.716567f, -0.681718f, -0.147621f},
{-0.716567f, -0.681718f, 0.147621f},
{-0.525731f, -0.850651f, 0.000000f},
{-0.500000f, -0.809017f, 0.309017f},
{-0.238856f, -0.864188f, 0.442863f},
{-0.262866f, -0.951056f, 0.162460f},
{-0.864188f, -0.442863f, 0.238856f},
{-0.809017f, -0.309017f, 0.500000f},
{-0.688191f, -0.587785f, 0.425325f},
{-0.681718f, -0.147621f, 0.716567f},
{-0.442863f, -0.238856f, 0.864188f},
{-0.587785f, -0.425325f, 0.688191f},
{-0.309017f, -0.500000f, 0.809017f},
{-0.147621f, -0.716567f, 0.681718f},
{-0.425325f, -0.688191f, 0.587785f},
{-0.162460f, -0.262866f, 0.951056f},
{ 0.442863f, -0.238856f, 0.864188f},
{ 0.162460f, -0.262866f, 0.951056f},
{ 0.309017f, -0.500000f, 0.809017f},
{ 0.147621f, -0.716567f, 0.681718f},
{ 0.000000f, -0.525731f, 0.850651f},
{ 0.425325f, -0.688191f, 0.587785f},
{ 0.587785f, -0.425325f, 0.688191f},
{ 0.688191f, -0.587785f, 0.425325f},
{-0.955423f, 0.295242f, 0.000000f},
{-0.951056f, 0.162460f, 0.262866f},
{-1.000000f, 0.000000f, 0.000000f},
{-0.850651f, 0.000000f, 0.525731f},
{-0.955423f, -0.295242f, 0.000000f},
{-0.951056f, -0.162460f, 0.262866f},
{-0.864188f, 0.442863f, -0.238856f},
{-0.951056f, 0.162460f, -0.262866f},
{-0.809017f, 0.309017f, -0.500000f},
{-0.864188f, -0.442863f, -0.238856f},
{-0.951056f, -0.162460f, -0.262866f},
{-0.809017f, -0.309017f, -0.500000f},
{-0.681718f, 0.147621f, -0.716567f},
{-0.681718f, -0.147621f, -0.716567f},
{-0.850651f, 0.000000f, -0.525731f},
{-0.688191f, 0.587785f, -0.425325f},
{-0.587785f, 0.425325f, -0.688191f},
{-0.425325f, 0.688191f, -0.587785f},
{-0.425325f, -0.688191f, -0.587785f},
{-0.587785f, -0.425325f, -0.688191f},
{-0.688191f, -0.587785f, -0.425325f},
};
static inline void
_md2_loader_fini(MD2_Loader *loader)
{
if (loader->map)
{
eina_file_map_free(loader->file, loader->map);
loader->map = NULL;
}
if (loader->file)
{
eina_file_close(loader->file);
loader->file = NULL;
}
}
static inline Eina_Bool
_md2_loader_init(MD2_Loader *loader, const char *file)
{
MD2_Header header;
memset(loader, 0x00, sizeof(MD2_Loader));
/* Open given file. */
loader->file = eina_file_open(file, 0);
if (loader->file == NULL)
{
ERR("Failed to open file %s\n", file);
goto error;
}
/* Check file size. We require a file larger than MD2 header size. */
loader->size = eina_file_size_get(loader->file);
if (loader->size < (int)sizeof(MD2_Header))
goto error;
/* Map the file. */
loader->map = eina_file_map_all(loader->file, EINA_FILE_SEQUENTIAL);
if (loader->map == NULL)
goto error;
/* Read header. */
memcpy(&header, loader->map, sizeof(MD2_Header));
/* Check identity */
if (header.magic != MD2_MAGIC_NUMBER || header.version != MD2_VERSION)
goto error;
/* Check offsets */
if (header.offset_skins > header.offset_end)
goto error;
if (header.offset_texcoords > header.offset_end)
goto error;
if (header.offset_triangles > header.offset_end)
goto error;
if (header.offset_frames > header.offset_end)
goto error;
if (header.offset_glcmds > header.offset_end)
goto error;
if (header.offset_end > loader->size)
goto error;
loader->skin_width = header.skin_width;
loader->skin_height = header.skin_height;
loader->frame_count = header.frame_count;
loader->frame_size = header.frame_size;
loader->frames = loader->map + header.offset_frames;
loader->vertex_count = header.vertex_count;
loader->triangle_count = header.triangle_count;
loader->texcoord_count = header.texcoord_count;
loader->triangles = (MD2_Triangle *)(loader->map + header.offset_triangles);
loader->texcoords = (MD2_Texcoord *)(loader->map + header.offset_texcoords);
return EINA_TRUE;
error:
_md2_loader_fini(loader);
return EINA_FALSE;
}
void
evas_3d_mesh_file_md2_set(Evas_3D_Mesh *mesh, const char *file)
{
MD2_Loader loader;
int i, j, k;
float *pos, *nor, *tex;
int stride_pos, stride_nor, stride_tex;
float s_scale, t_scale;
Evas_3D_Mesh_Data *pd;
/* Initialize MD2 loader (Open file and read MD2 head ant etc) */
if (!_md2_loader_init(&loader, file))
{
ERR("Failed to initialize MD2 loader.");
return;
}
s_scale = 1.0 / (float)(loader.skin_width - 1);
t_scale = 1.0 / (float)(loader.skin_height - 1);
eo_do(mesh,
evas_3d_mesh_vertex_count_set(loader.triangle_count * 3),
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES));
/* Load frames */
for (i = 0; i < loader.frame_count; i++)
{
const MD2_Frame *frame = (const MD2_Frame *)(loader.frames + loader.frame_size * i);
int f = i * MD2_FRAME_SCALE;
eo_do(mesh,
/* Add a mesh frame. */
evas_3d_mesh_frame_add(f),
/* Allocate vertex buffer for the frame. */
evas_3d_mesh_frame_vertex_data_copy_set(f, EVAS_3D_VERTEX_POSITION, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(f, EVAS_3D_VERTEX_NORMAL, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(f, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
/* Map vertex buffer. */
pos = (float *)evas_3d_mesh_frame_vertex_data_map(f, EVAS_3D_VERTEX_POSITION),
nor = (float *)evas_3d_mesh_frame_vertex_data_map(f, EVAS_3D_VERTEX_NORMAL),
tex = (float *)evas_3d_mesh_frame_vertex_data_map(f, EVAS_3D_VERTEX_TEXCOORD),
stride_pos = evas_3d_mesh_frame_vertex_stride_get(f, EVAS_3D_VERTEX_POSITION),
stride_nor = evas_3d_mesh_frame_vertex_stride_get(f, EVAS_3D_VERTEX_NORMAL),
stride_tex = evas_3d_mesh_frame_vertex_stride_get(f, EVAS_3D_VERTEX_TEXCOORD));
if (stride_pos == 0)
stride_pos = sizeof(float) * 3;
if (stride_nor == 0)
stride_nor = sizeof(float) * 3;
if (stride_tex == 0)
stride_tex = sizeof(float) * 2;
for (j = 0; j < loader.triangle_count; j++)
{
const MD2_Triangle *tri = &loader.triangles[j];
for (k = 0; k < 3; k++)
{
unsigned int tidx, vidx;
float *p, *n, *t;
tidx = tri->texcoord_idx[k];
vidx = tri->vertex_idx[k];
p = (float *)((char *)pos + stride_pos * (j * 3 + k));
n = (float *)((char *)nor + stride_nor * (j * 3 + k));
t = (float *)((char *)tex + stride_tex * (j * 3 + k));
p[0] = frame->vertices[vidx].pos[0] * frame->scale[0] + frame->trans[0];
p[1] = frame->vertices[vidx].pos[1] * frame->scale[1] + frame->trans[1];
p[2] = frame->vertices[vidx].pos[2] * frame->scale[2] + frame->trans[2];
n[0] = normal_table[frame->vertices[vidx].normal_idx][0];
n[1] = normal_table[frame->vertices[vidx].normal_idx][1];
n[2] = normal_table[frame->vertices[vidx].normal_idx][2];
t[0] = loader.texcoords[tidx].s * s_scale;
t[1] = 1.0 - loader.texcoords[tidx].t * t_scale;
}
}
/* Unmap vertex buffer. */
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(f, EVAS_3D_VERTEX_POSITION),
evas_3d_mesh_frame_vertex_data_unmap(f, EVAS_3D_VERTEX_NORMAL),
evas_3d_mesh_frame_vertex_data_unmap(f, EVAS_3D_VERTEX_TEXCOORD));
pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
if (!evas_3d_mesh_aabb_add_to_frame(pd, f, stride_pos))
{
ERR("Axis-Aligned Bounding Box wasn't added in frame %d ", f);
}
}
_md2_loader_fini(&loader);
}

View File

@ -1,401 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include "stdio.h"
#include "evas_common_private.h"
#include "evas_private.h"
/* set value to position [x][y] to array name which have. */
#define ARRAY_2D(name, x, y, count_y) (*(name + x * count_y + y))
/* read 3 float values in string and put it in array */
#define PUT_DATA_TO_ARRAY(array_name, name) \
sscanf (current,"%f %f %f", \
&ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 0, 3), \
&ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 1, 3), \
&ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 2, 3)); \
counts.current_##name##_counter++;
/* Structures for reading data from file. */
typedef struct _OBJ_Counts OBJ_Counts;
struct _OBJ_Counts
{
int _vertex_counter;
int _normal_counter;
int _texture_point_counter;
int _triangles_counter;
int current_vertex_counter;
int current_normal_counter;
int current_texture_point_counter;
int current_triangles_counter;
Eina_Bool existence_of_normal;
Eina_Bool existence_of_tex_point;
};
static inline char*
_file_to_buf(const char *file, long *length)//prepare text file for reading
{
FILE *file_for_print;
char *buf;
int unused __attribute__((unused));//this variable fixes warning "ignoring return value of fread"
*length = 0;
file_for_print = fopen(file, "rb");
if (!file_for_print) return NULL;
fseek(file_for_print, 0, SEEK_END);//set file_for_print to the end of file
*length = ftell(file_for_print);//set current position of file_for_print
if (*length < 0)
{
fclose(file_for_print);
return NULL;
}
buf = malloc(*length + 1);
fseek(file_for_print, 0, SEEK_SET);//set file_for_print to the begining of file
unused = fread(buf, *length, 1, file_for_print);
fclose(file_for_print);
buf[*length] = '\0';
return buf;
}
/* create new counter */
static inline OBJ_Counts
_new_count_elements()
{
OBJ_Counts counts;
counts._vertex_counter = 0;
counts._normal_counter = 0;
counts._texture_point_counter = 0;
counts._triangles_counter = 0;
counts.current_vertex_counter = 0;
counts.current_normal_counter = 0;
counts.current_texture_point_counter = 0;
counts.current_triangles_counter = 0;
counts.existence_of_normal = EINA_FALSE;
counts.existence_of_tex_point = EINA_FALSE;
return counts;
}
/* count triangles in face */
static void
_analyze_face_line(char * face_analyzer,
int * count_of_triangles_in_line)
{
int polygon_checker = -2;
Eina_Bool previous_is_space = EINA_TRUE;
while ((*face_analyzer != '\n') && (*face_analyzer != '#'))
{
if (*face_analyzer == ' ')
{
previous_is_space = EINA_TRUE;
}
else if ((previous_is_space) && (*face_analyzer >= '0') && (*face_analyzer <= '9'))
{
polygon_checker++;
previous_is_space = EINA_FALSE;
}
face_analyzer++;
}
*count_of_triangles_in_line = polygon_checker;
}
static inline OBJ_Counts
_count_elements(char *start, long length)//count elements of mesh in .obj
{
OBJ_Counts counts = _new_count_elements();
char * current = start;
int polygon_checker = -2;//polygons with n vertices can be represented as n-2 triangles
Eina_Bool will_check_next_char = EINA_FALSE;
Eina_Bool first_char_is_v = EINA_FALSE;
Eina_Bool first_char_is_f = EINA_FALSE;
Eina_Bool previous_is_space = EINA_FALSE;
long i = 0;
/* count elements of mesh in .obj */
for (; length > i; i++)
{
if (will_check_next_char)
{
if (first_char_is_v)
{
switch (*current)
{
case ' ':
counts._vertex_counter++;
break;
case 't':
counts._texture_point_counter++;
counts.existence_of_tex_point = EINA_TRUE;
break;
case 'n':
counts._normal_counter++;
counts.existence_of_normal = EINA_TRUE;
break;
default:
break;
}
first_char_is_v = EINA_FALSE;
will_check_next_char = EINA_FALSE;
}
else if (first_char_is_f)
{
switch (*current)
{
case '\n':
first_char_is_f = EINA_FALSE;
counts._triangles_counter += polygon_checker;
polygon_checker = -2;
previous_is_space = EINA_FALSE;
break;
case '#':
first_char_is_f = EINA_FALSE;
counts._triangles_counter += polygon_checker;
polygon_checker = -2;
previous_is_space = EINA_FALSE;
break;
case ' ':
previous_is_space = EINA_TRUE;
break;
default:
if ((previous_is_space) && (*current >= '0') && (*current <= '9'))
{
polygon_checker++;
previous_is_space = EINA_FALSE;
}
break;
}
}
else
{
switch (*current)
{
case 'v':
first_char_is_v = EINA_TRUE;
break;
case 'f':
first_char_is_f = EINA_TRUE;
break;
case 'm':
will_check_next_char = EINA_FALSE;
break;
default:
will_check_next_char = EINA_FALSE;
break;
}
}
}
else if (*current == '\n')
{
will_check_next_char = EINA_TRUE;
}
current++;
}
return counts;
}
void
evas_3d_mesh_file_obj_set(Evas_3D_Mesh *mesh, const char *file)
{
long length, i;
char * start = _file_to_buf(file, &length);
OBJ_Counts counts = _count_elements(start, length);//count elements of mesh in .obj
Eina_Bool will_check_next_char = EINA_FALSE;
Eina_Bool first_char_is_v = EINA_FALSE;
Eina_Bool first_char_is_f = EINA_FALSE;
float *pos, *nor, *tex;
int stride_pos, stride_nor, stride_tex;
int j, k;
char * current;
float *_vertices_obj = malloc(counts._vertex_counter * 3 * sizeof(float));
float *_normales_obj = malloc(counts._normal_counter * 3 * sizeof(float));
float *_tex_coords_obj = malloc(counts._texture_point_counter * 3 * sizeof(float));
/* triangle has 3 points, every point has 3(vertix, texture and normal) coord */
int *_triangles = malloc(counts._triangles_counter * 9 * sizeof(int));
if ((start == NULL) || (_vertices_obj == NULL) ||
(_normales_obj == NULL) || (_tex_coords_obj == NULL) || (_triangles == NULL))
{
ERR("Allocate memory is failed.");
free(start);
free(_vertices_obj);
free(_normales_obj);
free(_tex_coords_obj);
free(_triangles);
return;
}
current = start;
i = 0;
/* put data to arrays */
for (; length > i; i++)
{
if (will_check_next_char)
{
if (first_char_is_v)
{
switch (*current)
{
case ' ':
PUT_DATA_TO_ARRAY(vertices, vertex)
i--;
break;
case 't':
current++;
PUT_DATA_TO_ARRAY(tex_coords, texture_point)
break;
case 'n':
current++;
PUT_DATA_TO_ARRAY(normales, normal)
break;
default:
break;
}
first_char_is_v = EINA_FALSE;
will_check_next_char = EINA_FALSE;
}
else if (first_char_is_f)
{
char * auxiliary_pointer = current;
int count_of_triangles_in_line;
_analyze_face_line(auxiliary_pointer,
&count_of_triangles_in_line);
current++;
i++;
int first_pos, first_tex, first_norm;
sscanf (current,"%i/%i/%i",
&first_pos,
&first_tex,
&first_norm);
do
{
current++;
i++;
}
while (*current != ' ');
current++;
i++;
for (j = 0; j < count_of_triangles_in_line; j++)
{
auxiliary_pointer = current;
ARRAY_2D(_triangles, counts.current_triangles_counter, 0, 9) = first_pos;
ARRAY_2D(_triangles, counts.current_triangles_counter, 1, 9) = first_tex;
ARRAY_2D(_triangles, counts.current_triangles_counter, 2, 9) = first_norm;
sscanf (auxiliary_pointer,"%i/%i/%i %i/%i/%i",
&ARRAY_2D(_triangles, counts.current_triangles_counter, 3, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 4, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 5, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 6, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 7, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 8, 9));
while (*current != ' ')
{
current++;
i++;
}
counts.current_triangles_counter++;
}
first_char_is_f = EINA_FALSE;
}
else
{
switch (*current)
{
case 'v':
first_char_is_v = EINA_TRUE;
break;
case 'f':
first_char_is_f = EINA_TRUE;
break;
case 'm':
will_check_next_char = EINA_FALSE;
break;
default:
will_check_next_char = EINA_FALSE;
break;
}
}
}
else if (*current == '\n')
{
will_check_next_char = EINA_TRUE;
}
current++;
}
free(start);
/* prepare of mesh and take pointers to data which must be read */
eo_do(mesh,
evas_3d_mesh_vertex_count_set(counts._triangles_counter * 3),
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES),
evas_3d_mesh_frame_add(0),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_POSITION, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
pos = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_POSITION),
nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION),
stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL),
stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD));
if (stride_pos == 0) stride_pos = sizeof(float) * 3;
if (stride_nor == 0) stride_nor = sizeof(float) * 3;
if (stride_tex == 0) stride_tex = sizeof(float) * 2;
for (j = 0; j < counts._triangles_counter; j++)
{
for (k = 0; k < 3; k++)
{
float *p, *n, *t;
p = (float *)((char *)pos + stride_pos * (j * 3 + k));
n = (float *)((char *)nor + stride_nor * (j * 3 + k));
t = (float *)((char *)tex + stride_tex * (j * 3 + k));
p[0] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 0, 3);
p[1] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 1, 3);
p[2] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 2, 3);
n[0] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 0, 3);
n[1] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 1, 3);
n[2] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 2, 3);
t[0] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 0, 3);
t[1] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 1, 3);
}
}
free(_vertices_obj);
free(_normales_obj);
free(_tex_coords_obj);
free(_triangles);
/* Unmap vertex buffer. */
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD));
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
if (!evas_3d_mesh_aabb_add_to_frame(pd, 0, stride_pos))
{
ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0);
}
}

View File

@ -1,401 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include "stdio.h"
#include "evas_common_private.h"
#include "evas_private.h"
#include <Eina.h>
/* set value to position [x][y] to array name which have. */
#define ARRAY_2D(name, x, y, count_y) (*(name + x * count_y + y))
/* Structures for reading data from file. */
typedef struct _PLY_Header PLY_Header;
struct _PLY_Header
{
int vertices_count;
int triangles_count;
Eina_Bool existence_of_geometries;
Eina_Bool existence_of_normals;
Eina_Bool existence_of_texcoords;
Eina_Bool existence_of_colors;
};
static inline char*
_file_to_buf(const char *file, long *length)//prepare text file for reading
{
FILE *file_for_print;
char *buf;
int unused __attribute__((unused));//this variable fixes warning "ignoring return value of fread"
*length = 0;
file_for_print = fopen(file, "rb");
if (!file_for_print) return NULL;
fseek(file_for_print, 0, SEEK_END);//set file_for_print to the end of file
*length = ftell(file_for_print);//set current position of file_for_print
buf = malloc(*length + 1);
fseek(file_for_print, 0, SEEK_SET);//set file_for_print to the begining of file
unused = fread(buf, *length, 1, file_for_print);
fclose(file_for_print);
buf[*length] = '\0';
return buf;
}
/* create new header */
static inline PLY_Header
_new_ply_header()
{
PLY_Header header;
header.vertices_count = 0;
header.triangles_count = 0;
header.existence_of_geometries = EINA_FALSE;
header.existence_of_normals = EINA_FALSE;
header.existence_of_texcoords = EINA_FALSE;
header.existence_of_colors = EINA_FALSE;
return header;
}
static inline char *
_to_next_line(char *current)
{
while (*current != '\n') current++;
current++;
return current;
}
static inline char *
_to_begin_of_line(char *current)
{
while (*current != '\n') current--;
current++;
return current;
}
static inline char *
_to_next_number(char *current, int count)
{
int i;
for (i = 0; i < count; i++)
{
while (*current != ' ') current++;
current++;
}
return current;
}
static inline char *
_read_data(float *array, int place, int count, char *current, float divider)
{
int i;
for (i = 0; i < count; i++)
{
sscanf (current,"%f", &ARRAY_2D(array, place, i, count));
ARRAY_2D(array, place, i, count) /= divider;
current = _to_next_number(current, 1);
}
return current;
}
static inline PLY_Header
_read_header(char *start)//Check properties of mesh in .ply file.
{
eina_init();
Eina_Bool reading_vertices = EINA_TRUE, check_next_char = EINA_FALSE;
int vertex_lines, triangles = 0, vertices_in_current_face = 0;
char **helping_pointer;
char *current;
PLY_Header header;
header = _new_ply_header();
helping_pointer = eina_str_split(start, "vertex ", 0);
if (helping_pointer == NULL)
{
ERR("File have not kayword vertex. It is necessary.");
return header;
}
sscanf(helping_pointer[1], "%d", &header.vertices_count);
free(helping_pointer);
helping_pointer = eina_str_split(start, "end_header\n", 0);
if (helping_pointer == NULL)
{
ERR("File have not kayword end_header. It is necessary.");
return header;
}
current = helping_pointer[1];
vertex_lines = header.vertices_count;
while (*current != '\0')
{
if (vertex_lines == 1)
reading_vertices = EINA_FALSE;
if (*current == '\n')
{
if (reading_vertices)
vertex_lines--;
else
check_next_char = EINA_TRUE;
}
if (check_next_char)
{
if ((*current <= '9') && (*current >= '0'))
vertices_in_current_face = (vertices_in_current_face * 10) + (*current - '0');
else if (*current >= ' ')
{
triangles += (vertices_in_current_face - 2);
vertices_in_current_face = 0;
check_next_char = EINA_FALSE;
}
}
current++;
}
header.triangles_count = triangles;
free(helping_pointer);
/* analyse flags used when file was saved in blender */
helping_pointer = eina_str_split(start, "property float ", 0);
if ((helping_pointer[1] != NULL) && (*helping_pointer[1] == 'x') &&
(helping_pointer[2] != NULL) && (*helping_pointer[2] == 'y') &&
(helping_pointer[3] != NULL) && (*helping_pointer[3] == 'z'))
header.existence_of_geometries = EINA_TRUE;
else return header;
if ((helping_pointer[4] != NULL) && (*helping_pointer[4] == 'n') &&
(helping_pointer[5] != NULL) && (*helping_pointer[5] == 'n') &&
(helping_pointer[6] != NULL) && (*helping_pointer[6] == 'n'))
header.existence_of_normals = EINA_TRUE;
if ((header.existence_of_normals &&
((helping_pointer[7] != NULL) && (*helping_pointer[7] == 's') &&
(helping_pointer[8] != NULL) && (*helping_pointer[8] == 't'))) ||
(!header.existence_of_normals &&
((helping_pointer[4] != NULL) && (*helping_pointer[4] == 's') &&
(helping_pointer[5] != NULL) && (*helping_pointer[5] == 't'))))
header.existence_of_texcoords = EINA_TRUE;
helping_pointer = eina_str_split(start, "property uchar ", 0);
if ((helping_pointer[1] != NULL) && (*helping_pointer[1] == 'r') &&
(helping_pointer[2] != NULL) && (*helping_pointer[2] == 'g') &&
(helping_pointer[3] != NULL) && (*helping_pointer[3] == 'b'))
header.existence_of_colors = EINA_TRUE;
free(helping_pointer);
return header;
}
void
evas_3d_mesh_file_ply_set(Evas_3D_Mesh *mesh, const char *file)
{
long length;
Evas_3D_Mesh_Data *pd;
int i = 0, j = 0, k = 0, count_of_triangles_in_line = 0;
float *pos, *nor, *tex, *col;
int stride_pos, stride_nor, stride_tex, stride_col;
char *start, *current;
PLY_Header header;
float *_vertices_ply = NULL, *_normals_ply = NULL, *_tex_coords_ply = NULL, *_colors_ply = NULL;
char **helping_pointer;
start = _file_to_buf(file, &length);
if (start == NULL)
{
ERR("Buffer is empty after preparation file for reading.");
return;
}
header = _read_header(start);
if (!header.existence_of_geometries)
{
ERR("File have not x, y, or z field as the first 3 float fields. They are necessary.");
return;
}
helping_pointer = eina_str_split(start, "end_header\n", 0);
if (helping_pointer == NULL)
{
ERR("File have not kayword end_header. It is necessary.");
return;
}
current = helping_pointer[1];
_vertices_ply = malloc(header.vertices_count * 3 * sizeof(float));
if (header.existence_of_normals)
_normals_ply = malloc(header.vertices_count * 3 * sizeof(float));
if (header.existence_of_texcoords)
_tex_coords_ply = malloc(header.vertices_count * 2 * sizeof(float));
if (header.existence_of_colors)
_colors_ply = malloc(header.vertices_count * 3 * sizeof(float));
int *_triangles = malloc(header.triangles_count * 3 * sizeof(int));
if ((header.existence_of_geometries && (_vertices_ply == NULL)) ||
(header.existence_of_normals && (_normals_ply == NULL)) ||
(header.existence_of_texcoords && (_tex_coords_ply == NULL)) ||
(header.existence_of_colors && (_colors_ply == NULL)) ||
(_triangles == NULL))
{
ERR("Allocate memory is failed.");
free(start);
free(_vertices_ply);
free(_normals_ply);
free(_tex_coords_ply);
free(_colors_ply);
free(_triangles);
return;
}
for (i = 0; i < header.vertices_count; i++)
{
current = _read_data(_vertices_ply, i, 3, current, 1.0);
if (header.existence_of_normals)
current = _read_data(_normals_ply, i, 3, current, 1.0);
if (header.existence_of_texcoords)
current = _read_data(_tex_coords_ply, i, 2, current, 1.0);
if (header.existence_of_colors)
current = _read_data(_colors_ply, i, 3, current, 255.0);
current = _to_begin_of_line(current);
}
for (i = 0; i < header.triangles_count;)
{
sscanf (current,"%d", &count_of_triangles_in_line);
count_of_triangles_in_line -= 2;
current = _to_next_number(current, 1);
sscanf (current,"%i", &ARRAY_2D(_triangles, i, 0, 3));
for (j = 0; j < count_of_triangles_in_line; j++)
{
if (j > 0)
ARRAY_2D(_triangles, i, 0, 3) = ARRAY_2D(_triangles, (i - 1), 0, 3);
current = _to_next_number(current, 1);
sscanf (current,"%i %i",
&ARRAY_2D(_triangles, i, 1, 3),
&ARRAY_2D(_triangles, i, 2, 3));
i++;
}
current = _to_next_line(current);
}
/* prepare of mesh and take pointers to data which must be read */
eo_do(mesh,
evas_3d_mesh_vertex_count_set(header.triangles_count * 3),
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES),
evas_3d_mesh_frame_add(0),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_POSITION, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_COLOR, 0, NULL),
pos = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_POSITION),
nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
col = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_COLOR),
stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION),
stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL),
stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD),
stride_col = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_COLOR));
if (stride_pos == 0) stride_pos = sizeof(float) * 3;
if (stride_nor == 0) stride_nor = sizeof(float) * 3;
if (stride_tex == 0) stride_tex = sizeof(float) * 2;
if (stride_col == 0) stride_col = sizeof(float) * 4;
for (j = 0; j < header.triangles_count; j++)
{
for (k = 0; k < 3; k++)
{
float *p, *n, *t, *c;
p = (float *)((char *)pos + stride_pos * (j * 3 + k));
n = (float *)((char *)nor + stride_nor * (j * 3 + k));
t = (float *)((char *)tex + stride_tex * (j * 3 + k));
c = (float *)((char *)col + stride_col * (j * 3 + k));
p[0] = ARRAY_2D(_vertices_ply, ARRAY_2D(_triangles, j, k, 3), 0, 3);
p[1] = ARRAY_2D(_vertices_ply, ARRAY_2D(_triangles, j, k, 3), 1, 3);
p[2] = ARRAY_2D(_vertices_ply, ARRAY_2D(_triangles, j, k, 3), 2, 3);
if (header.existence_of_normals)
{
n[0] = ARRAY_2D(_normals_ply, ARRAY_2D(_triangles, j, k, 3), 0, 3);
n[1] = ARRAY_2D(_normals_ply, ARRAY_2D(_triangles, j, k, 3), 1, 3);
n[2] = ARRAY_2D(_normals_ply, ARRAY_2D(_triangles, j, k, 3), 2, 3);
}
else
{
n[0] = 0.0;
n[1] = 0.0;
n[2] = 0.0;
}
if (header.existence_of_texcoords)
{
t[0] = ARRAY_2D(_tex_coords_ply, ARRAY_2D(_triangles, j, k, 3), 0, 2);
t[1] = ARRAY_2D(_tex_coords_ply, ARRAY_2D(_triangles, j, k, 3), 1, 2);
}
else
{
t[0] = 0.0;
t[1] = 0.0;
}
if (header.existence_of_colors)
{
c[0] = ARRAY_2D(_colors_ply, ARRAY_2D(_triangles, j, k, 3), 0, 3);
c[1] = ARRAY_2D(_colors_ply, ARRAY_2D(_triangles, j, k, 3), 1, 3);
c[2] = ARRAY_2D(_colors_ply, ARRAY_2D(_triangles, j, k, 3), 2, 3);
c[3] = 1.0;
}
else
{
c[0] = 0.0;
c[1] = 0.0;
c[2] = 0.0;
c[3] = 1.0;
}
}
}
free(helping_pointer);
free(_vertices_ply);
if (header.existence_of_normals)
free(_normals_ply);
if (header.existence_of_texcoords)
free(_tex_coords_ply);
if (header.existence_of_colors)
free(_colors_ply);
free(_triangles);
/* Unmap vertex buffer. */
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_COLOR));
pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
if (!evas_3d_mesh_aabb_add_to_frame(pd, 0, stride_pos))
{
ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0);
}
}

View File

@ -1,197 +0,0 @@
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include "evas_common_private.h"
#include "evas_private.h"
#define COMPONENT_OF_DEFAULT_GREY_COLOR 0.3
#define TRANSPARENCY_OF_DEFAULT_GREY_COLOR 0.5
extern Evas_3D_File_Eet* eet_file;
extern const char EVAS_3D_FILE_CACHE_FILE_ENTRY[];
extern Eet_Data_Descriptor *_file_descriptor;
void
_set_geometry_to_eet_file_from_mesh(Evas_3D_Mesh_Data *mesh,
Evas_3D_Mesh_Eet *eet_mesh,
Evas_3D_Header_Eet *eet_header,
Evas_3D_Mesh_Frame *f)
{
Evas_3D_Vertex_Buffer *vb;
int i;
float *src;
Evas_3D_Vertex_Eet *vertices =
malloc(sizeof(Evas_3D_Vertex_Eet) * mesh->vertex_count);
Evas_3D_Geometry_Eet *geometry =
malloc(sizeof(Evas_3D_Geometry_Eet));
int *geometries = malloc(sizeof(int));
if ((vertices == NULL) || (geometry == NULL))
{
ERR("Allocating of memory is failed.");
free(vertices);
free(geometry);
free(geometries);
return;
}
geometry->vertices_count = mesh->vertex_count;
geometries[0] = mesh->vertex_count;
#define SAVE_GEOMETRICS(a, component)\
vb = &f->vertices[a];\
if (vb->data == NULL)\
{\
ERR("Reading of geometrics is failed.");\
free(vertices);\
free(geometry);\
free(geometries);\
return;\
}\
src = (float *)vb->data;\
for (i = 0; i < mesh->vertex_count; i++)\
{\
vertices[i].component.x = src[0];\
vertices[i].component.y = src[1];\
vertices[i].component.z = src[2];\
src += f->vertices[a].element_count;\
}
geometry->vertices = vertices;
SAVE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, position)
SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, normal)
SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, texcoord)
#undef SAVE_GEOMETRICS
eet_mesh->geometries = geometry;
eet_header->geometries = geometries;
}
void
_set_material_to_eet_file_from_mesh(Evas_3D_Mesh_Eet *eet_mesh,
Evas_3D_Header_Eet *eet_header,
Evas_3D_Mesh_Frame *f)
{
int i;
Evas_3D_Material_Data *material =
eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);
Evas_3D_Material_Eet *saved_materials =
malloc(sizeof(Evas_3D_Material_Eet));
Evas_3D_Color_Eet *saved_colors =
malloc(sizeof(Evas_3D_Color_Eet) * EVAS_3D_MATERIAL_ATTRIB_COUNT);
int *materials = malloc(sizeof(int));
if ((saved_materials == NULL) || (saved_colors == NULL))
{
ERR("Allocating of memory is failed.");
free(material);
free(saved_materials);
free(saved_colors);
free(materials);
return;
}
if (material == NULL)
{
ERR("Default material is set to saved file, because custom material \
was not saved before using of function evas_3d_mesh_save.");
for (i = 0; i < 5; i++)
{
saved_colors[i].r = COMPONENT_OF_DEFAULT_GREY_COLOR;
saved_colors[i].g = COMPONENT_OF_DEFAULT_GREY_COLOR;
saved_colors[i].b = COMPONENT_OF_DEFAULT_GREY_COLOR;
saved_colors[i].a = TRANSPARENCY_OF_DEFAULT_GREY_COLOR;
}
saved_materials->shininess = 50;
}
else
{
for (i = 0; i < 5; i++)
{
saved_colors[i].r = material->attribs[i].color.r;
saved_colors[i].g = material->attribs[i].color.g;
saved_colors[i].b = material->attribs[i].color.b;
saved_colors[i].a = material->attribs[i].color.a;
}
saved_materials->shininess = material->shininess;
}
saved_materials->colors_count = EVAS_3D_MATERIAL_ATTRIB_COUNT;
materials[0] = EVAS_3D_MATERIAL_ATTRIB_COUNT;
saved_materials->id = 1;
saved_materials->colors = saved_colors;
eet_mesh->materials = saved_materials;
eet_header->materials = materials;
}
void
_set_frame_to_eet_file_from_mesh(Evas_3D_Mesh_Eet *eet_mesh)
{
eet_mesh->frames = malloc(sizeof(Evas_3D_Frame_Eet));
if (eet_mesh->frames == NULL)
{
ERR("Allocating of memory is failed.");
return;
}
eet_mesh->frames->id = 1;
eet_mesh->frames->geometry_id = 1;
eet_mesh->frames->material_id = 1;
}
void
evas_3d_mesh_save_eet(Evas_3D_Mesh *mesh,
const char *file,
Evas_3D_Mesh_Frame *f)
{
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
Eet_File *ef = eet_open(file, EET_FILE_MODE_WRITE);
Evas_3D_Mesh_Eet* eet_mesh = malloc(sizeof(Evas_3D_Mesh_Eet));
Evas_3D_Header_Eet* eet_header = malloc(sizeof(Evas_3D_Header_Eet));
_evas_3d_eet_file_init();
eet_file = _evas_3d_eet_file_new();
eet_mesh->materials_count = 1;
eet_header->materials_count = 1;
eet_mesh->frames_count = 1;
eet_header->frames = 1;
eet_mesh->geometries_count = 1;
eet_header->geometries_count = 1;
eet_header->version = 1;
_set_geometry_to_eet_file_from_mesh(pd, eet_mesh, eet_header, f);
_set_material_to_eet_file_from_mesh(eet_mesh, eet_header, f);
_set_frame_to_eet_file_from_mesh(eet_mesh);
if (ef == NULL)
{
ERR("Opening of file is failed.");
free(eet_mesh);
free(eet_header);
_evas_3d_eet_file_free();
return;
}
eet_file->mesh = eet_mesh;
eet_file->header = eet_header;
eet_data_write(ef,
_file_descriptor,
EVAS_3D_FILE_CACHE_FILE_ENTRY,
eet_file,
EINA_TRUE);
eet_close(ef);
_evas_3d_eet_file_free();
}

View File

@ -1,137 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <time.h>
#include "stdio.h"
#include "evas_common_private.h"
#include "evas_private.h"
#define OPEN_FILE(extension)\
int length=strlen(file);\
char * extension = "."#extension;\
char * _##extension##_file_name = (char *)malloc(length+4);\
strcpy(_##extension##_file_name,file);\
strcpy(_##extension##_file_name+length,extension);\
FILE * _##extension##_file = fopen(_##extension##_file_name, "w+");\
free(_##extension##_file_name);
#define SAVE_GEOMETRICS(a, format)\
vb = &f->vertices[a];\
fprintf(_obj_file, "o %s\n",file);\
if (vb->data == NULL)\
{\
ERR("Reading of geometrics is failed.");\
fclose(_obj_file);\
return;\
}\
src = (float *)vb->data;\
for (i = 0; i < pd->vertex_count; i++)\
{\
fprintf(_obj_file, format, src[0], src[1], src[2]);\
src += f->vertices[a].element_count;\
}
static void
_save_mesh(Evas_3D_Mesh_Data *pd, const char *file, Evas_3D_Mesh_Frame *f)
{
Evas_3D_Vertex_Buffer *vb;
time_t current_time;
char* c_time_string;
int i;
float *src;
OPEN_FILE(obj)
if (!_obj_file)
{
ERR("File open '%s' for save failed", file);
return;
}
fprintf(_obj_file, "# Evas_3D saver OBJ v0.03 \n");//_obj_file created in macro
/* Adding time comment to .obj file. */
current_time = time(NULL);
if (current_time == ((time_t)-1))
{
ERR("Failure to compute the current time.");
fclose(_obj_file);
return;
}
c_time_string = ctime(&current_time);
if (c_time_string == NULL)
{
ERR("Failure to convert the current time.");
fclose(_obj_file);
return;
}
fprintf(_obj_file,"# Current time is %s \n", c_time_string);
fprintf(_obj_file,"mtllib %s.mtl \n\n", file);
/* Adding geometrics to file. */
if (f == NULL)
{
ERR("Not existing mesh frame.");
fclose(_obj_file);
return;
}
SAVE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, "v %.4f %.4f %.4f \n")
SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, "vn %.4f %.4f %.4f \n")
SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, "vt %.4f %.4f %.4f \n")
fprintf(_obj_file,"usemtl Material\n s off\n");
for (i = 1; i <= pd->vertex_count; i++)//numeration of faces in .obj started from 1
{
fprintf(_obj_file,"f %i/%i/%i ", i, i, i);
i++;
fprintf(_obj_file,"%i/%i/%i ", i, i, i);
i++;
fprintf(_obj_file,"%i/%i/%i \n", i, i, i);
}
fclose(_obj_file);
}
static void
_save_material(Evas_3D_Mesh_Data *pd EINA_UNUSED, const char *file, Evas_3D_Mesh_Frame *f)
{
Evas_3D_Material_Data *mat = eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);
OPEN_FILE(mtl)
if (!_mtl_file)
{
ERR("File open '%s' for save failed", file);
return;
}
fprintf(_mtl_file, "# Evas_3D saver OBJ v0.03 \n");//_mtl_file created in macro
fprintf(_mtl_file, "# Material Count: 1 \n\n");
fprintf(_mtl_file, "newmtl Material \n");
fprintf(_mtl_file, "Ns 1.000000 \n");//exp factor for specular highlight
fprintf(_mtl_file, "Ka %.6f %.6f %.6f \n",
(float)mat->attribs[EVAS_3D_MATERIAL_AMBIENT].color.r,
(float)mat->attribs[EVAS_3D_MATERIAL_AMBIENT].color.g,
(float)mat->attribs[EVAS_3D_MATERIAL_AMBIENT].color.b);
fprintf(_mtl_file, "Kd %.6f %.6f %.6f \n",
(float)mat->attribs[EVAS_3D_MATERIAL_DIFFUSE].color.r,
(float)mat->attribs[EVAS_3D_MATERIAL_DIFFUSE].color.g,
(float)mat->attribs[EVAS_3D_MATERIAL_DIFFUSE].color.b);
fprintf(_mtl_file, "Ks %.6f %.6f %.6f \n",
(float)mat->attribs[EVAS_3D_MATERIAL_SPECULAR].color.r,
(float)mat->attribs[EVAS_3D_MATERIAL_SPECULAR].color.g,
(float)mat->attribs[EVAS_3D_MATERIAL_SPECULAR].color.b);
fprintf(_mtl_file, "Ni 1.000000 \n");//optical density
fprintf(_mtl_file, "d 1.000000 \n");//a factor d of 1.0 is fully opaque material
fprintf(_mtl_file, "illum 2 \n");//illumination properties
fclose(_mtl_file);
}
void
evas_3d_mesh_save_obj(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f)
{
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
_save_mesh(pd, file, f);
_save_material(pd, file, f);
}

View File

@ -1,61 +0,0 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <time.h>
#include "stdio.h"
#include "math.h"
#include "evas_common_private.h"
#include "evas_private.h"
void
evas_3d_mesh_save_ply(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f)
{
float *src_pos, *src_nor, *src_tex, *src_col;
int i;
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
FILE *_ply_file = fopen(file, "w+");
if (!_ply_file)
{
ERR("File open '%s' for save failed", file);
return;
}
fprintf(_ply_file,"ply\nformat ascii 1.0\ncomment Created by EFL evas_3d_mesh_saver_ply.c" \
"version 1 (sub 0) - www.enlightenment.org, source file: ''\n");
fprintf(_ply_file,"element vertex %d\n", pd->vertex_count);
fprintf(_ply_file,"property float x\nproperty float y\nproperty float z\n" \
"property float nx\nproperty float ny\nproperty float nz\n" \
"property float s\nproperty float t\n" \
"property uchar red\nproperty uchar green\nproperty uchar blue\n");
fprintf(_ply_file,"element face %d\nproperty list uchar uint vertex_indices\nend_header\n",
pd->vertex_count / 3);
src_pos = (float*)(&f->vertices[EVAS_3D_VERTEX_POSITION])->data;
src_nor = (float*)(&f->vertices[EVAS_3D_VERTEX_NORMAL])->data;
src_tex = (float*)(&f->vertices[EVAS_3D_VERTEX_TEXCOORD])->data;
src_col = (float*)(&f->vertices[EVAS_3D_VERTEX_COLOR])->data;
for (i = 0; i < pd->vertex_count; i++)
{
fprintf(_ply_file,"%f %f %f %f %f %f %f %f %.0f %.0f %.0f\n",
src_pos[0], src_pos[1], src_pos[2],
src_nor[0], src_nor[1], src_nor[2],
src_tex[0], src_tex[1],
round(src_col[0] * 255), round(src_col[1] * 255), round(src_col[2] * 255));
src_pos += 3;
src_nor += 3;
src_tex += 2;
src_col += 4;
}
for (i = 0; i < pd->vertex_count;)
{
fprintf(_ply_file,"3 %d %d %d\n", i, i + 1, i + 2);
i += 3;
}
fclose(_ply_file);
}

View File

@ -1 +1,131 @@
//dummy of saver/loader
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <Eo.h>
#include <stdio.h>
#include "evas_common_private.h"
#include "evas_private.h"
extern Evas_3D_File_Eet* eet_file;
extern const char EVAS_3D_FILE_CACHE_FILE_ENTRY[];
extern Eet_Data_Descriptor *_file_descriptor;
void
_set_geometry_to_mesh_from_eet_file(Evas_3D_Mesh *mesh,
Evas_3D_Mesh_Eet *eet_mesh)
{
float *pos, *nor, *tex;
int stride_pos, stride_nor, stride_tex, j;
eo_do(mesh,
evas_3d_mesh_vertex_count_set(eet_mesh->geometries->vertices_count),
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES),
evas_3d_mesh_frame_add(0),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_POSITION, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
pos = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_POSITION),
nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION),
stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL),
stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD));
if (stride_pos == 0) stride_pos = sizeof(float) * 3;
if (stride_nor == 0) stride_nor = sizeof(float) * 3;
if (stride_tex == 0) stride_tex = sizeof(float) * 2;
/* set data to vertex buffer */
for (j = 0; j < eet_mesh->geometries->vertices_count; j++)
{
float *p, *n, *t;
p = (float *)((char *)pos + stride_pos * j);
n = (float *)((char *)nor + stride_nor * j);
t = (float *)((char *)tex + stride_tex * j);
p[0] = eet_mesh->geometries->vertices[j].position.x;
p[1] = eet_mesh->geometries->vertices[j].position.y;
p[2] = eet_mesh->geometries->vertices[j].position.z;
n[0] = eet_mesh->geometries->vertices[j].normal.x;
n[1] = eet_mesh->geometries->vertices[j].normal.y;
n[2] = eet_mesh->geometries->vertices[j].normal.z;
t[0] = eet_mesh->geometries->vertices[j].texcoord.x;
t[1] = eet_mesh->geometries->vertices[j].texcoord.y;
}
/* unmap vertex buffer */
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD));
}
void
_set_material_to_mesh_from_eet_file(Evas_3D_Mesh *mesh,
Evas_3D_Mesh_Eet *eet_mesh)
{
Evas_3D_Object_Data *pd = eo_data_scope_get(mesh, EVAS_3D_OBJECT_CLASS);
Eo *material = NULL;
material = eo_add(EVAS_3D_MATERIAL_CLASS, pd->evas);
eo_do(material,
evas_3d_material_enable_set(EVAS_3D_MATERIAL_AMBIENT,
!!(eet_mesh->materials->colors[0].a > 0)),
evas_3d_material_enable_set(EVAS_3D_MATERIAL_DIFFUSE,
!!(eet_mesh->materials->colors[1].a > 0)),
evas_3d_material_enable_set(EVAS_3D_MATERIAL_SPECULAR,
!!(eet_mesh->materials->colors[2].a > 0)),
evas_3d_material_enable_set(EVAS_3D_MATERIAL_NORMAL, EINA_TRUE),
evas_3d_material_color_set(EVAS_3D_MATERIAL_AMBIENT,
eet_mesh->materials->colors[0].r,
eet_mesh->materials->colors[0].g,
eet_mesh->materials->colors[0].b,
eet_mesh->materials->colors[0].a),
evas_3d_material_color_set(EVAS_3D_MATERIAL_DIFFUSE,
eet_mesh->materials->colors[1].r,
eet_mesh->materials->colors[1].g,
eet_mesh->materials->colors[1].b,
eet_mesh->materials->colors[1].a),
evas_3d_material_color_set(EVAS_3D_MATERIAL_SPECULAR,
eet_mesh->materials->colors[2].r,
eet_mesh->materials->colors[2].g,
eet_mesh->materials->colors[2].b,
eet_mesh->materials->colors[2].a),
evas_3d_material_shininess_set(eet_mesh->materials->shininess));
eo_do(mesh, evas_3d_mesh_frame_material_set(0, material));
}
void
evas_3d_mesh_file_eet_set(Evas_3D_Mesh *mesh, const char *file)
{
Eet_File *ef;
_evas_3d_eet_file_init();
ef = eet_open(file, EET_FILE_MODE_READ);
eet_file = eet_data_read(ef,
_file_descriptor,
EVAS_3D_FILE_CACHE_FILE_ENTRY);
eet_close(ef);
if ((eet_file->mesh == NULL) || (eet_file->header == NULL))
{
ERR("Reading of file is failed.");
_evas_3d_eet_file_free();
return;
}
_set_geometry_to_mesh_from_eet_file(mesh, eet_file->mesh);
_set_material_to_mesh_from_eet_file(mesh, eet_file->mesh);
_evas_3d_eet_file_free();
}

View File

@ -1 +1,446 @@
//dummy of saver/loader
#include "evas_common_private.h"
#include "evas_private.h"
#define PACKED __attribute__((__packed__))
#define MD2_MAGIC_NUMBER 844121161
#define MD2_VERSION 8
#define MD2_FRAME_SCALE 256
/* Structures for reading data from file. */
typedef struct _MD2_Header MD2_Header;
typedef struct _MD2_Vertex MD2_Vertex;
typedef struct _MD2_Frame MD2_Frame;
typedef struct _MD2_Triangle MD2_Triangle;
typedef struct _MD2_Texcoord MD2_Texcoord;
struct PACKED _MD2_Header
{
int magic;
int version;
int skin_width;
int skin_height;
int frame_size;
int skins_count;
int vertex_count;
int texcoord_count;
int triangle_count;
int glcmd_count;
int frame_count;
int offset_skins;
int offset_texcoords;
int offset_triangles;
int offset_frames;
int offset_glcmds;
int offset_end;
};
struct PACKED _MD2_Vertex
{
unsigned char pos[3];
unsigned char normal_idx;
};
struct PACKED _MD2_Frame
{
float scale[3];
float trans[3];
char name[16];
MD2_Vertex vertices[1];
};
struct PACKED _MD2_Triangle
{
unsigned short vertex_idx[3];
unsigned short texcoord_idx[3];
};
struct PACKED _MD2_Texcoord
{
short s;
short t;
};
typedef struct _MD2_Loader
{
Eina_File *file;
char *map;
int size;
int skin_width;
int skin_height;
int frame_count;
int frame_size;
char *frames;
int vertex_count;
int triangle_count;
int texcoord_count;
MD2_Triangle *triangles;
MD2_Texcoord *texcoords;
} MD2_Loader;
static const float normal_table[162][3] =
{
{-0.525731f, 0.000000f, 0.850651f},
{-0.442863f, 0.238856f, 0.864188f},
{-0.295242f, 0.000000f, 0.955423f},
{-0.309017f, 0.500000f, 0.809017f},
{-0.162460f, 0.262866f, 0.951056f},
{ 0.000000f, 0.000000f, 1.000000f},
{ 0.000000f, 0.850651f, 0.525731f},
{-0.147621f, 0.716567f, 0.681718f},
{ 0.147621f, 0.716567f, 0.681718f},
{ 0.000000f, 0.525731f, 0.850651f},
{ 0.309017f, 0.500000f, 0.809017f},
{ 0.525731f, 0.000000f, 0.850651f},
{ 0.295242f, 0.000000f, 0.955423f},
{ 0.442863f, 0.238856f, 0.864188f},
{ 0.162460f, 0.262866f, 0.951056f},
{-0.681718f, 0.147621f, 0.716567f},
{-0.809017f, 0.309017f, 0.500000f},
{-0.587785f, 0.425325f, 0.688191f},
{-0.850651f, 0.525731f, 0.000000f},
{-0.864188f, 0.442863f, 0.238856f},
{-0.716567f, 0.681718f, 0.147621f},
{-0.688191f, 0.587785f, 0.425325f},
{-0.500000f, 0.809017f, 0.309017f},
{-0.238856f, 0.864188f, 0.442863f},
{-0.425325f, 0.688191f, 0.587785f},
{-0.716567f, 0.681718f, -0.147621f},
{-0.500000f, 0.809017f, -0.309017f},
{-0.525731f, 0.850651f, 0.000000f},
{ 0.000000f, 0.850651f, -0.525731f},
{-0.238856f, 0.864188f, -0.442863f},
{ 0.000000f, 0.955423f, -0.295242f},
{-0.262866f, 0.951056f, -0.162460f},
{ 0.000000f, 1.000000f, 0.000000f},
{ 0.000000f, 0.955423f, 0.295242f},
{-0.262866f, 0.951056f, 0.162460f},
{ 0.238856f, 0.864188f, 0.442863f},
{ 0.262866f, 0.951056f, 0.162460f},
{ 0.500000f, 0.809017f, 0.309017f},
{ 0.238856f, 0.864188f, -0.442863f},
{ 0.262866f, 0.951056f, -0.162460f},
{ 0.500000f, 0.809017f, -0.309017f},
{ 0.850651f, 0.525731f, 0.000000f},
{ 0.716567f, 0.681718f, 0.147621f},
{ 0.716567f, 0.681718f, -0.147621f},
{ 0.525731f, 0.850651f, 0.000000f},
{ 0.425325f, 0.688191f, 0.587785f},
{ 0.864188f, 0.442863f, 0.238856f},
{ 0.688191f, 0.587785f, 0.425325f},
{ 0.809017f, 0.309017f, 0.500000f},
{ 0.681718f, 0.147621f, 0.716567f},
{ 0.587785f, 0.425325f, 0.688191f},
{ 0.955423f, 0.295242f, 0.000000f},
{ 1.000000f, 0.000000f, 0.000000f},
{ 0.951056f, 0.162460f, 0.262866f},
{ 0.850651f, -0.525731f, 0.000000f},
{ 0.955423f, -0.295242f, 0.000000f},
{ 0.864188f, -0.442863f, 0.238856f},
{ 0.951056f, -0.162460f, 0.262866f},
{ 0.809017f, -0.309017f, 0.500000f},
{ 0.681718f, -0.147621f, 0.716567f},
{ 0.850651f, 0.000000f, 0.525731f},
{ 0.864188f, 0.442863f, -0.238856f},
{ 0.809017f, 0.309017f, -0.500000f},
{ 0.951056f, 0.162460f, -0.262866f},
{ 0.525731f, 0.000000f, -0.850651f},
{ 0.681718f, 0.147621f, -0.716567f},
{ 0.681718f, -0.147621f, -0.716567f},
{ 0.850651f, 0.000000f, -0.525731f},
{ 0.809017f, -0.309017f, -0.500000f},
{ 0.864188f, -0.442863f, -0.238856f},
{ 0.951056f, -0.162460f, -0.262866f},
{ 0.147621f, 0.716567f, -0.681718f},
{ 0.309017f, 0.500000f, -0.809017f},
{ 0.425325f, 0.688191f, -0.587785f},
{ 0.442863f, 0.238856f, -0.864188f},
{ 0.587785f, 0.425325f, -0.688191f},
{ 0.688191f, 0.587785f, -0.425325f},
{-0.147621f, 0.716567f, -0.681718f},
{-0.309017f, 0.500000f, -0.809017f},
{ 0.000000f, 0.525731f, -0.850651f},
{-0.525731f, 0.000000f, -0.850651f},
{-0.442863f, 0.238856f, -0.864188f},
{-0.295242f, 0.000000f, -0.955423f},
{-0.162460f, 0.262866f, -0.951056f},
{ 0.000000f, 0.000000f, -1.000000f},
{ 0.295242f, 0.000000f, -0.955423f},
{ 0.162460f, 0.262866f, -0.951056f},
{-0.442863f, -0.238856f, -0.864188f},
{-0.309017f, -0.500000f, -0.809017f},
{-0.162460f, -0.262866f, -0.951056f},
{ 0.000000f, -0.850651f, -0.525731f},
{-0.147621f, -0.716567f, -0.681718f},
{ 0.147621f, -0.716567f, -0.681718f},
{ 0.000000f, -0.525731f, -0.850651f},
{ 0.309017f, -0.500000f, -0.809017f},
{ 0.442863f, -0.238856f, -0.864188f},
{ 0.162460f, -0.262866f, -0.951056f},
{ 0.238856f, -0.864188f, -0.442863f},
{ 0.500000f, -0.809017f, -0.309017f},
{ 0.425325f, -0.688191f, -0.587785f},
{ 0.716567f, -0.681718f, -0.147621f},
{ 0.688191f, -0.587785f, -0.425325f},
{ 0.587785f, -0.425325f, -0.688191f},
{ 0.000000f, -0.955423f, -0.295242f},
{ 0.000000f, -1.000000f, 0.000000f},
{ 0.262866f, -0.951056f, -0.162460f},
{ 0.000000f, -0.850651f, 0.525731f},
{ 0.000000f, -0.955423f, 0.295242f},
{ 0.238856f, -0.864188f, 0.442863f},
{ 0.262866f, -0.951056f, 0.162460f},
{ 0.500000f, -0.809017f, 0.309017f},
{ 0.716567f, -0.681718f, 0.147621f},
{ 0.525731f, -0.850651f, 0.000000f},
{-0.238856f, -0.864188f, -0.442863f},
{-0.500000f, -0.809017f, -0.309017f},
{-0.262866f, -0.951056f, -0.162460f},
{-0.850651f, -0.525731f, 0.000000f},
{-0.716567f, -0.681718f, -0.147621f},
{-0.716567f, -0.681718f, 0.147621f},
{-0.525731f, -0.850651f, 0.000000f},
{-0.500000f, -0.809017f, 0.309017f},
{-0.238856f, -0.864188f, 0.442863f},
{-0.262866f, -0.951056f, 0.162460f},
{-0.864188f, -0.442863f, 0.238856f},
{-0.809017f, -0.309017f, 0.500000f},
{-0.688191f, -0.587785f, 0.425325f},
{-0.681718f, -0.147621f, 0.716567f},
{-0.442863f, -0.238856f, 0.864188f},
{-0.587785f, -0.425325f, 0.688191f},
{-0.309017f, -0.500000f, 0.809017f},
{-0.147621f, -0.716567f, 0.681718f},
{-0.425325f, -0.688191f, 0.587785f},
{-0.162460f, -0.262866f, 0.951056f},
{ 0.442863f, -0.238856f, 0.864188f},
{ 0.162460f, -0.262866f, 0.951056f},
{ 0.309017f, -0.500000f, 0.809017f},
{ 0.147621f, -0.716567f, 0.681718f},
{ 0.000000f, -0.525731f, 0.850651f},
{ 0.425325f, -0.688191f, 0.587785f},
{ 0.587785f, -0.425325f, 0.688191f},
{ 0.688191f, -0.587785f, 0.425325f},
{-0.955423f, 0.295242f, 0.000000f},
{-0.951056f, 0.162460f, 0.262866f},
{-1.000000f, 0.000000f, 0.000000f},
{-0.850651f, 0.000000f, 0.525731f},
{-0.955423f, -0.295242f, 0.000000f},
{-0.951056f, -0.162460f, 0.262866f},
{-0.864188f, 0.442863f, -0.238856f},
{-0.951056f, 0.162460f, -0.262866f},
{-0.809017f, 0.309017f, -0.500000f},
{-0.864188f, -0.442863f, -0.238856f},
{-0.951056f, -0.162460f, -0.262866f},
{-0.809017f, -0.309017f, -0.500000f},
{-0.681718f, 0.147621f, -0.716567f},
{-0.681718f, -0.147621f, -0.716567f},
{-0.850651f, 0.000000f, -0.525731f},
{-0.688191f, 0.587785f, -0.425325f},
{-0.587785f, 0.425325f, -0.688191f},
{-0.425325f, 0.688191f, -0.587785f},
{-0.425325f, -0.688191f, -0.587785f},
{-0.587785f, -0.425325f, -0.688191f},
{-0.688191f, -0.587785f, -0.425325f},
};
static inline void
_md2_loader_fini(MD2_Loader *loader)
{
if (loader->map)
{
eina_file_map_free(loader->file, loader->map);
loader->map = NULL;
}
if (loader->file)
{
eina_file_close(loader->file);
loader->file = NULL;
}
}
static inline Eina_Bool
_md2_loader_init(MD2_Loader *loader, const char *file)
{
MD2_Header header;
memset(loader, 0x00, sizeof(MD2_Loader));
/* Open given file. */
loader->file = eina_file_open(file, 0);
if (loader->file == NULL)
{
ERR("Failed to open file %s\n", file);
goto error;
}
/* Check file size. We require a file larger than MD2 header size. */
loader->size = eina_file_size_get(loader->file);
if (loader->size < (int)sizeof(MD2_Header))
goto error;
/* Map the file. */
loader->map = eina_file_map_all(loader->file, EINA_FILE_SEQUENTIAL);
if (loader->map == NULL)
goto error;
/* Read header. */
memcpy(&header, loader->map, sizeof(MD2_Header));
/* Check identity */
if (header.magic != MD2_MAGIC_NUMBER || header.version != MD2_VERSION)
goto error;
/* Check offsets */
if (header.offset_skins > header.offset_end)
goto error;
if (header.offset_texcoords > header.offset_end)
goto error;
if (header.offset_triangles > header.offset_end)
goto error;
if (header.offset_frames > header.offset_end)
goto error;
if (header.offset_glcmds > header.offset_end)
goto error;
if (header.offset_end > loader->size)
goto error;
loader->skin_width = header.skin_width;
loader->skin_height = header.skin_height;
loader->frame_count = header.frame_count;
loader->frame_size = header.frame_size;
loader->frames = loader->map + header.offset_frames;
loader->vertex_count = header.vertex_count;
loader->triangle_count = header.triangle_count;
loader->texcoord_count = header.texcoord_count;
loader->triangles = (MD2_Triangle *)(loader->map + header.offset_triangles);
loader->texcoords = (MD2_Texcoord *)(loader->map + header.offset_texcoords);
return EINA_TRUE;
error:
_md2_loader_fini(loader);
return EINA_FALSE;
}
void
evas_3d_mesh_file_md2_set(Evas_3D_Mesh *mesh, const char *file)
{
MD2_Loader loader;
int i, j, k;
float *pos, *nor, *tex;
int stride_pos, stride_nor, stride_tex;
float s_scale, t_scale;
Evas_3D_Mesh_Data *pd;
/* Initialize MD2 loader (Open file and read MD2 head ant etc) */
if (!_md2_loader_init(&loader, file))
{
ERR("Failed to initialize MD2 loader.");
return;
}
s_scale = 1.0 / (float)(loader.skin_width - 1);
t_scale = 1.0 / (float)(loader.skin_height - 1);
eo_do(mesh,
evas_3d_mesh_vertex_count_set(loader.triangle_count * 3),
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES));
/* Load frames */
for (i = 0; i < loader.frame_count; i++)
{
const MD2_Frame *frame = (const MD2_Frame *)(loader.frames + loader.frame_size * i);
int f = i * MD2_FRAME_SCALE;
eo_do(mesh,
/* Add a mesh frame. */
evas_3d_mesh_frame_add(f),
/* Allocate vertex buffer for the frame. */
evas_3d_mesh_frame_vertex_data_copy_set(f, EVAS_3D_VERTEX_POSITION, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(f, EVAS_3D_VERTEX_NORMAL, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(f, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
/* Map vertex buffer. */
pos = (float *)evas_3d_mesh_frame_vertex_data_map(f, EVAS_3D_VERTEX_POSITION),
nor = (float *)evas_3d_mesh_frame_vertex_data_map(f, EVAS_3D_VERTEX_NORMAL),
tex = (float *)evas_3d_mesh_frame_vertex_data_map(f, EVAS_3D_VERTEX_TEXCOORD),
stride_pos = evas_3d_mesh_frame_vertex_stride_get(f, EVAS_3D_VERTEX_POSITION),
stride_nor = evas_3d_mesh_frame_vertex_stride_get(f, EVAS_3D_VERTEX_NORMAL),
stride_tex = evas_3d_mesh_frame_vertex_stride_get(f, EVAS_3D_VERTEX_TEXCOORD));
if (stride_pos == 0)
stride_pos = sizeof(float) * 3;
if (stride_nor == 0)
stride_nor = sizeof(float) * 3;
if (stride_tex == 0)
stride_tex = sizeof(float) * 2;
for (j = 0; j < loader.triangle_count; j++)
{
const MD2_Triangle *tri = &loader.triangles[j];
for (k = 0; k < 3; k++)
{
unsigned int tidx, vidx;
float *p, *n, *t;
tidx = tri->texcoord_idx[k];
vidx = tri->vertex_idx[k];
p = (float *)((char *)pos + stride_pos * (j * 3 + k));
n = (float *)((char *)nor + stride_nor * (j * 3 + k));
t = (float *)((char *)tex + stride_tex * (j * 3 + k));
p[0] = frame->vertices[vidx].pos[0] * frame->scale[0] + frame->trans[0];
p[1] = frame->vertices[vidx].pos[1] * frame->scale[1] + frame->trans[1];
p[2] = frame->vertices[vidx].pos[2] * frame->scale[2] + frame->trans[2];
n[0] = normal_table[frame->vertices[vidx].normal_idx][0];
n[1] = normal_table[frame->vertices[vidx].normal_idx][1];
n[2] = normal_table[frame->vertices[vidx].normal_idx][2];
t[0] = loader.texcoords[tidx].s * s_scale;
t[1] = 1.0 - loader.texcoords[tidx].t * t_scale;
}
}
/* Unmap vertex buffer. */
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(f, EVAS_3D_VERTEX_POSITION),
evas_3d_mesh_frame_vertex_data_unmap(f, EVAS_3D_VERTEX_NORMAL),
evas_3d_mesh_frame_vertex_data_unmap(f, EVAS_3D_VERTEX_TEXCOORD));
pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
if (!evas_3d_mesh_aabb_add_to_frame(pd, f, stride_pos))
{
ERR("Axis-Aligned Bounding Box wasn't added in frame %d ", f);
}
}
_md2_loader_fini(&loader);
}

View File

@ -1 +1,401 @@
//dummy of saver/loader
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include "stdio.h"
#include "evas_common_private.h"
#include "evas_private.h"
/* set value to position [x][y] to array name which have. */
#define ARRAY_2D(name, x, y, count_y) (*(name + x * count_y + y))
/* read 3 float values in string and put it in array */
#define PUT_DATA_TO_ARRAY(array_name, name) \
sscanf (current,"%f %f %f", \
&ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 0, 3), \
&ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 1, 3), \
&ARRAY_2D(_##array_name##_obj, counts.current_##name##_counter, 2, 3)); \
counts.current_##name##_counter++;
/* Structures for reading data from file. */
typedef struct _OBJ_Counts OBJ_Counts;
struct _OBJ_Counts
{
int _vertex_counter;
int _normal_counter;
int _texture_point_counter;
int _triangles_counter;
int current_vertex_counter;
int current_normal_counter;
int current_texture_point_counter;
int current_triangles_counter;
Eina_Bool existence_of_normal;
Eina_Bool existence_of_tex_point;
};
static inline char*
_file_to_buf(const char *file, long *length)//prepare text file for reading
{
FILE *file_for_print;
char *buf;
int unused __attribute__((unused));//this variable fixes warning "ignoring return value of fread"
*length = 0;
file_for_print = fopen(file, "rb");
if (!file_for_print) return NULL;
fseek(file_for_print, 0, SEEK_END);//set file_for_print to the end of file
*length = ftell(file_for_print);//set current position of file_for_print
if (*length < 0)
{
fclose(file_for_print);
return NULL;
}
buf = malloc(*length + 1);
fseek(file_for_print, 0, SEEK_SET);//set file_for_print to the begining of file
unused = fread(buf, *length, 1, file_for_print);
fclose(file_for_print);
buf[*length] = '\0';
return buf;
}
/* create new counter */
static inline OBJ_Counts
_new_count_elements()
{
OBJ_Counts counts;
counts._vertex_counter = 0;
counts._normal_counter = 0;
counts._texture_point_counter = 0;
counts._triangles_counter = 0;
counts.current_vertex_counter = 0;
counts.current_normal_counter = 0;
counts.current_texture_point_counter = 0;
counts.current_triangles_counter = 0;
counts.existence_of_normal = EINA_FALSE;
counts.existence_of_tex_point = EINA_FALSE;
return counts;
}
/* count triangles in face */
static void
_analyze_face_line(char * face_analyzer,
int * count_of_triangles_in_line)
{
int polygon_checker = -2;
Eina_Bool previous_is_space = EINA_TRUE;
while ((*face_analyzer != '\n') && (*face_analyzer != '#'))
{
if (*face_analyzer == ' ')
{
previous_is_space = EINA_TRUE;
}
else if ((previous_is_space) && (*face_analyzer >= '0') && (*face_analyzer <= '9'))
{
polygon_checker++;
previous_is_space = EINA_FALSE;
}
face_analyzer++;
}
*count_of_triangles_in_line = polygon_checker;
}
static inline OBJ_Counts
_count_elements(char *start, long length)//count elements of mesh in .obj
{
OBJ_Counts counts = _new_count_elements();
char * current = start;
int polygon_checker = -2;//polygons with n vertices can be represented as n-2 triangles
Eina_Bool will_check_next_char = EINA_FALSE;
Eina_Bool first_char_is_v = EINA_FALSE;
Eina_Bool first_char_is_f = EINA_FALSE;
Eina_Bool previous_is_space = EINA_FALSE;
long i = 0;
/* count elements of mesh in .obj */
for (; length > i; i++)
{
if (will_check_next_char)
{
if (first_char_is_v)
{
switch (*current)
{
case ' ':
counts._vertex_counter++;
break;
case 't':
counts._texture_point_counter++;
counts.existence_of_tex_point = EINA_TRUE;
break;
case 'n':
counts._normal_counter++;
counts.existence_of_normal = EINA_TRUE;
break;
default:
break;
}
first_char_is_v = EINA_FALSE;
will_check_next_char = EINA_FALSE;
}
else if (first_char_is_f)
{
switch (*current)
{
case '\n':
first_char_is_f = EINA_FALSE;
counts._triangles_counter += polygon_checker;
polygon_checker = -2;
previous_is_space = EINA_FALSE;
break;
case '#':
first_char_is_f = EINA_FALSE;
counts._triangles_counter += polygon_checker;
polygon_checker = -2;
previous_is_space = EINA_FALSE;
break;
case ' ':
previous_is_space = EINA_TRUE;
break;
default:
if ((previous_is_space) && (*current >= '0') && (*current <= '9'))
{
polygon_checker++;
previous_is_space = EINA_FALSE;
}
break;
}
}
else
{
switch (*current)
{
case 'v':
first_char_is_v = EINA_TRUE;
break;
case 'f':
first_char_is_f = EINA_TRUE;
break;
case 'm':
will_check_next_char = EINA_FALSE;
break;
default:
will_check_next_char = EINA_FALSE;
break;
}
}
}
else if (*current == '\n')
{
will_check_next_char = EINA_TRUE;
}
current++;
}
return counts;
}
void
evas_3d_mesh_file_obj_set(Evas_3D_Mesh *mesh, const char *file)
{
long length, i;
char * start = _file_to_buf(file, &length);
OBJ_Counts counts = _count_elements(start, length);//count elements of mesh in .obj
Eina_Bool will_check_next_char = EINA_FALSE;
Eina_Bool first_char_is_v = EINA_FALSE;
Eina_Bool first_char_is_f = EINA_FALSE;
float *pos, *nor, *tex;
int stride_pos, stride_nor, stride_tex;
int j, k;
char * current;
float *_vertices_obj = malloc(counts._vertex_counter * 3 * sizeof(float));
float *_normales_obj = malloc(counts._normal_counter * 3 * sizeof(float));
float *_tex_coords_obj = malloc(counts._texture_point_counter * 3 * sizeof(float));
/* triangle has 3 points, every point has 3(vertix, texture and normal) coord */
int *_triangles = malloc(counts._triangles_counter * 9 * sizeof(int));
if ((start == NULL) || (_vertices_obj == NULL) ||
(_normales_obj == NULL) || (_tex_coords_obj == NULL) || (_triangles == NULL))
{
ERR("Allocate memory is failed.");
free(start);
free(_vertices_obj);
free(_normales_obj);
free(_tex_coords_obj);
free(_triangles);
return;
}
current = start;
i = 0;
/* put data to arrays */
for (; length > i; i++)
{
if (will_check_next_char)
{
if (first_char_is_v)
{
switch (*current)
{
case ' ':
PUT_DATA_TO_ARRAY(vertices, vertex)
i--;
break;
case 't':
current++;
PUT_DATA_TO_ARRAY(tex_coords, texture_point)
break;
case 'n':
current++;
PUT_DATA_TO_ARRAY(normales, normal)
break;
default:
break;
}
first_char_is_v = EINA_FALSE;
will_check_next_char = EINA_FALSE;
}
else if (first_char_is_f)
{
char * auxiliary_pointer = current;
int count_of_triangles_in_line;
_analyze_face_line(auxiliary_pointer,
&count_of_triangles_in_line);
current++;
i++;
int first_pos, first_tex, first_norm;
sscanf (current,"%i/%i/%i",
&first_pos,
&first_tex,
&first_norm);
do
{
current++;
i++;
}
while (*current != ' ');
current++;
i++;
for (j = 0; j < count_of_triangles_in_line; j++)
{
auxiliary_pointer = current;
ARRAY_2D(_triangles, counts.current_triangles_counter, 0, 9) = first_pos;
ARRAY_2D(_triangles, counts.current_triangles_counter, 1, 9) = first_tex;
ARRAY_2D(_triangles, counts.current_triangles_counter, 2, 9) = first_norm;
sscanf (auxiliary_pointer,"%i/%i/%i %i/%i/%i",
&ARRAY_2D(_triangles, counts.current_triangles_counter, 3, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 4, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 5, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 6, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 7, 9),
&ARRAY_2D(_triangles, counts.current_triangles_counter, 8, 9));
while (*current != ' ')
{
current++;
i++;
}
counts.current_triangles_counter++;
}
first_char_is_f = EINA_FALSE;
}
else
{
switch (*current)
{
case 'v':
first_char_is_v = EINA_TRUE;
break;
case 'f':
first_char_is_f = EINA_TRUE;
break;
case 'm':
will_check_next_char = EINA_FALSE;
break;
default:
will_check_next_char = EINA_FALSE;
break;
}
}
}
else if (*current == '\n')
{
will_check_next_char = EINA_TRUE;
}
current++;
}
free(start);
/* prepare of mesh and take pointers to data which must be read */
eo_do(mesh,
evas_3d_mesh_vertex_count_set(counts._triangles_counter * 3),
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES),
evas_3d_mesh_frame_add(0),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_POSITION, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
pos = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_POSITION),
nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION),
stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL),
stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD));
if (stride_pos == 0) stride_pos = sizeof(float) * 3;
if (stride_nor == 0) stride_nor = sizeof(float) * 3;
if (stride_tex == 0) stride_tex = sizeof(float) * 2;
for (j = 0; j < counts._triangles_counter; j++)
{
for (k = 0; k < 3; k++)
{
float *p, *n, *t;
p = (float *)((char *)pos + stride_pos * (j * 3 + k));
n = (float *)((char *)nor + stride_nor * (j * 3 + k));
t = (float *)((char *)tex + stride_tex * (j * 3 + k));
p[0] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 0, 3);
p[1] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 1, 3);
p[2] = ARRAY_2D(_vertices_obj, (ARRAY_2D(_triangles, j, (3 * k), 9) - 1), 2, 3);
n[0] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 0, 3);
n[1] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 1, 3);
n[2] = ARRAY_2D(_normales_obj, (ARRAY_2D(_triangles, j, (3 * k + 2), 9) - 1), 2, 3);
t[0] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 0, 3);
t[1] = ARRAY_2D(_tex_coords_obj, (ARRAY_2D(_triangles, j, (3 * k + 1), 9) - 1), 1, 3);
}
}
free(_vertices_obj);
free(_normales_obj);
free(_tex_coords_obj);
free(_triangles);
/* Unmap vertex buffer. */
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD));
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
if (!evas_3d_mesh_aabb_add_to_frame(pd, 0, stride_pos))
{
ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0);
}
}

View File

@ -1 +1,401 @@
//dummy of saver/loader
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include "stdio.h"
#include "evas_common_private.h"
#include "evas_private.h"
#include <Eina.h>
/* set value to position [x][y] to array name which have. */
#define ARRAY_2D(name, x, y, count_y) (*(name + x * count_y + y))
/* Structures for reading data from file. */
typedef struct _PLY_Header PLY_Header;
struct _PLY_Header
{
int vertices_count;
int triangles_count;
Eina_Bool existence_of_geometries;
Eina_Bool existence_of_normals;
Eina_Bool existence_of_texcoords;
Eina_Bool existence_of_colors;
};
static inline char*
_file_to_buf(const char *file, long *length)//prepare text file for reading
{
FILE *file_for_print;
char *buf;
int unused __attribute__((unused));//this variable fixes warning "ignoring return value of fread"
*length = 0;
file_for_print = fopen(file, "rb");
if (!file_for_print) return NULL;
fseek(file_for_print, 0, SEEK_END);//set file_for_print to the end of file
*length = ftell(file_for_print);//set current position of file_for_print
buf = malloc(*length + 1);
fseek(file_for_print, 0, SEEK_SET);//set file_for_print to the begining of file
unused = fread(buf, *length, 1, file_for_print);
fclose(file_for_print);
buf[*length] = '\0';
return buf;
}
/* create new header */
static inline PLY_Header
_new_ply_header()
{
PLY_Header header;
header.vertices_count = 0;
header.triangles_count = 0;
header.existence_of_geometries = EINA_FALSE;
header.existence_of_normals = EINA_FALSE;
header.existence_of_texcoords = EINA_FALSE;
header.existence_of_colors = EINA_FALSE;
return header;
}
static inline char *
_to_next_line(char *current)
{
while (*current != '\n') current++;
current++;
return current;
}
static inline char *
_to_begin_of_line(char *current)
{
while (*current != '\n') current--;
current++;
return current;
}
static inline char *
_to_next_number(char *current, int count)
{
int i;
for (i = 0; i < count; i++)
{
while (*current != ' ') current++;
current++;
}
return current;
}
static inline char *
_read_data(float *array, int place, int count, char *current, float divider)
{
int i;
for (i = 0; i < count; i++)
{
sscanf (current,"%f", &ARRAY_2D(array, place, i, count));
ARRAY_2D(array, place, i, count) /= divider;
current = _to_next_number(current, 1);
}
return current;
}
static inline PLY_Header
_read_header(char *start)//Check properties of mesh in .ply file.
{
eina_init();
Eina_Bool reading_vertices = EINA_TRUE, check_next_char = EINA_FALSE;
int vertex_lines, triangles = 0, vertices_in_current_face = 0;
char **helping_pointer;
char *current;
PLY_Header header;
header = _new_ply_header();
helping_pointer = eina_str_split(start, "vertex ", 0);
if (helping_pointer == NULL)
{
ERR("File have not kayword vertex. It is necessary.");
return header;
}
sscanf(helping_pointer[1], "%d", &header.vertices_count);
free(helping_pointer);
helping_pointer = eina_str_split(start, "end_header\n", 0);
if (helping_pointer == NULL)
{
ERR("File have not kayword end_header. It is necessary.");
return header;
}
current = helping_pointer[1];
vertex_lines = header.vertices_count;
while (*current != '\0')
{
if (vertex_lines == 1)
reading_vertices = EINA_FALSE;
if (*current == '\n')
{
if (reading_vertices)
vertex_lines--;
else
check_next_char = EINA_TRUE;
}
if (check_next_char)
{
if ((*current <= '9') && (*current >= '0'))
vertices_in_current_face = (vertices_in_current_face * 10) + (*current - '0');
else if (*current >= ' ')
{
triangles += (vertices_in_current_face - 2);
vertices_in_current_face = 0;
check_next_char = EINA_FALSE;
}
}
current++;
}
header.triangles_count = triangles;
free(helping_pointer);
/* analyse flags used when file was saved in blender */
helping_pointer = eina_str_split(start, "property float ", 0);
if ((helping_pointer[1] != NULL) && (*helping_pointer[1] == 'x') &&
(helping_pointer[2] != NULL) && (*helping_pointer[2] == 'y') &&
(helping_pointer[3] != NULL) && (*helping_pointer[3] == 'z'))
header.existence_of_geometries = EINA_TRUE;
else return header;
if ((helping_pointer[4] != NULL) && (*helping_pointer[4] == 'n') &&
(helping_pointer[5] != NULL) && (*helping_pointer[5] == 'n') &&
(helping_pointer[6] != NULL) && (*helping_pointer[6] == 'n'))
header.existence_of_normals = EINA_TRUE;
if ((header.existence_of_normals &&
((helping_pointer[7] != NULL) && (*helping_pointer[7] == 's') &&
(helping_pointer[8] != NULL) && (*helping_pointer[8] == 't'))) ||
(!header.existence_of_normals &&
((helping_pointer[4] != NULL) && (*helping_pointer[4] == 's') &&
(helping_pointer[5] != NULL) && (*helping_pointer[5] == 't'))))
header.existence_of_texcoords = EINA_TRUE;
helping_pointer = eina_str_split(start, "property uchar ", 0);
if ((helping_pointer[1] != NULL) && (*helping_pointer[1] == 'r') &&
(helping_pointer[2] != NULL) && (*helping_pointer[2] == 'g') &&
(helping_pointer[3] != NULL) && (*helping_pointer[3] == 'b'))
header.existence_of_colors = EINA_TRUE;
free(helping_pointer);
return header;
}
void
evas_3d_mesh_file_ply_set(Evas_3D_Mesh *mesh, const char *file)
{
long length;
Evas_3D_Mesh_Data *pd;
int i = 0, j = 0, k = 0, count_of_triangles_in_line = 0;
float *pos, *nor, *tex, *col;
int stride_pos, stride_nor, stride_tex, stride_col;
char *start, *current;
PLY_Header header;
float *_vertices_ply = NULL, *_normals_ply = NULL, *_tex_coords_ply = NULL, *_colors_ply = NULL;
char **helping_pointer;
start = _file_to_buf(file, &length);
if (start == NULL)
{
ERR("Buffer is empty after preparation file for reading.");
return;
}
header = _read_header(start);
if (!header.existence_of_geometries)
{
ERR("File have not x, y, or z field as the first 3 float fields. They are necessary.");
return;
}
helping_pointer = eina_str_split(start, "end_header\n", 0);
if (helping_pointer == NULL)
{
ERR("File have not kayword end_header. It is necessary.");
return;
}
current = helping_pointer[1];
_vertices_ply = malloc(header.vertices_count * 3 * sizeof(float));
if (header.existence_of_normals)
_normals_ply = malloc(header.vertices_count * 3 * sizeof(float));
if (header.existence_of_texcoords)
_tex_coords_ply = malloc(header.vertices_count * 2 * sizeof(float));
if (header.existence_of_colors)
_colors_ply = malloc(header.vertices_count * 3 * sizeof(float));
int *_triangles = malloc(header.triangles_count * 3 * sizeof(int));
if ((header.existence_of_geometries && (_vertices_ply == NULL)) ||
(header.existence_of_normals && (_normals_ply == NULL)) ||
(header.existence_of_texcoords && (_tex_coords_ply == NULL)) ||
(header.existence_of_colors && (_colors_ply == NULL)) ||
(_triangles == NULL))
{
ERR("Allocate memory is failed.");
free(start);
free(_vertices_ply);
free(_normals_ply);
free(_tex_coords_ply);
free(_colors_ply);
free(_triangles);
return;
}
for (i = 0; i < header.vertices_count; i++)
{
current = _read_data(_vertices_ply, i, 3, current, 1.0);
if (header.existence_of_normals)
current = _read_data(_normals_ply, i, 3, current, 1.0);
if (header.existence_of_texcoords)
current = _read_data(_tex_coords_ply, i, 2, current, 1.0);
if (header.existence_of_colors)
current = _read_data(_colors_ply, i, 3, current, 255.0);
current = _to_begin_of_line(current);
}
for (i = 0; i < header.triangles_count;)
{
sscanf (current,"%d", &count_of_triangles_in_line);
count_of_triangles_in_line -= 2;
current = _to_next_number(current, 1);
sscanf (current,"%i", &ARRAY_2D(_triangles, i, 0, 3));
for (j = 0; j < count_of_triangles_in_line; j++)
{
if (j > 0)
ARRAY_2D(_triangles, i, 0, 3) = ARRAY_2D(_triangles, (i - 1), 0, 3);
current = _to_next_number(current, 1);
sscanf (current,"%i %i",
&ARRAY_2D(_triangles, i, 1, 3),
&ARRAY_2D(_triangles, i, 2, 3));
i++;
}
current = _to_next_line(current);
}
/* prepare of mesh and take pointers to data which must be read */
eo_do(mesh,
evas_3d_mesh_vertex_count_set(header.triangles_count * 3),
evas_3d_mesh_vertex_assembly_set(EVAS_3D_VERTEX_ASSEMBLY_TRIANGLES),
evas_3d_mesh_frame_add(0),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_POSITION, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_NORMAL, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_TEXCOORD, 0, NULL),
evas_3d_mesh_frame_vertex_data_copy_set(0, EVAS_3D_VERTEX_COLOR, 0, NULL),
pos = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_POSITION),
nor = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_NORMAL),
tex = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_TEXCOORD),
col = (float *)evas_3d_mesh_frame_vertex_data_map(0, EVAS_3D_VERTEX_COLOR),
stride_pos = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_POSITION),
stride_nor = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_NORMAL),
stride_tex = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_TEXCOORD),
stride_col = evas_3d_mesh_frame_vertex_stride_get(0, EVAS_3D_VERTEX_COLOR));
if (stride_pos == 0) stride_pos = sizeof(float) * 3;
if (stride_nor == 0) stride_nor = sizeof(float) * 3;
if (stride_tex == 0) stride_tex = sizeof(float) * 2;
if (stride_col == 0) stride_col = sizeof(float) * 4;
for (j = 0; j < header.triangles_count; j++)
{
for (k = 0; k < 3; k++)
{
float *p, *n, *t, *c;
p = (float *)((char *)pos + stride_pos * (j * 3 + k));
n = (float *)((char *)nor + stride_nor * (j * 3 + k));
t = (float *)((char *)tex + stride_tex * (j * 3 + k));
c = (float *)((char *)col + stride_col * (j * 3 + k));
p[0] = ARRAY_2D(_vertices_ply, ARRAY_2D(_triangles, j, k, 3), 0, 3);
p[1] = ARRAY_2D(_vertices_ply, ARRAY_2D(_triangles, j, k, 3), 1, 3);
p[2] = ARRAY_2D(_vertices_ply, ARRAY_2D(_triangles, j, k, 3), 2, 3);
if (header.existence_of_normals)
{
n[0] = ARRAY_2D(_normals_ply, ARRAY_2D(_triangles, j, k, 3), 0, 3);
n[1] = ARRAY_2D(_normals_ply, ARRAY_2D(_triangles, j, k, 3), 1, 3);
n[2] = ARRAY_2D(_normals_ply, ARRAY_2D(_triangles, j, k, 3), 2, 3);
}
else
{
n[0] = 0.0;
n[1] = 0.0;
n[2] = 0.0;
}
if (header.existence_of_texcoords)
{
t[0] = ARRAY_2D(_tex_coords_ply, ARRAY_2D(_triangles, j, k, 3), 0, 2);
t[1] = ARRAY_2D(_tex_coords_ply, ARRAY_2D(_triangles, j, k, 3), 1, 2);
}
else
{
t[0] = 0.0;
t[1] = 0.0;
}
if (header.existence_of_colors)
{
c[0] = ARRAY_2D(_colors_ply, ARRAY_2D(_triangles, j, k, 3), 0, 3);
c[1] = ARRAY_2D(_colors_ply, ARRAY_2D(_triangles, j, k, 3), 1, 3);
c[2] = ARRAY_2D(_colors_ply, ARRAY_2D(_triangles, j, k, 3), 2, 3);
c[3] = 1.0;
}
else
{
c[0] = 0.0;
c[1] = 0.0;
c[2] = 0.0;
c[3] = 1.0;
}
}
}
free(helping_pointer);
free(_vertices_ply);
if (header.existence_of_normals)
free(_normals_ply);
if (header.existence_of_texcoords)
free(_tex_coords_ply);
if (header.existence_of_colors)
free(_colors_ply);
free(_triangles);
/* Unmap vertex buffer. */
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_POSITION),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_NORMAL),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_TEXCOORD),
evas_3d_mesh_frame_vertex_data_unmap(0, EVAS_3D_VERTEX_COLOR));
pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
if (!evas_3d_mesh_aabb_add_to_frame(pd, 0, stride_pos))
{
ERR("Axis-Aligned Bounding Box wan't added in frame %d ", 0);
}
}

View File

@ -1 +1,197 @@
//dummy of saver/loader
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include <stdio.h>
#include "evas_common_private.h"
#include "evas_private.h"
#define COMPONENT_OF_DEFAULT_GREY_COLOR 0.3
#define TRANSPARENCY_OF_DEFAULT_GREY_COLOR 0.5
extern Evas_3D_File_Eet* eet_file;
extern const char EVAS_3D_FILE_CACHE_FILE_ENTRY[];
extern Eet_Data_Descriptor *_file_descriptor;
void
_set_geometry_to_eet_file_from_mesh(Evas_3D_Mesh_Data *mesh,
Evas_3D_Mesh_Eet *eet_mesh,
Evas_3D_Header_Eet *eet_header,
Evas_3D_Mesh_Frame *f)
{
Evas_3D_Vertex_Buffer *vb;
int i;
float *src;
Evas_3D_Vertex_Eet *vertices =
malloc(sizeof(Evas_3D_Vertex_Eet) * mesh->vertex_count);
Evas_3D_Geometry_Eet *geometry =
malloc(sizeof(Evas_3D_Geometry_Eet));
int *geometries = malloc(sizeof(int));
if ((vertices == NULL) || (geometry == NULL))
{
ERR("Allocating of memory is failed.");
free(vertices);
free(geometry);
free(geometries);
return;
}
geometry->vertices_count = mesh->vertex_count;
geometries[0] = mesh->vertex_count;
#define SAVE_GEOMETRICS(a, component)\
vb = &f->vertices[a];\
if (vb->data == NULL)\
{\
ERR("Reading of geometrics is failed.");\
free(vertices);\
free(geometry);\
free(geometries);\
return;\
}\
src = (float *)vb->data;\
for (i = 0; i < mesh->vertex_count; i++)\
{\
vertices[i].component.x = src[0];\
vertices[i].component.y = src[1];\
vertices[i].component.z = src[2];\
src += f->vertices[a].element_count;\
}
geometry->vertices = vertices;
SAVE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, position)
SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, normal)
SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, texcoord)
#undef SAVE_GEOMETRICS
eet_mesh->geometries = geometry;
eet_header->geometries = geometries;
}
void
_set_material_to_eet_file_from_mesh(Evas_3D_Mesh_Eet *eet_mesh,
Evas_3D_Header_Eet *eet_header,
Evas_3D_Mesh_Frame *f)
{
int i;
Evas_3D_Material_Data *material =
eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);
Evas_3D_Material_Eet *saved_materials =
malloc(sizeof(Evas_3D_Material_Eet));
Evas_3D_Color_Eet *saved_colors =
malloc(sizeof(Evas_3D_Color_Eet) * EVAS_3D_MATERIAL_ATTRIB_COUNT);
int *materials = malloc(sizeof(int));
if ((saved_materials == NULL) || (saved_colors == NULL))
{
ERR("Allocating of memory is failed.");
free(material);
free(saved_materials);
free(saved_colors);
free(materials);
return;
}
if (material == NULL)
{
ERR("Default material is set to saved file, because custom material \
was not saved before using of function evas_3d_mesh_save.");
for (i = 0; i < 5; i++)
{
saved_colors[i].r = COMPONENT_OF_DEFAULT_GREY_COLOR;
saved_colors[i].g = COMPONENT_OF_DEFAULT_GREY_COLOR;
saved_colors[i].b = COMPONENT_OF_DEFAULT_GREY_COLOR;
saved_colors[i].a = TRANSPARENCY_OF_DEFAULT_GREY_COLOR;
}
saved_materials->shininess = 50;
}
else
{
for (i = 0; i < 5; i++)
{
saved_colors[i].r = material->attribs[i].color.r;
saved_colors[i].g = material->attribs[i].color.g;
saved_colors[i].b = material->attribs[i].color.b;
saved_colors[i].a = material->attribs[i].color.a;
}
saved_materials->shininess = material->shininess;
}
saved_materials->colors_count = EVAS_3D_MATERIAL_ATTRIB_COUNT;
materials[0] = EVAS_3D_MATERIAL_ATTRIB_COUNT;
saved_materials->id = 1;
saved_materials->colors = saved_colors;
eet_mesh->materials = saved_materials;
eet_header->materials = materials;
}
void
_set_frame_to_eet_file_from_mesh(Evas_3D_Mesh_Eet *eet_mesh)
{
eet_mesh->frames = malloc(sizeof(Evas_3D_Frame_Eet));
if (eet_mesh->frames == NULL)
{
ERR("Allocating of memory is failed.");
return;
}
eet_mesh->frames->id = 1;
eet_mesh->frames->geometry_id = 1;
eet_mesh->frames->material_id = 1;
}
void
evas_3d_mesh_save_eet(Evas_3D_Mesh *mesh,
const char *file,
Evas_3D_Mesh_Frame *f)
{
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
Eet_File *ef = eet_open(file, EET_FILE_MODE_WRITE);
Evas_3D_Mesh_Eet* eet_mesh = malloc(sizeof(Evas_3D_Mesh_Eet));
Evas_3D_Header_Eet* eet_header = malloc(sizeof(Evas_3D_Header_Eet));
_evas_3d_eet_file_init();
eet_file = _evas_3d_eet_file_new();
eet_mesh->materials_count = 1;
eet_header->materials_count = 1;
eet_mesh->frames_count = 1;
eet_header->frames = 1;
eet_mesh->geometries_count = 1;
eet_header->geometries_count = 1;
eet_header->version = 1;
_set_geometry_to_eet_file_from_mesh(pd, eet_mesh, eet_header, f);
_set_material_to_eet_file_from_mesh(eet_mesh, eet_header, f);
_set_frame_to_eet_file_from_mesh(eet_mesh);
if (ef == NULL)
{
ERR("Opening of file is failed.");
free(eet_mesh);
free(eet_header);
_evas_3d_eet_file_free();
return;
}
eet_file->mesh = eet_mesh;
eet_file->header = eet_header;
eet_data_write(ef,
_file_descriptor,
EVAS_3D_FILE_CACHE_FILE_ENTRY,
eet_file,
EINA_TRUE);
eet_close(ef);
_evas_3d_eet_file_free();
}

View File

@ -1 +1,137 @@
//dummy of saver/loader
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <time.h>
#include "stdio.h"
#include "evas_common_private.h"
#include "evas_private.h"
#define OPEN_FILE(extension)\
int length=strlen(file);\
char * extension = "."#extension;\
char * _##extension##_file_name = (char *)malloc(length+4);\
strcpy(_##extension##_file_name,file);\
strcpy(_##extension##_file_name+length,extension);\
FILE * _##extension##_file = fopen(_##extension##_file_name, "w+");\
free(_##extension##_file_name);
#define SAVE_GEOMETRICS(a, format)\
vb = &f->vertices[a];\
fprintf(_obj_file, "o %s\n",file);\
if (vb->data == NULL)\
{\
ERR("Reading of geometrics is failed.");\
fclose(_obj_file);\
return;\
}\
src = (float *)vb->data;\
for (i = 0; i < pd->vertex_count; i++)\
{\
fprintf(_obj_file, format, src[0], src[1], src[2]);\
src += f->vertices[a].element_count;\
}
static void
_save_mesh(Evas_3D_Mesh_Data *pd, const char *file, Evas_3D_Mesh_Frame *f)
{
Evas_3D_Vertex_Buffer *vb;
time_t current_time;
char* c_time_string;
int i;
float *src;
OPEN_FILE(obj)
if (!_obj_file)
{
ERR("File open '%s' for save failed", file);
return;
}
fprintf(_obj_file, "# Evas_3D saver OBJ v0.03 \n");//_obj_file created in macro
/* Adding time comment to .obj file. */
current_time = time(NULL);
if (current_time == ((time_t)-1))
{
ERR("Failure to compute the current time.");
fclose(_obj_file);
return;
}
c_time_string = ctime(&current_time);
if (c_time_string == NULL)
{
ERR("Failure to convert the current time.");
fclose(_obj_file);
return;
}
fprintf(_obj_file,"# Current time is %s \n", c_time_string);
fprintf(_obj_file,"mtllib %s.mtl \n\n", file);
/* Adding geometrics to file. */
if (f == NULL)
{
ERR("Not existing mesh frame.");
fclose(_obj_file);
return;
}
SAVE_GEOMETRICS(EVAS_3D_VERTEX_POSITION, "v %.4f %.4f %.4f \n")
SAVE_GEOMETRICS(EVAS_3D_VERTEX_NORMAL, "vn %.4f %.4f %.4f \n")
SAVE_GEOMETRICS(EVAS_3D_VERTEX_TEXCOORD, "vt %.4f %.4f %.4f \n")
fprintf(_obj_file,"usemtl Material\n s off\n");
for (i = 1; i <= pd->vertex_count; i++)//numeration of faces in .obj started from 1
{
fprintf(_obj_file,"f %i/%i/%i ", i, i, i);
i++;
fprintf(_obj_file,"%i/%i/%i ", i, i, i);
i++;
fprintf(_obj_file,"%i/%i/%i \n", i, i, i);
}
fclose(_obj_file);
}
static void
_save_material(Evas_3D_Mesh_Data *pd EINA_UNUSED, const char *file, Evas_3D_Mesh_Frame *f)
{
Evas_3D_Material_Data *mat = eo_data_scope_get(f->material, EVAS_3D_MATERIAL_CLASS);
OPEN_FILE(mtl)
if (!_mtl_file)
{
ERR("File open '%s' for save failed", file);
return;
}
fprintf(_mtl_file, "# Evas_3D saver OBJ v0.03 \n");//_mtl_file created in macro
fprintf(_mtl_file, "# Material Count: 1 \n\n");
fprintf(_mtl_file, "newmtl Material \n");
fprintf(_mtl_file, "Ns 1.000000 \n");//exp factor for specular highlight
fprintf(_mtl_file, "Ka %.6f %.6f %.6f \n",
(float)mat->attribs[EVAS_3D_MATERIAL_AMBIENT].color.r,
(float)mat->attribs[EVAS_3D_MATERIAL_AMBIENT].color.g,
(float)mat->attribs[EVAS_3D_MATERIAL_AMBIENT].color.b);
fprintf(_mtl_file, "Kd %.6f %.6f %.6f \n",
(float)mat->attribs[EVAS_3D_MATERIAL_DIFFUSE].color.r,
(float)mat->attribs[EVAS_3D_MATERIAL_DIFFUSE].color.g,
(float)mat->attribs[EVAS_3D_MATERIAL_DIFFUSE].color.b);
fprintf(_mtl_file, "Ks %.6f %.6f %.6f \n",
(float)mat->attribs[EVAS_3D_MATERIAL_SPECULAR].color.r,
(float)mat->attribs[EVAS_3D_MATERIAL_SPECULAR].color.g,
(float)mat->attribs[EVAS_3D_MATERIAL_SPECULAR].color.b);
fprintf(_mtl_file, "Ni 1.000000 \n");//optical density
fprintf(_mtl_file, "d 1.000000 \n");//a factor d of 1.0 is fully opaque material
fprintf(_mtl_file, "illum 2 \n");//illumination properties
fclose(_mtl_file);
}
void
evas_3d_mesh_save_obj(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f)
{
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
_save_mesh(pd, file, f);
_save_material(pd, file, f);
}

View File

@ -1 +1,61 @@
//dummy of saver/loader
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include <stdlib.h>
#include <time.h>
#include "stdio.h"
#include "math.h"
#include "evas_common_private.h"
#include "evas_private.h"
void
evas_3d_mesh_save_ply(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f)
{
float *src_pos, *src_nor, *src_tex, *src_col;
int i;
Evas_3D_Mesh_Data *pd = eo_data_scope_get(mesh, EVAS_3D_MESH_CLASS);
FILE *_ply_file = fopen(file, "w+");
if (!_ply_file)
{
ERR("File open '%s' for save failed", file);
return;
}
fprintf(_ply_file,"ply\nformat ascii 1.0\ncomment Created by EFL evas_3d_mesh_saver_ply.c" \
"version 1 (sub 0) - www.enlightenment.org, source file: ''\n");
fprintf(_ply_file,"element vertex %d\n", pd->vertex_count);
fprintf(_ply_file,"property float x\nproperty float y\nproperty float z\n" \
"property float nx\nproperty float ny\nproperty float nz\n" \
"property float s\nproperty float t\n" \
"property uchar red\nproperty uchar green\nproperty uchar blue\n");
fprintf(_ply_file,"element face %d\nproperty list uchar uint vertex_indices\nend_header\n",
pd->vertex_count / 3);
src_pos = (float*)(&f->vertices[EVAS_3D_VERTEX_POSITION])->data;
src_nor = (float*)(&f->vertices[EVAS_3D_VERTEX_NORMAL])->data;
src_tex = (float*)(&f->vertices[EVAS_3D_VERTEX_TEXCOORD])->data;
src_col = (float*)(&f->vertices[EVAS_3D_VERTEX_COLOR])->data;
for (i = 0; i < pd->vertex_count; i++)
{
fprintf(_ply_file,"%f %f %f %f %f %f %f %f %.0f %.0f %.0f\n",
src_pos[0], src_pos[1], src_pos[2],
src_nor[0], src_nor[1], src_nor[2],
src_tex[0], src_tex[1],
round(src_col[0] * 255), round(src_col[1] * 255), round(src_col[2] * 255));
src_pos += 3;
src_nor += 3;
src_tex += 2;
src_col += 4;
}
for (i = 0; i < pd->vertex_count;)
{
fprintf(_ply_file,"3 %d %d %d\n", i, i + 1, i + 2);
i += 3;
}
fclose(_ply_file);
}