evas: add API for creation Evas_3D node primitives.

Summary: Now mechanism of creation of primitives is similar to model loading.

Reviewers: Oleksander, Hermet, raster, cedric

Reviewed By: cedric

Subscribers: cedric

Differential Revision: https://phab.enlightenment.org/D2516

Signed-off-by: Cedric BAIL <cedric@osg.samsung.com>
This commit is contained in:
Bogdan Devichev 2015-05-26 18:49:15 +02:00 committed by Cedric BAIL
parent abc1eabecb
commit 6dac83e643
17 changed files with 1511 additions and 3 deletions

View File

@ -29,6 +29,7 @@ evas_eolian_files = \
lib/evas/canvas/evas_3d_material.eo\
lib/evas/canvas/evas_3d_light.eo\
lib/evas/canvas/evas_3d_mesh.eo\
lib/evas/canvas/evas_3d_primitive.eo\
lib/evas/canvas/evas_3d_node.eo\
lib/evas/canvas/evas_3d_scene.eo\
lib/evas/canvas/evas_3d_object.eo \
@ -202,6 +203,7 @@ 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_primitive.c \
lib/evas/canvas/evas_3d_node_callback.h
# Model savers/loaders (will be replaced to modules in next commits)
@ -215,6 +217,18 @@ 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
# 3d primitives
lib_evas_libevas_la_SOURCES += \
lib/evas/common3d/primitives/tabulated_primitives/square.c \
lib/evas/common3d/primitives/tabulated_primitives/cube.c \
lib/evas/common3d/primitives/solids_of_revolution/sphere.c \
lib/evas/common3d/primitives/solids_of_revolution/torus.c \
lib/evas/common3d/primitives/solids_of_revolution/cylinder.c \
lib/evas/common3d/primitives/solids_of_revolution/cone.c \
lib/evas/common3d/primitives/surfaces/surface.c \
lib/evas/common3d/primitives/surfaces/terrain.c \
lib/evas/common3d/primitives/primitive_common.c
# Evas_VG
lib_evas_libevas_la_SOURCES += \
lib/evas/canvas/evas_object_vg.c \

View File

