3D Model
The widget supports loading 3D models composed of .obj
and .mtl
files, and supports adding animation effects.
GUI Load 3D Model
Components of a 3D model
.obj
file: Stores the geometric data of the 3D model, including vertices, normals, texture coordinates, faces, etc..mtl
file: Describes the material properties of the 3D model, including color, glossiness, transparency, and texture mapping.Image files: Textures used in the model.
Example of 3D Model Components
Parsing the 3D model and generating a 3D information descriptor
Invoke a script to process the
.obj
file.
Script Processing
Generate a 3D information descriptor, which includes parsed OBJ data, parsed MTL data, and texture maps.
Generating Binary Arrays
GUI load descriptor
Place the desc file containing parsed obj data, mtl data, and image data into the project directory, and load it using
gui_3d_create()
.Example:
void *test_3d = gui_3d_create(gui_obj_get_root(), "3d-widget", (void *)_acdesc, 0, 0, 480, 480);
3D Widget Usage
Create Widget
Use gui_3d_create()
to create the 3D model. The imported desc_addr
file is the parsed data extracted by the script.
Global Shape Transformation
Use gui_3d_set_global_shape_transform_cb()
to apply a global transformation to the 3D model, where cb
sets the same shape transformation for all faces of the object. In this function, world
and camera
represent the world coordinate transformation of the 3D object and the camera view projection, respectively.
Additionally, rectangular faces support the setting of light
information.
Local Shape Transformation
Use gui_3d_set_local_shape_transform_cb()
to apply a local transformation to the 3D model, where cb
allows setting different shape transformations for each face of the object, and face_index
specifies the face to be transformed. In this function, world
and camera
represent the world coordinate transformation of the 3D object and the camera view projection, respectively.
Additionally, rectangular faces support the setting of light
information.
World Transformation
The initialization function is gui_3d_world_inititalize(gui_3d_matrix_t *world, float x, float y, float z, float rotX, float rotY, float rotZ, float scale)
.
world
: A pointer to the world transformation matrix, it transforms the 3D object from model coordinates to world coordinates.x
: The distance of translation along the X-axis, used to determine the object’s position in the X direction within the world coordinate system.y
: The distance of translation along the Y-axis, used to determine the object’s position in the Y direction within the world coordinate system.z
: The distance of translation along the Z-axis, used to determine the object’s position in the Z direction within the world coordinate system.rotX
: The angle of rotation around the X-axis (in degrees).rotY
: The angle of rotation around the Y-axis (in degrees).rotZ
: The angle of rotation around the Z-axis (in degrees).scale
: A uniform scaling factor used to proportionally scale the object in all directions.
Purpose:
The world transformation matrix typically handles transforming the model coordinate system to the world coordinate system. For example, if an object is located at the origin of the model coordinate system, it can be moved to any position in the scene and scaled/rotated through world transformation.
Performing independent world transformations for each face can achieve localized animations or static displays.
Different faces can share the same world matrix, or you can use
gui_3d_calculator_matrix(gui_3d_matrix_t *matrix, float x, float y, float z, gui_point_4d_t point, gui_vector_4d_t vector, float degrees, float scale)
to generate different matrices for each face to achieve personalized local transformations.
Camera Transformation
The initialization function is gui_3d_camera_UVN_initialize(gui_3d_camera_t *camera, gui_point_4d_t cameraPosition, gui_point_4d_t cameraTarget, float near, float far, float fov, float viewPortWidth, float viewPortHeight)
.
camera
: A pointer to the camera structure, used to initialize camera properties.cameraPosition
: The position of the camera in world coordinates.cameraTarget
: The target point the camera is directed at, i.e., the focal point of the camera’s line of sight.near
: The near clipping plane distance, defining the distance from the camera to the near plane of the camera’s view frustum. Objects closer than this distance will be clipped.far
: The far clipping plane distance, defining the distance from the camera to the far plane of the view frustum. Objects farther than this distance will be clipped.fov
: The field of view, usually expressed as a vertical angle (in degrees), defining the openness of the camera, i.e., the opening angle of the camera’s view frustum.viewPortWidth
: The width of the viewport, defining the horizontal size of the rendering target or window.viewPortHeight
: The height of the viewport, defining the vertical size of the rendering target or window.
Purpose:
Camera transformation defines the observer’s position and direction in the scene, transforming the world coordinate system to the camera coordinate system.
By manipulating the camera, different perspectives can be achieved, such as translating the camera position or changing the viewing direction.
Lighting Information
The initialization function is gui_3d_light_inititalize(gui_3d_light_t *light, gui_point_4d_t lightPosition, gui_point_4d_t lightTarget, float included_angle, float blend_ratio, gui_3d_RGBAcolor_t color)
.
light
: A pointer to the light source structure, used to initialize the properties of the light source.lightPosition
: The position of the light source in world coordinates.lightTarget
: The target position of the light source, defining the direction of illumination.included_angle
: The cone angle of the light (in degrees), represented as angle \(\alpha\) in the diagram. It determines the illumination range of the spotlight, which corresponds to the outer circle of the spotlight in the diagram.blend_ratio
: The ratio of the light blending region, defining the softness of the spotlight’s edge. It ranges from 0 to 1 and determines angle \(\beta\) in the diagram. The value is calculated using the following formula:\[β = α (1 - ratio)\]The blending region extends from the inner circle to the outer circle of the spotlight. Within the inner circle, the light intensity is constant, while it gradually diminishes from the inner to the outer circle.
color
: The color of the light source and its transparency.