@ -303,6 +303,15 @@ EAPI extern const Eo_Event_Description _EVAS_CANVAS_EVENT_VIEWPORT_RESIZE;
* contained in a single node.
*/
/**
* @defgroup Evas_3D_Primitive Primitive Object
* @ingroup Evas_3D
*
* A primitive object is an object with necessary data for creating meshes with ptimitive shapes.
* Data from a primitive can be set to Evas_3D_Mesh by using evas_3d_mesh_from_primitive_set()
* function.
*/
/**
* @defgroup Evas_3D_Texture Texture Object
* @ingroup Evas_3D
@ -434,6 +443,33 @@ typedef Eo Evas_3D_Material;
#define _EVAS_3D_MATERIAL_EO_CLASS_TYPE
/**
* @typedef Evas_3D_Primitive
*
* Primitive object handle
*
* @since 1.15
* @ingroup Evas_3D_Primitive
*/
typedef Eo Evas_3D_Primitive;
#define _EVAS_3D_PRIMITIVE_EO_CLASS_TYPE
/**
* @typedef Evas_3D_Surface_Func
*
* User-defined parametric surface function.
* Used for easy creation of custom surfaces as a primitive.
*
* @since 1.15
* @ingroup Evas_3D_Primitive
*/
typedef void (Evas_3D_Surface_Func)(Evas_Real *out_x,
Evas_Real *out_y,
Evas_Real *out_z,
Evas_Real a,
Evas_Real b);
/**
* Type of 3D Object
*
@ -451,6 +487,7 @@ typedef enum _Evas_3D_Object_Type
EVAS_3D_OBJECT_TYPE_MESH,
EVAS_3D_OBJECT_TYPE_TEXTURE,
EVAS_3D_OBJECT_TYPE_MATERIAL,
EVAS_3D_OBJECT_TYPE_PRIMITIVE,
} Evas_3D_Object_Type;
/**
@ -716,7 +753,7 @@ typedef enum _Evas_3D_Wrap_Mode
} Evas_3D_Wrap_Mode;
/**
* Mesh Primitive
* Mesh primitive
*
* @since 1.12
* @ingroup Evas_3D_Types
@ -740,9 +777,27 @@ typedef enum _Evas_3D_Mesh_Primitive
/**< Custom surface (can use pointer to users function, precision and texture scale) */
EVAS_3D_MESH_PRIMITIVE_SURFACE,
/**< Terrain as surface with pointer to Perlin's noise function */
EVAS_3D_MESH_PRIMITIVE_TERRAIN
EVAS_3D_MESH_PRIMITIVE_TERRAIN,
/**< Count of supported primitives */
EVAS_3D_MESH_PRIMITIVE_COUNT
} Evas_3D_Mesh_Primitive;
/**
* Mode of mesh primitive
*
* @since 1.15
* @ingroup Evas_3D_Types
*/
typedef enum _Evas_3D_Primitive_Mode
{
/**< Default mode of primitive */
EVAS_3D_PRIMITIVE_MODE_DEFAULT = 0,
/**< Primitive without base (supported for cylinder and cone) */
EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE,
/**< Ptimitive with alternative UV (supported for sphere)*/
EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV
} Evas_3D_Primitive_Mode;
/**
* Texture filters
*
@ -818,6 +873,8 @@ typedef enum _Evas_3D_Material_Attrib
#include "canvas/evas_3d_mesh.eo.h"
#include "canvas/evas_3d_primitive.eo.h"
#include "canvas/evas_3d_node.eo.h"
#include "canvas/evas_3d_scene.eo.h"

View File

@ -893,6 +893,19 @@ _evas_3d_mesh_efl_file_save(Eo *obj, Evas_3D_Mesh_Data *pd,
return EINA_TRUE;
}
EOLIAN static void
_evas_3d_mesh_from_primitive_set(Eo *obj,
Evas_3D_Mesh_Data *pd EINA_UNUSED,
int frame,
Eo *primitive)
{
if ((primitive == NULL) || (obj == NULL)) return;
Evas_3D_Primitive_Data *ppd = eo_data_scope_get(primitive, EVAS_3D_PRIMITIVE_CLASS);
evas_common_set_model_from_primitive(obj, frame, ppd);
}
static inline void
_mesh_frame_find(Evas_3D_Mesh_Data *mesh, int frame,
Eina_List **l, Eina_List **r)

View File

@ -291,7 +291,16 @@ class Evas_3D_Mesh (Evas_3D_Object, Evas.Common_Interface, Efl.File)
@out dfactor: Evas_3D_Blend_Func; /*@ Pointer to receive destination blendin factors key.*/
}
}
from_primitive_set {
/*@
Set the data of given mesh frame from the given primitive
@ingroup Evas_3D_Mesh
*/
params {
@in frame: int; /*@ Specifies data of which frame of given mesh will be set.*/
@in primitive: Evas_3D_Primitive *; /*@ Specifies which data will be set.*/
}
}
@property shade_mode {
set {
/*@

View File

@ -0,0 +1,162 @@
#include "evas_common_private.h"
#include "evas_private.h"
#define MY_CLASS EVAS_3D_PRIMITIVE_CLASS
static inline void
_primitive_init(Evas_3D_Primitive_Data *pd)
{
pd->form = EVAS_3D_MESH_PRIMITIVE_NONE;
pd->ratio = 3.0;
pd->precision = 10;
pd->surface = NULL;
pd->tex_scale.x = 1.0;
pd->tex_scale.y = 1.0;
}
static inline void
_primitive_fini(Evas_3D_Primitive_Data *pd)
{
if (pd->surface)
free(pd->surface);
}
EAPI Evas_3D_Primitive *
evas_3d_primitive_add(Evas *e)
{
MAGIC_CHECK(e, Evas, MAGIC_EVAS);
return NULL;
MAGIC_CHECK_END();
Evas_Object *eo_obj = eo_add(MY_CLASS, e);
return eo_obj;
}
EOLIAN static Eo *
_evas_3d_primitive_eo_base_constructor(Eo *obj, Evas_3D_Primitive_Data *pd)
{
obj = eo_do_super_ret(obj, MY_CLASS, obj, eo_constructor());
eo_do(obj, evas_3d_object_type_set(EVAS_3D_OBJECT_TYPE_PRIMITIVE));
_primitive_init(pd);
return obj;
}
EOLIAN static void
_evas_3d_primitive_eo_base_destructor(Eo *obj, Evas_3D_Primitive_Data *pd)
{
_primitive_fini(pd);
eo_do_super(obj, MY_CLASS, eo_destructor());
}
EOLIAN static void
_evas_3d_primitive_form_set(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd,
Evas_3D_Mesh_Primitive form)
{
if ((form < EVAS_3D_MESH_PRIMITIVE_NONE) ||
(form >= EVAS_3D_MESH_PRIMITIVE_COUNT))
{
ERR("Wrong form of primitive.");
return;
}
if (pd->form != form)
pd->form = form;
}
EOLIAN static Evas_3D_Mesh_Primitive
_evas_3d_primitive_form_get(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd)
{
return pd->form;
}
EOLIAN static void
_evas_3d_primitive_mode_set(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd,
Evas_3D_Primitive_Mode mode)
{
if (pd->mode != mode)
pd->mode = mode;
}
EOLIAN static Evas_3D_Primitive_Mode
_evas_3d_primitive_mode_get(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd)
{
return pd->mode;
}
EOLIAN static void
_evas_3d_primitive_ratio_set(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd,
Evas_Real ratio)
{
pd->ratio = ratio;
}
EOLIAN static Evas_Real
_evas_3d_primitive_ratio_get(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd)
{
return pd->ratio;
}
EOLIAN static void
_evas_3d_primitive_precision_set(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd,
int precision)
{
if ((precision < 3))
{
ERR("Precision of Evas_3D_Primitive cannot be less than 3.");
return;
}
if ((precision >= 100))
{
ERR("%s\n%s",
"Be careful with precision of Evas_3D_Primitive more than 100.",
"It can give unacceptable result.");
}
if (pd->precision != precision)
pd->precision = precision;
}
EOLIAN static int
_evas_3d_primitive_precision_get(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd)
{
return pd->precision;
}
EOLIAN static void
_evas_3d_primitive_surface_set(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd,
Evas_3D_Surface_Func surface_func)
{
pd->surface = surface_func;
}
EOLIAN static void
_evas_3d_primitive_tex_scale_set(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd,
Evas_Real x,
Evas_Real y)
{
if (x) pd->tex_scale.x = x;
if (y) pd->tex_scale.y = y;
}
EOLIAN static void
_evas_3d_primitive_tex_scale_get(Eo *obj EINA_UNUSED,
Evas_3D_Primitive_Data *pd,
Evas_Real *x,
Evas_Real *y)
{
if (x) *x = pd->tex_scale.x;
if (y) *y = pd->tex_scale.y;
}
#include "canvas/evas_3d_primitive.eo.c"

View File

@ -0,0 +1,179 @@
class Evas_3D_Primitive (Evas_3D_Object, Evas.Common_Interface)
{
legacy_prefix: null;
data: Evas_3D_Primitive_Data;
methods {
@property form {
set {
/*
*Set the form of the given primitive.
*
*Form defines which function will be chosen to set data to mesh
*on call of evas_3d_mesh_primitive_set.
*
*Now avaliable next forms of primitives:
*-tabulated primitives: SQUARE and CUBE;
*-solids of revolution: CYLINDER, CONE, SPHERE and TORUS;
*-surfaces: SURFACE and TERRAIN.
*
*Default form is EVAS_3D_MESH_PRIMITIVE_NONE
*
*@ingroup Evas_3D_Primitive
*/
}
get {
/*
*Get the form of the given primitive.
*@see evas_3d_primitive_form_set()
*@return The form of primitive.
*@ingroup Evas_3D_Primitive
*/
}
values {
form: Evas_3D_Mesh_Primitive; /*@ Form of primitive.*/
}
}
@property mode {
set {
/*
*Set the mode of the given primitive.
*
*Mode defines which function will be chosen to set data to mesh
*on call of evas_3d_mesh_primitive_set. It helps to choose
*alternative algorithm for primitive with given form
*(like cone without base or sphere textured in alternative way).
*
*Now avaliable next mods of primitives:
*-witout base (bases): supported for cylinder and cone;
*-with alternative UV: supported by sphere;
*
*Default form is EVAS_3D_PRIMITIVE_MODE_DEFAULT
*
*@ingroup Evas_3D_Primitive
*/
}
get {
/*
*Get the mode of the given primitive.
*@see evas_3d_primitive_mode_set()
*@return The mode of primitive.
*@ingroup Evas_3D_Primitive
*/
}
values {
mode: Evas_3D_Primitive_Mode; /*@ Mode of primitive.*/
}
}
@property ratio {
set {
/*
*Set the ratio of the given primitive.
*
*Now ratio uses only in torus as the ratio of the
*major radius and minor radius. For this usage
*Avaliable values is from 1.0 to infinity.
*If ratio for torus has a bad value,
*will be used 3.0 as ratio. Like ratio of usual doughnut.
*
*Default ratio is 3.0
*
*@ingroup Evas_3D_Primitive
*/
}
get {
/*
*Get the ratio of the given primitive.
*@see evas_3d_primitive_ratio_set()
*@return The ratio of primitive.
*@ingroup Evas_3D_Primitive
*/
}
values {
ratio: Evas_Real; /*@ Ratio of primitive.*/
}
}
@property precision {
set {
/*
*Set the precision of the given primitive.
*
*Precision uses in all non tabulated primitives and defines
*precision of created primitives.
*Avaliable values is from 3 to infinity.
*But if value will be more than 100, should be a warning
*about possibility of incorrect or slow work.
*
*Default ratio is 10
*
*@ingroup Evas_3D_Primitive
*/
}
get {
/*
*Get the precision of the given primitive.
*@see evas_3d_primitive_precision_set()
*@return The precision of primitive.
*@ingroup Evas_3D_Primitive
*/
}
values {
precision: int; /*@ Precision of primitive.*/
}
}
@property surface {
set {
/*
*Set the surface of the given primitive.
*
*Surface uses only in surface primitive and defines
*equation of filling mesh data on call of
*evas_3d_mesh_primitive_set.
*
*It gives possibility to create customers primitives like
*shell, heart, hyperbolic paraboloid etc. See _shell_func in
*examples/evas/evas-3d-visual-test.c or _perlin_terrain in
*modules/evas/primitives/surfaces/terrain.c as an example of usage.
*
*Default surface is NULL
*
*@ingroup Evas_3D_Primitive
*/
}
values {
surface: Evas_3D_Surface_Func *; /*@ Pointer to customers surface function.*/
}
}
@property tex_scale {
set {
/*
*Set the texture scale of the given primitive.
*
*Texture scale uses in all non tabulated primitives
*and defines scale of texture coords or primitives.
*
*It uses to create periodical textured meshes.
*
*Default tex_scale is {1.0, 1.0}
*
*@ingroup Evas_3D_Primitive
*/
}
get {
/*
*Get the texture scale of the given primitive.
*@see evas_3d_primitive_tex_scale_set()
*@ingroup Evas_3D_Primitive
*/
}
values {
tex_scale_x: Evas_Real;
tex_scale_y: Evas_Real;
}
}
}
implements {
Eo.Base.constructor;
Eo.Base.destructor;
}
}

View File

@ -0,0 +1,209 @@
#include "primitive_common.h"
void _set_vertex_data_from_array(Evas_3D_Mesh *mesh,
int frame,
const float *data,
Evas_3D_Vertex_Attrib attr,
int start,
int attr_count,
int line,
int vcount)
{
float *address, *out;
int stride, i, j;
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_copy_set(frame, attr, 0, NULL),
address = (float *)evas_3d_mesh_frame_vertex_data_map(frame, attr),
stride = evas_3d_mesh_frame_vertex_stride_get(frame, attr));
if (stride == 0) stride = sizeof(float) * attr_count;
for (i = 0; i < vcount; i++)
{
out = (float *)((char *)address + stride * i);
for (j = 0; j < attr_count; j++)
out[j] = data[start + (line * i) + j];
}
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(frame, attr));
}
void
_set_vec3_vertex_data(Evas_3D_Mesh *mesh,
int frame,
int vcount,
Evas_Vec3 *data,
Evas_3D_Vertex_Attrib attr)
{
float *address, *out;
int stride, i;
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_copy_set(frame, attr, 0, NULL),
address = (float *)evas_3d_mesh_frame_vertex_data_map(frame, attr),
stride = evas_3d_mesh_frame_vertex_stride_get(frame, attr));
if (stride == 0) stride = sizeof(float) * 3;
for (i = 0; i < vcount; i++)
{
out = (float *)((char *)address + stride * i);
out[0] = data[i].x;
out[1] = data[i].y;
out[2] = data[i].z;
}
free(data);
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(frame, attr));
}
void
_set_vec2_vertex_data(Evas_3D_Mesh *mesh,
int frame,
int vcount,
Evas_Vec2 *data,
Evas_3D_Vertex_Attrib attr)
{
float *address, *out;
int stride, i;
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_copy_set(frame, attr, 0, NULL),
address = (float *)evas_3d_mesh_frame_vertex_data_map(frame, attr),
stride = evas_3d_mesh_frame_vertex_stride_get(frame, attr));
if (stride == 0) stride = sizeof(float) * 2;
for (i = 0; i < vcount; i++)
{
out = (float *)((char *)address + stride * i);
out[0] = data[i].x;
out[1] = data[i].y;
}
free(data);
eo_do(mesh,
evas_3d_mesh_frame_vertex_data_unmap(frame, attr));
}
void
_generate_indices(unsigned short *indices, int a, int b)
{
int i, j, a1 = a + 1;
unsigned short *index = &indices[0];
for (i = 0; i < b; i++)
{
for (j = 0; j < a; j++)
{
*index++ = j + a1 * i;
*index++ = j + a1 * (i + 1);
*index++ = j + 1 + a1 * (i + 1);
*index++ = j + a1 * i;
*index++ = j + 1 + a1 * i;
*index++ = j + a1 * (i + 1) + 1;
}
}
}
void
_primitives_vec3_copy(Evas_Vec3 *dst, const Evas_Vec3 *src)
{
dst->x = src->x;
dst->y = src->y;
dst->z = src->z;
}
void
_primitives_vec3_subtract(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b)
{
out->x = a->x - b->x;
out->y = a->y - b->y;
out->z = a->z - b->z;
}
void
_primitives_vec3_cross_product(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b)
{
Evas_Vec3 tmp;
tmp.x = a->y * b->z - a->z * b->y;
tmp.y = a->z * b->x - a->x * b->z;
tmp.z = a->x * b->y - a->y * b->x;
_primitives_vec3_copy(out, &tmp);
}
void
_primitives_vec3_normalize(Evas_Vec3 *out)
{
Evas_Real size = out->x * out->x + out->y *out->y + out->z * out->z;
size = sqrt(size);
out->x /= size;
out->y /= size;
out->z /= size;
}
void
evas_common_set_model_from_primitive(Evas_3D_Mesh *model,
int frame,
Evas_3D_Primitive_Data *primitive)
{
Evas_Real ratio = primitive->ratio;
int precision = primitive->precision;
Evas_3D_Surface_Func *surface = primitive->surface;
Evas_Vec2 tex_scale = primitive->tex_scale;
Evas_3D_Primitive_Mode mode = primitive->mode;
switch (primitive->form)
{
case EVAS_3D_MESH_PRIMITIVE_NONE:
case EVAS_3D_MESH_PRIMITIVE_COUNT:
{
ERR("Primitive with this type cannot be set to mesh.");
break;
}
case EVAS_3D_MESH_PRIMITIVE_SQUARE:
{
evas_model_set_from_square_primitive(model, frame);
break;
}
case EVAS_3D_MESH_PRIMITIVE_CUBE:
{
evas_model_set_from_cube_primitive(model, frame);
break;
}
case EVAS_3D_MESH_PRIMITIVE_CYLINDER:
{
evas_model_set_from_cylinder_primitive(model, frame, mode,
precision, tex_scale);
break;
}
case EVAS_3D_MESH_PRIMITIVE_CONE:
{
evas_model_set_from_cone_primitive(model, frame, mode,
precision, tex_scale);
break;
}
case EVAS_3D_MESH_PRIMITIVE_SPHERE:
{
evas_model_set_from_sphere_primitive(model, frame, mode,
precision, tex_scale);
break;
}
case EVAS_3D_MESH_PRIMITIVE_TORUS:
{
evas_model_set_from_torus_primitive(model, frame,
ratio, precision, tex_scale);
break;
}
case EVAS_3D_MESH_PRIMITIVE_SURFACE:
{
evas_model_set_from_surface_primitive(model, frame,
surface, precision, tex_scale);
break;
}
case EVAS_3D_MESH_PRIMITIVE_TERRAIN:
{
evas_model_set_from_terrain_primitive(model, frame,
precision, tex_scale);
break;
}
default:
{
ERR("Unknown type of primitive");
}
}
}