Example of Spotlight Effect
Purpose:
The light source type is a spotlight, and its properties include initial position, light direction, cone angle, blend ratio, and light color.
Adjusting lighting locally for each face or object can create different visual styles.
Set Animation
The gui_obj_create_timer()
function can be used to set animation properties for a 3D object. The callback
parameter is a callback function for animation updates.
Example
3D Butterfly
The model is composed entirely of rectangular faces. By calling gui_3d_set_local_shape_transform_cb()
, you can set local transformations for different faces to create animation effects.
#include "guidef.h"
#include "gui_img.h"
#include "gui_obj.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "gui_server.h"
#include "gui_components_init.h"
#include "gui_canvas.h"
#include "gui_3d.h"
#include "butterfly/desc.txt"
#include "math.h"
#include "tp_algo.h"
static int frame_counter = 0;
static float wing_angle = 0.0f;
static float butterfly_x = 0.0f;
static float butterfly_y = 0.0f;
static float butterfly_z = 0.0f;
static float butterfly_rz = 0.0f;
bool is_moving_to_target = false;
static float target_dx = 0.0f;
static float target_dy = 0.0f;
static float source_dx = 0.0f;
static float source_dy = 0.0f;
static float move_speed = 0.02f;
static float wing_time = 0.0f;
void update_animation()
{
touch_info_t *tp = tp_get_info();
gui_dispdev_t *dc = gui_get_dc();
if (tp->pressed)
{
target_dx = (tp->x - dc->screen_width / 2) / 2.5f;
target_dy = (tp->y - dc->screen_height / 2) / 2.5f;
is_moving_to_target = true;
}
if (is_moving_to_target)
{
float dx = target_dx - source_dx;
float dy = target_dy - source_dy;
float distance = sqrtf(dx * dx + dy * dy);
if (distance > 10.0f)
{
// Acceleration and deceleration
float speed_factor = fminf(distance / 40.0f, 1.0f);
source_dx += dx * move_speed * speed_factor;
source_dy += dy * move_speed * speed_factor;
// Caculate new rotate angle
float desired_angle = atan2f(dy, dx) * (180.0f / M_PI) + 90;
float angle_difference = desired_angle - butterfly_rz;
if (angle_difference > 180.0f)
{
angle_difference -= 360.0f;
}
if (angle_difference < -180.0f)
{
angle_difference += 360.0f;
}
butterfly_rz += angle_difference * 0.1f;
// Adjust wing flapping frequency based on speed
wing_time += 0.2f + speed_factor * 0.2f;
wing_angle = 60.0f * sinf(wing_time);
butterfly_x = -source_dx;
butterfly_y = -source_dy;
}
else
{
is_moving_to_target = false;
}
}
else
{
frame_counter++;
wing_time += 0.1f;
wing_angle = 50.0f * sinf(wing_time);
butterfly_z = 5.0f * sinf(frame_counter * 0.05f);
}
}
static void cb(void *this, size_t face_index/*face offset*/, gui_3d_world_t *world,
gui_3d_camera_t *camera, gui_3d_light_t *light)
{
gui_dispdev_t *dc = gui_get_dc();
gui_3d_matrix_t face_matrix;
gui_3d_matrix_t object_matrix;
gui_3d_camera_UVN_initialize(camera, gui_point_4d(0, 0, 80), gui_point_4d(0, 0, 0), 1, 32767, 90,
dc->screen_width, dc->screen_height);
gui_3d_world_inititalize(&object_matrix, butterfly_x, butterfly_y, butterfly_z, 0, 0,
butterfly_rz,
5);
if (face_index == 0)
{
gui_3d_calculator_matrix(&face_matrix, 0, 0, 0, gui_3d_point(0, 0, 0), gui_3d_vector(0, 1, 0),
wing_angle, 1);
}
else if (face_index == 1)
{
gui_3d_calculator_matrix(&face_matrix, 0, 0, 0, gui_3d_point(0, 0, 0), gui_3d_vector(0, 1, 0),
-wing_angle, 1);
}
else if (face_index == 2)
{
gui_3d_calculator_matrix(&face_matrix, 0, 0, 0, gui_3d_point(0, 0, 0), gui_3d_vector(0, 1, 0),
wing_angle, 1);
}
else if (face_index == 3)
{
gui_3d_calculator_matrix(&face_matrix, 0, 0, 0, gui_3d_point(0, 0, 0), gui_3d_vector(0, 1, 0),
-wing_angle, 1);
}
else
{
gui_3d_calculator_matrix(&face_matrix, 0, 0, 0, gui_3d_point(0, 0, 0), gui_3d_vector(0, 1, 0), 0,
1);
}
*world = gui_3d_matrix_multiply(face_matrix, object_matrix);
}
static int app_init(void)
{
void *test_3d = gui_3d_create(gui_obj_get_root(), "3d-widget", (void *)_acdesc, 0, 0, 480, 480);
gui_3d_set_local_shape_transform_cb(test_3d, 0, (gui_3d_shape_transform_cb)cb);
gui_obj_create_timer(&(((gui_3d_base_t *)test_3d)->base), 17, true, update_animation);
gui_obj_start_timer(&(((gui_3d_base_t *)test_3d)->base));
return 0;
}