View File

@ -0,0 +1,58 @@
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif //HAVE_CONFIG_H
#ifndef PRIMITIVE_COMMON
#define PRIMITIVE_COMMON
#include "evas_options.h"
#include "evas_common_private.h"
#include "evas_private.h"
#define ALLOCATE_VERTEX_DATA \
Evas_Vec3 *vertices = malloc(sizeof(Evas_Vec3) * vcount); \
Evas_Vec3 *normals = malloc(sizeof(Evas_Vec3) * vcount); \
Evas_Vec2 *tex_coord = malloc(sizeof(Evas_Vec2) * vcount); \
Evas_Vec3 *tangents = malloc(sizeof(Evas_Vec3) * vcount); \
unsigned short *indices = malloc(sizeof(short) * icount);
#define SET_VERTEX_DATA(frame) \
eo_do(mesh, \
evas_3d_mesh_vertex_count_set(vcount), \
evas_3d_mesh_frame_add(frame), \
evas_3d_mesh_index_data_copy_set(EVAS_3D_INDEX_FORMAT_UNSIGNED_SHORT, \
icount, &indices[0])); \
_set_vec3_vertex_data(mesh, frame, vcount, vertices, EVAS_3D_VERTEX_POSITION); \
_set_vec3_vertex_data(mesh, frame, vcount, normals, EVAS_3D_VERTEX_NORMAL); \
_set_vec2_vertex_data(mesh, frame, vcount, tex_coord, EVAS_3D_VERTEX_TEXCOORD); \
_set_vec3_vertex_data(mesh, frame, vcount, tangents, EVAS_3D_VERTEX_TANGENT); \
free(indices);
#define SET_VERTEX_DATA_FROM_ARRAY(mesh, frame, varray, vcount, indices, icount) \
eo_do(mesh, \
evas_3d_mesh_vertex_count_set(vcount), \
evas_3d_mesh_frame_add(frame), \
evas_3d_mesh_index_data_copy_set(EVAS_3D_INDEX_FORMAT_UNSIGNED_SHORT, \
icount, &indices[0])); \
_set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_POSITION, \
0, 3, 15, vcount); \
_set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_NORMAL, \
3, 3, 15, vcount); \
_set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_COLOR, \
6, 4, 15, vcount); \
_set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_TEXCOORD, \
10, 2, 15, vcount); \
_set_vertex_data_from_array(mesh, frame, varray, EVAS_3D_VERTEX_TANGENT, \
12, 3, 15, vcount);
void _generate_indices(unsigned short *indices, int count, int width);
void _set_vec3_vertex_data(Evas_3D_Mesh *mesh, int frame, int vcount, Evas_Vec3 *data, Evas_3D_Vertex_Attrib attr);
void _set_vec2_vertex_data(Evas_3D_Mesh *mesh, int frame, int vcount, Evas_Vec2 *data, Evas_3D_Vertex_Attrib attr);
void _set_vertex_data_from_array(Evas_3D_Mesh *mesh, int frame, const float *data, Evas_3D_Vertex_Attrib attr, int start, int attr_count, int line, int vcount);
void _primitives_vec3_copy(Evas_Vec3 *dst, const Evas_Vec3 *src);
void _primitives_vec3_subtract(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b);
void _primitives_vec3_cross_product(Evas_Vec3 *out, const Evas_Vec3 *a, const Evas_Vec3 *b);
void _primitives_vec3_normalize(Evas_Vec3 *out);
#endif //PRIMITIVE_COMMON

View File