3D Prism
The model is composed entirely of rectangular faces. By calling gui_3d_light_inititalize()
, you can add lighting effects.
#include "math.h"
#include "cube3D/desc.txt"
static float rot_angle = 0.0f;
void update_cube_animation()
{
rot_angle++;
}
static void cube_cb(gui_3d_t *this, size_t face/*face offset*/, gui_3d_world_t *world,
gui_3d_camera_t *camera, gui_3d_light_t *light)
{
gui_dispdev_t *dc = gui_get_dc();
gui_3d_matrix_t face_matrix;
gui_3d_matrix_t object_matrix;
gui_3d_camera_UVN_initialize(camera, gui_point_4d(0, 6, 15), gui_point_4d(0, 0, 0), 1, 32767, 90,
dc->screen_width, dc->screen_height);
gui_3d_world_inititalize(&object_matrix, 0, 22, 40, 90, 0, 0,
10);
gui_3d_light_inititalize(light, gui_point_4d(0, 22, 45), gui_point_4d(0, 22, 40), 60, 0.6, (gui_3d_RGBAcolor_t){255, 215, 0, 255});
gui_3d_calculator_matrix(&face_matrix, 0, 0, 0, gui_3d_point(0, 0, 0), gui_3d_vector(0, 0, 1), rot_angle,
1);
*world = gui_3d_matrix_multiply(face_matrix, object_matrix);
}
static int app_init(void)
{
void *test_3d = gui_3d_create(gui_obj_get_root(), "3d-widget", (void *)_acdesc, 0, 0, 480, 480);
gui_3d_set_global_shape_transform_cb(test_3d, (gui_3d_shape_transform_cb)cube_cb);
gui_obj_create_timer(&(((gui_3d_base_t *)test_3d)->base), 17, true, update_cube_animation);
gui_obj_start_timer(&(((gui_3d_base_t *)test_3d)->base));
return 0;
}