@ -0,0 +1,140 @@
#include "../primitive_common.h"
void
_set_default_cone(Evas_3D_Mesh *mesh,
int frame,
int p,
Evas_Vec2 tex_scale)
{
int vcount, icount, vccount, i, j, num;
double dfi, fi, sinfi, cosfi, nplane, nz;
icount = p * 18;
vccount = p + 1;
vcount = 4 * vccount;
dfi = 2.0 * M_PI / p;
nz = sqrt(1.0 / 3.0);
nplane = sqrt(2.0 / 3.0);
ALLOCATE_VERTEX_DATA
for (i = 0; i < vccount; i++)
{
fi = i * dfi;
sinfi = sin(fi);
cosfi = cos(fi);
vertices[i].x = 0.0;
vertices[i].y = 0.0;
vertices[i].z = -0.5;
vertices[i + vccount].x = sinfi / 2.0;
vertices[i + vccount].y = cosfi / 2.0;
vertices[i + vccount].z = -0.5;
vertices[i + 2 * vccount] = vertices[i + vccount];
vertices[i + 3 * vccount].x = 0.0;
vertices[i + 3 * vccount].y = 0.0;
vertices[i + 3 * vccount].z = 0.5;
normals[i].x = normals[i].y = 0.0;
normals[i].z = -1.0;
normals[i + vccount] = normals[i];
normals[i + 2 * vccount].x = sinfi * nplane;
normals[i + 2 * vccount].y = cosfi * nplane;
normals[i + 2 * vccount].z = nz;
normals[i + 3 * vccount] = normals[i + 2 * vccount];
for (j = 0; j < 4; j++)
{
num = i + j * vccount;
tangents[num].x = cosfi;
tangents[num].y = -sinfi;
tangents[num].z = 0.0;
tex_coord[num].x = i / (float)(vccount - 1) * tex_scale.x;
tex_coord[num].y = (float)((j + 1) / 2) * tex_scale.y / 2.0;
}
}
_generate_indices(indices, p, 3);
SET_VERTEX_DATA(frame)
}
void
_set_cone_without_base(Evas_3D_Mesh *mesh,
int frame,
int p,
Evas_Vec2 tex_scale)
{
int vcount, icount, vccount, i;
double dfi, fi, sinfi, cosfi, nplane, nz;
icount = p * 6;
vccount = p + 1;
vcount = 2 * vccount;
dfi = 2.0 * M_PI / p;
nz = sqrt(1.0 / 3.0);
nplane = sqrt(2.0 / 3.0);
ALLOCATE_VERTEX_DATA
for (i = 0; i < vccount; i++)
{
fi = i * dfi;
sinfi = sin(fi);
cosfi = cos(fi);
vertices[i].x = sinfi / 2.0;
vertices[i].y = cosfi / 2.0;
vertices[i].z = -0.5;
vertices[i + vccount].x = 0;
vertices[i + vccount].y = 0;
vertices[i + vccount].z = 0.5;
normals[i + vccount].x = normals[i].x = sinfi * nplane;
normals[i + vccount].y = normals[i].y = cosfi * nplane;
normals[i + vccount].z = normals[i].z = nz;
tangents[i + vccount].x = tangents[i].x = cosfi;
tangents[i + vccount].y = tangents[i].y = -sinfi;
tangents[i + vccount].z = tangents[i].z = 0;
tex_coord[i].x = i / (float)(vccount - 1) * tex_scale.x;
tex_coord[i].y = 0;
tex_coord[i + vccount].x = tex_coord[i].x;
tex_coord[i + vccount].y = tex_scale.y;
}
_generate_indices(indices, p, 1);
SET_VERTEX_DATA(frame)
}
void
evas_model_set_from_cone_primitive(Evas_3D_Mesh *mesh,
int frame,
Evas_3D_Primitive_Mode mode,
int p,
Evas_Vec2 tex_scale)
{
switch (mode)
{
case EVAS_3D_PRIMITIVE_MODE_DEFAULT:
case EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV:
{
_set_default_cone(mesh, frame, p, tex_scale);
break;
}
case EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE:
{
_set_cone_without_base(mesh, frame, p, tex_scale);
break;
}
default:
{
ERR("Unknown mode of primitive");
}
}
}

View File

@ -0,0 +1,136 @@
#include "../primitive_common.h"
void
_set_default_cylinder(Evas_3D_Mesh *mesh,
int frame,
int p,
Evas_Vec2 tex_scale)
{
int vcount, icount, vccount, i, j, num;
icount = p * 30;
vccount = p + 1;
vcount = 6 * vccount;
ALLOCATE_VERTEX_DATA
double dfi, fi, sinfi, cosfi;
dfi = 2 * M_PI / p;
for (i = 0; i < vccount; i++)
{
fi = i * dfi;
sinfi = sin(fi);
cosfi = cos(fi);
for (j = 0; j < 6; j++)
{
num = i + j * vccount;
vertices[num].z = -0.5 + (float)(j / 3);
if ((j == 0) || (j == 5))
{
vertices[num].x = vertices[num].y = 0.0;
}
else
{
vertices[num].x = sinfi / 2.0;
vertices[num].y = cosfi / 2.0;
}
if ((j == 2) || (j == 3))
{
normals[num].x = sinfi;
normals[num].y = cosfi;
normals[num].z = 0.0;
}
else
{
normals[num].x = normals[num].y = 0.0;
normals[num].z = -1.0 + (float)(j / 2);
}
tangents[num].x = cosfi;
tangents[num].y = -sinfi;
tangents[num].z = 0.0;
tex_coord[num].x = i / (float)(vccount - 1) * tex_scale.x;
tex_coord[num].y = (float)((j + 1) / 2) * tex_scale.y / 3.0;
}
}
_generate_indices(indices, p, 5);
SET_VERTEX_DATA(frame)
}
void
_set_cylinder_without_bases(Evas_3D_Mesh *mesh,
int frame,
int p,
Evas_Vec2 tex_scale)
{
int vcount, icount, vccount, i;
icount = p * 6;
vccount = p + 1;
vcount = 2 * vccount;
ALLOCATE_VERTEX_DATA
double dfi, fi, sinfi, cosfi;
dfi = 2 * M_PI / p;
for (i = 0; i < vccount; i++)
{
fi = i * dfi;
sinfi = sin(fi);
cosfi = cos(fi);
vertices[i + vccount].x = vertices[i].x = sinfi / 2.0;
vertices[i + vccount].y = vertices[i].y = cosfi / 2.0;
vertices[i].z = -0.5;
vertices[i + vccount].z = 0.5;
normals[i + vccount].x = normals[i].x = sinfi;
normals[i + vccount].y = normals[i].y = cosfi;
normals[i + vccount].z = normals[i].z = 0;
tangents[i + vccount].x = tangents[i].x = cosfi;
tangents[i + vccount].y = tangents[i].y = -sinfi;
tangents[i + vccount].z = tangents[i].z = 0;
tex_coord[i].x = i / (float)(vccount - 1) * tex_scale.x;
tex_coord[i].y = 0;
tex_coord[i + vccount].x = i / (float)(vccount - 1) * tex_scale.x;
tex_coord[i + vccount].y = tex_scale.y;
}
_generate_indices(indices, p, 1);
SET_VERTEX_DATA(frame)
}
void
evas_model_set_from_cylinder_primitive(Evas_3D_Mesh *mesh,
int frame,
Evas_3D_Primitive_Mode mode,
int p,
Evas_Vec2 tex_scale)
{
switch (mode)
{
case EVAS_3D_PRIMITIVE_MODE_DEFAULT:
case EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV:
{
_set_default_cylinder(mesh, frame, p, tex_scale);
break;
}
case EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE:
{
_set_cylinder_without_bases(mesh, frame, p, tex_scale);
break;
}
default:
{
ERR("Unknown mode of primitive");
}
}
}

View File

@ -0,0 +1,189 @@
#include "../primitive_common.h"
void
_set_default_sphere(Evas_3D_Mesh *mesh,
int frame,
int p,
Evas_Vec2 tex_scale)
{
int vcount, icount, vccount, i, j;
icount = p * p * 6;
vccount = p + 1;
vcount = vccount * vccount;
ALLOCATE_VERTEX_DATA
double dtheta, dfi, sinth, costh, fi, theta, sinfi, cosfi;
dtheta = M_PI / p;
dfi = 2 * M_PI / p;
for (j = 0; j < vccount; j++)
{
theta = j * dtheta;
sinth = sin(theta);
costh = cos(theta);
for (i = 0; i < vccount; i++)
{
fi = i * dfi;
sinfi = sin(fi);
cosfi = cos(fi);
normals[i + j * vccount].x = sinth * sinfi;
normals[i + j * vccount].y = sinth * cosfi;
normals[i + j * vccount].z = costh;
vertices[i + j * vccount].x = normals[i + j * vccount].x / 2;
vertices[i + j * vccount].y = normals[i + j * vccount].y / 2;
vertices[i + j * vccount].z = normals[i + j * vccount].z / 2;
tangents[i + j * vccount].x = -sinth * cosfi;
tangents[i + j * vccount].y = sinth * sinfi;
tangents[i + j * vccount].z = 0;
_primitives_vec3_normalize(&tangents[i + j * vccount]);
tex_coord[i + j * vccount].x = i / (float)(vccount - 1) * tex_scale.x;
tex_coord[i + j *vccount].y = tex_scale.y - j / (float)(vccount - 1) * tex_scale.y;
}
}
_generate_indices(indices, p, p);
SET_VERTEX_DATA(frame)
}
void
_set_sphere_with_alternative_uv(Evas_3D_Mesh *mesh,
int frame,
int p,
Evas_Vec2 tex_scale)
{
int vcount, icount, vccount, i, j;
vccount = p + 1;
vcount = vccount * vccount;
icount = p * p * 6;
ALLOCATE_VERTEX_DATA
/* Calculate vertices position of the sphere mesh by using
splitting of sphere by latitude and longitude. */
for (i = 0; i <= p; i++)
{
double lati, z, r, point_r;
point_r = 0.00001;//non-zero little value for correct tangents calculation.
lati = ((M_PI - 2 * point_r) * (double)i) / (double)p;
z = cos(lati + point_r);
r = fabs(sin(lati + point_r));
for (j = 0; j <= p; j++)
{
double longi;
int num = (i * (p + 1)) + j;
longi = (M_PI * 2.0 * (double)j) / (double)p;
normals[num].x = r * sin(longi);
normals[num].y = r * cos(longi);
normals[num].z = z;
vertices[num].x = normals[num].x / 2;
vertices[num].y = normals[num].y / 2;
vertices[num].z = normals[num].z / 2;
if (vertices[num].x > 0.0)
{
tangents[num].x = -normals[num].z;
tangents[num].y = normals[num].y;
tangents[num].z = normals[num].x;
}
else
{
tangents[num].x = normals[num].z;
tangents[num].y = normals[num].y;
tangents[num].z = -normals[num].x;
}
tex_coord[num].x = i / (float)(vccount - 1) * tex_scale.x;
tex_coord[num].y = tex_scale.y - j / (float)(vccount - 1) * tex_scale.y;
}
}
_generate_indices(indices, p, p);
/* Triangulation of sphere mesh in appliance with buffer of indices. */
for (i = 0; i < icount; i += 3)
{
Evas_Vec3 e1, e2;
float du1, du2, dv1, dv2, f;
Evas_Vec3 tangent;
int num0, num1, num2;
num0 = indices[i + 0];
num1 = indices[i + 1];
num2 = indices[i + 2];
e1.x = vertices[num1].x - vertices[num0].x;
e1.y = vertices[num1].y - vertices[num0].y;
e1.z = vertices[num1].z - vertices[num0].z;
e2.x = vertices[num2].x - vertices[num0].x;
e2.y = vertices[num2].y - vertices[num0].y;
e2.z = vertices[num2].z - vertices[num0].z;
du1 = tex_coord[num1].x - tex_coord[num0].x;
dv1 = tex_coord[num1].y - tex_coord[num0].y;
du2 = tex_coord[num2].x - tex_coord[num0].x;
dv2 = tex_coord[num2].y - tex_coord[num0].y;
f = 1.0 / ((du1 * dv2) - (du2 * dv1));
tangent.x = f * ((dv2 * e1.x) - (dv1 * e2.x));
tangent.y = f * ((dv2 * e1.y) - (dv1 * e2.y));
tangent.z = f * ((dv2 * e1.z) - (dv1 * e2.z));
tangents[num0] = tangent;
}
/* Coupling between vertices by calculation of tangent parametr correct value. */
for (i = 0; i <= p; i++)
{
for (j = 0; j <= p; j++)
{
if (j == p)
{
tangents[(i * (p + 1)) + j] = tangents[i * (p + 1)];
}
}
}
SET_VERTEX_DATA(frame)
}
void
evas_model_set_from_sphere_primitive(Evas_3D_Mesh *mesh,
int frame,
Evas_3D_Primitive_Mode mode,
int p,
Evas_Vec2 tex_scale)
{
switch (mode)
{
case EVAS_3D_PRIMITIVE_MODE_DEFAULT:
case EVAS_3D_PRIMITIVE_MODE_WITHOUT_BASE:
{
_set_default_sphere(mesh, frame, p, tex_scale);
break;
}
case EVAS_3D_PRIMITIVE_MODE_ALTERNATIVE_UV:
{
_set_sphere_with_alternative_uv(mesh, frame, p, tex_scale);
break;
}
default:
{
ERR("Unknown mode of primitive");
}
}
}

View File