3D Face
The model is composed of 1,454 triangular faces.
#include "guidef.h"
#include "gui_img.h"
#include "gui_obj.h"
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include "gui_server.h"
#include "gui_components_init.h"
#include "gui_3d.h"
#include "tp_algo.h"
#include "face3d/desc_1454.txt"
#include "face3d/desc_5822.txt"
static float rot_angle = 0.0f;
void update_face_animation()
{
touch_info_t *tp = tp_get_info();
if (tp->pressed || tp->pressing)
{
rot_angle += tp->deltaX / 5.0f;
}
}
static void face_cb(void *this, gui_3d_world_t *world,
gui_3d_camera_t *camera)
{
gui_dispdev_t *dc = gui_get_dc();
gui_3d_matrix_t face_matrix;
gui_3d_matrix_t object_matrix;
gui_3d_camera_UVN_initialize(camera, gui_point_4d(0, 3, 60), gui_point_4d(0, 0, 0), 1, 32767, 90,
dc->screen_width, dc->screen_height);
// gui_3d_world_inititalize(&object_matrix, 0, 25, 120, 0, 0, 0,
// 5);
// gui_3d_calculator_matrix(&face_matrix, 0, 0, 0, gui_3d_point(0, 0, 0), gui_3d_vector(0, 1, 0),
// rot_angle,
// 1);
// *world = gui_3d_matrix_multiply(face_matrix, object_matrix);
gui_3d_world_inititalize(world, 0, 25, 120, 0, rot_angle, 0, 5);
}
static int app_init(void)
{
void *test_3d = gui_3d_create(gui_obj_get_root(), "3d-widget", (void *)_acdesc_1454, 0, 0, 480,
480);
gui_3d_set_global_shape_transform_cb(test_3d, (gui_3d_shape_transform_cb)face_cb);
// extern void gui_fps_create(void *parent);
// gui_fps_create(&(app->screen));
gui_obj_create_timer(&(((gui_3d_base_t *)test_3d)->base), 17, true, update_face_animation);
gui_obj_start_timer(&(((gui_3d_base_t *)test_3d)->base));
return 0;
}

API
Typedefs
-
typedef void (*gui_3d_shape_transform_cb)(void *this, gui_3d_world_t *world, gui_3d_camera_t *camera, void *extra)
Functions
-
void *gui_3d_create(void *parent, const char *name, void *desc_addr, int16_t x, int16_t y, int16_t w, int16_t h)
3d widget create
- Parameters:
parent – parent widget
name – widget name
desc_addr – description file data
x – the X-axis coordinate relative to parent widget
y – the Y-axis coordinate relative to parent widget
w – width
h – height
- Returns:
the widget object pointer
-
void gui_3d_set_global_shape_transform_cb(void *this, gui_3d_shape_transform_cb cb)
set global shape transform callback
- Parameters:
this – the 3d widget pointer
cb – Set callback functions for the world coordinate system, camera coordinate system, and light source for all faces
-
void gui_3d_set_local_shape_transform_cb(void *this, size_t face, gui_3d_shape_transform_cb cb)
set local shape transform callback
- Parameters:
this – the 3d widget pointer
face – face offset
cb – Set callback functions for the world coordinate system, camera coordinate system, and light source for the specified face
-
void gui_3d_on_click(void *this, void *callback, void *parameter)
Set a callback function for when the 3D widget is clicked.
- Parameters:
this – Pointer to the 3D widget.
callback – Callback function to execute on click.
parameter – Additional parameter for the callback.
-
struct gui_3d_base_t