@ -0,0 +1,67 @@
#include "../primitive_common.h"
void
evas_model_set_from_torus_primitive(Evas_3D_Mesh *mesh,
int frame,
Evas_Real ratio,
int p,
Evas_Vec2 tex_scale)
{
int vcount, icount, vccount, i, j;
icount = p * p * 6;
vccount = p + 1;
vcount = vccount * vccount;
ALLOCATE_VERTEX_DATA
double d, sinth, costh, fi, theta, sinfi, cosfi;
d = 2 * M_PI / p;
float rratio;
if ((ratio < 1.0))
{
printf("Ratio of torus should be greater than or equal 1.0.\n");
printf("Ratio = %f is a bad value, so 3.0 is used like default ratio.\n",
ratio);
rratio = 1.0 / 3.0;
}
else
{
rratio = 1.0 / ratio;
}
for (j = 0; j < vccount; j++)
{
theta = j * d;
sinth = sin(theta);
costh = cos(theta);
for (i = 0; i < vccount; i++)
{
fi = i * d;
sinfi = sin(fi);
cosfi = cos(fi);
vertices[i + j * vccount].x = (1.0 - rratio + rratio * cosfi) * costh * 0.5;
vertices[i + j * vccount].y = (1.0 - rratio + rratio * cosfi) * sinth * 0.5;
vertices[i + j * vccount].z = rratio * sinfi * 0.5;
normals[i + j * vccount].x = cosfi * costh;
normals[i + j * vccount].y = cosfi * sinth;
normals[i + j * vccount].z = sinfi;
tangents[i + j * vccount].x = -sinfi * costh;
tangents[i + j * vccount].y = -sinfi * sinth;
tangents[i + j * vccount].z = cosfi;
_primitives_vec3_normalize(&normals[i + j * vccount]);
tex_coord[i + j * vccount].x = i / (float)(vccount - 1) * tex_scale.x;
tex_coord[i + j *vccount].y = tex_scale.y - j / (float)(vccount - 1) * tex_scale.y;
}
}
_generate_indices(indices, p, p);
SET_VERTEX_DATA(frame)
}

View File

@ -0,0 +1,91 @@
#include "../primitive_common.h"
Evas_Vec3 _get_func_normal(Evas_3D_Surface_Func *func, Evas_Real x, Evas_Real y)
{
Evas_Vec3 v00, v01, v10, d1, d2, normal;
func(&v00.x, &v00.y, &v00.z, x, y);
func(&v01.x, &v01.y, &v01.z, x, y + 0.01);
func(&v10.x, &v10.y, &v10.z, x + 0.01, y);
_primitives_vec3_subtract(&d1, &v00, &v01);
_primitives_vec3_subtract(&d2, &v01, &v10);
_primitives_vec3_cross_product(&normal, &d1, &d2);
_primitives_vec3_normalize(&normal);
return normal;
}
void
_normalize(Evas_Vec3 *vertices, Evas_Vec3 *normals, int vcount)
{
int i;
Evas_Vec3 min, max;
min = max = vertices[0];
#define CHECK_MIN_AND_MAX(coord) \
if (min.coord > vertices[i].coord) \
min.coord = vertices[i].coord; \
else if (max.coord < vertices[i].coord) \
max.coord = vertices[i].coord;
for (i = 1; i < vcount; i++)
{
CHECK_MIN_AND_MAX(x)
CHECK_MIN_AND_MAX(y)
CHECK_MIN_AND_MAX(z)
}
#undef CHECK_MIN_AND_MAX
for (i = 0; i < vcount; i++)
{
vertices[i].x = (vertices[i].x - min.x) / (max.x - min.x) - 0.5;
vertices[i].y = (vertices[i].y - min.y) / (max.y - min.y) - 0.5;
vertices[i].z = (vertices[i].z - min.z) / (max.z - min.z) - 0.5;
normals[i].x = normals[i].x / (max.x - min.x);
normals[i].y = normals[i].y / (max.y - min.y);
normals[i].z = normals[i].z / (max.z - min.z);
}
}
void
evas_model_set_from_surface_primitive(Evas_3D_Mesh *mesh,
int frame,
Evas_3D_Surface_Func func,
int p,
Evas_Vec2 tex_scale)
{
int vcount, icount, vccount, i, j, num;
icount = p * p * 6;
vccount = p + 1;
vcount = vccount * vccount;
ALLOCATE_VERTEX_DATA
Evas_Real v, u, d = 1.0 / p;
for (j = 0; j < vccount; j++)
{
u = j * d - 0.5;
for (i = 0; i < vccount; i++)
{
v = i * d - 0.5;
num = i + j * vccount;
func(&vertices[num].x,
&vertices[num].y,
&vertices[num].z,
v, u);
normals[num] = _get_func_normal(func, v, u);
tangents[num].x = tangents[num].y = tangents[num].z = 0;
tex_coord[num].x = i / ((vccount - 1) * tex_scale.x);
tex_coord[num].y = tex_scale.y - j / ((vccount - 1) * tex_scale.y);
}
}
_normalize(vertices, normals, vcount);
_generate_indices(indices, p, p);
SET_VERTEX_DATA(frame)
}

View File

@ -0,0 +1,86 @@
#include "../primitive_common.h"
static Evas_Real
_random(int x, int y)
{
int k = x + y * 57;
k = (k << 13) ^ k;
return (1.0f - ((k * (k * k * 15731 + 789221) + 1376312589) & 0x7fffffff) /
1073741824.0f);
}
static Evas_Real
_smooth(Evas_Real x, Evas_Real y)
{
Evas_Real res;
res = (_random(x - 1, y - 1) + _random(x + 1, y - 1) +
_random(x - 1, y + 1) + _random(x + 1, y + 1)) / 16;
res += (_random(x - 1, y) + _random(x + 1, y) +
_random(x, y - 1) + _random(x, y + 1)) / 8;
res += _random(x, y) / 4;
return res;
}
static Evas_Real
_interpolate(Evas_Real a, Evas_Real b, Evas_Real x)
{
Evas_Real ft = x * M_PI;
Evas_Real f = (1 - cosf(ft)) * 0.5;
return a * (1 - f) + b * f;
}
static Evas_Real _noise(Evas_Real x, Evas_Real y)
{
Evas_Real ix = (int)(x);
Evas_Real fx = x - ix;
Evas_Real iy = (int)(y);
Evas_Real fy = y - iy;
Evas_Real v1 = _smooth(ix, iy);
Evas_Real v2 = _smooth(ix + 1, iy);
Evas_Real v3 = _smooth(ix, iy + 1);
Evas_Real v4 = _smooth(ix + 1, iy + 1);
Evas_Real i1 = _interpolate(v1, v2, fx);
Evas_Real i2 = _interpolate(v3, v4, fx);
return _interpolate(i1, i2, fy);
}
static void
_perlin_terrain(Evas_Real *out_x,
Evas_Real *out_y,
Evas_Real *out_z,
Evas_Real x,
Evas_Real y)
{
Evas_Real persistence = 0.5f;
Evas_Real frequency = 5;
Evas_Real amplitude = 1;
int i = 0;
int octaves = 5;
*out_x = x;
x += 0.5;
*out_y = y;
y += 0.5;
*out_z = 0;
for(i = 0; i < octaves; i++)
{
*out_z += _noise(x * frequency, y * frequency) * amplitude;
amplitude *= persistence;
frequency *= 2;
}
}
void
evas_model_set_from_terrain_primitive(Evas_3D_Mesh *mesh,
int frame,
int p,
Evas_Vec2 tex_scale)
{
evas_model_set_from_surface_primitive(mesh, frame, _perlin_terrain, p, tex_scale);
}

View File

@ -0,0 +1,57 @@
#include "../primitive_common.h"
const float vertices_of_cube[] =
{
/* positions normals vertex_color tex_coords tangents */
/* Front */
0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
-0.5, -0.5, 0.5, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0,
-0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0,
0.5, -0.5, -0.5, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, -1.0, 0.0, 0.0,
/* Left */
-0.5, -0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, 1.0,
-0.5, 0.5, 0.5, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0,
-0.5, 0.5, -0.5, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 1.0,
-0.5, -0.5, -0.5, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0,
/* Back */
-0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.5, 0.5, 0.5, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
-0.5, 0.5, -0.5, 0.0, 1.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0,
/* Right */
0.5, 0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 1.0, 0.0, 0.0, -1.0,
0.5, -0.5, 0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, -1.0,
0.5, -0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0, 0.0, -1.0,
0.5, 0.5, -0.5, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 1.0, 1.0, 0.0, 0.0, -1.0,
/* Top */
-0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
-0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0,
0.5, 0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
0.5, -0.5, 0.5, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
/* Bottom */
-0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 0.0, -1.0, 0.0, 0.0,
-0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, -1.0, 0.0, 0.0,
0.5, 0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, -1.0, 0.0, 0.0,
0.5, -0.5, -0.5, 0.0, 0.0, -1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 0.0, -1.0, 0.0, 0.0,
};
const unsigned short indices_of_cube[] =
{
0, 1, 2, 6, 7, 4,
4, 5, 6, 10, 11, 8,
8, 9, 10, 14, 15, 12,
12, 13, 14, 2, 3, 0,
19, 16, 17, 17, 18, 19,
23, 20, 21, 21, 22, 23
};
void
evas_model_set_from_cube_primitive(Evas_3D_Mesh *mesh, int frame)
{
SET_VERTEX_DATA_FROM_ARRAY(mesh, frame, vertices_of_cube, 24, indices_of_cube, 36)
}

View File

@ -0,0 +1,18 @@
#include "../primitive_common.h"
const float vertices_of_square[] =
{
/* positions normals vertex_color tex_coords tangents */
-0.5, 0.5, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 1.0, 1.0, 0.0, 0.0,
0.5, 0.5, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, 0.0,
-0.5, -0.5, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0,
0.5, -0.5, 0.0, 0.0, 0.0, -1.0, 1.0, 0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0,
};
const unsigned short indices_of_square[] = {0, 1, 2, 2, 1, 3};
void
evas_model_set_from_square_primitive(Evas_3D_Mesh *mesh, int frame)
{
SET_VERTEX_DATA_FROM_ARRAY(mesh, frame, vertices_of_square, 4, indices_of_square, 6)
}

View File

@ -100,6 +100,7 @@ typedef struct _Evas_3D_Camera Evas_3D_Camera_Data;
typedef struct _Evas_3D_Light Evas_3D_Light_Data;
typedef struct _Evas_3D_Material Evas_3D_Material_Data;
typedef struct _Evas_3D_Texture Evas_3D_Texture_Data;
typedef struct _Evas_3D_Primitive Evas_3D_Primitive_Data;
/* Structs for mesh eet saver/loader */
typedef struct _Evas_3D_Vec2_Eet Evas_3D_Vec2_Eet;
@ -415,6 +416,17 @@ struct _Evas_3D_Material
Eina_Hash *meshes;
};
struct _Evas_3D_Primitive
{
Evas_3D_Mesh_Primitive form;
Evas_3D_Primitive_Mode mode;
Evas_Real ratio;
int precision;
Evas_3D_Surface_Func *surface;
Evas_Vec2 tex_scale;
};
struct _Evas_3D_Scene_Public_Data
{
Evas_Color bg_color;
@ -1746,6 +1758,17 @@ void evas_model_save_file_eet(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh
void evas_model_save_file_obj(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f);
void evas_model_save_file_ply(Evas_3D_Mesh *mesh, const char *file, Evas_3D_Mesh_Frame *f);
/* Primitives functions */
void evas_common_set_model_from_primitive(Evas_3D_Mesh *model, int frame, Evas_3D_Primitive_Data *primitive);
void evas_model_set_from_square_primitive(Evas_3D_Mesh *mesh, int frame);
void evas_model_set_from_cube_primitive(Evas_3D_Mesh *mesh, int frame);
void evas_model_set_from_cylinder_primitive(Evas_3D_Mesh *mesh, int frame, Evas_3D_Primitive_Mode mode, int precision, Evas_Vec2 tex_scale);
void evas_model_set_from_cone_primitive(Evas_3D_Mesh *mesh, int frame, Evas_3D_Primitive_Mode mode, int precision, Evas_Vec2 tex_scale);
void evas_model_set_from_sphere_primitive(Evas_3D_Mesh *mesh, int frame, Evas_3D_Primitive_Mode mode, int precision, Evas_Vec2 tex_scale);
void evas_model_set_from_torus_primitive(Evas_3D_Mesh *mesh, int frame, Evas_Real ratio, int precision, Evas_Vec2 tex_scale);
void evas_model_set_from_surface_primitive(Evas_3D_Mesh *mesh, int frame, Evas_3D_Surface_Func func, int precision, Evas_Vec2 tex_scale);
void evas_model_set_from_terrain_primitive(Evas_3D_Mesh *mesh, int frame, int precision, Evas_Vec2 tex_scale);
extern int _evas_alloc_error;
extern int _evas_event_counter;