/
Zamar_Terrier
/
TEngineEditor
Обзор
Документация
Войти
/
Zamar_Terrier
/
TEngineEditor
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
src/object.c
322 строки
12 KB
Zamar_Terrier
checkpoint
23 июл 2026, 18:41
23 июл 2026, 18:41
10276a6
Код
Авторство
О чём код?
#include "object.h" #include <stdlib.h> #include <string.h> // Создание нового объекта SceneObject* SceneObjectCreate(const char* name, ObjectType type) { SceneObject* object = (SceneObject*)malloc(sizeof(SceneObject)); if (!object) return NULL; memset(object, 0, sizeof(SceneObject)); if (name) { strncpy(object->name, name, 63); object->name[63] = '\0'; } object->type = type; object->transform.position = vec3_f(0, 0, 0); object->transform.rotation = vec3_f(0, 0, 0); object->transform.scale = vec3_f(1, 1, 1); object->render_object.primitive = NULL; object->primitiveParams = NULL; object->next = NULL; object->prev = NULL; // Выделение памяти для параметров примитива для примитивных объектов if (type == OBJECT_TYPE_3D_CUBE || type == OBJECT_TYPE_3D_SPHERE || type == OBJECT_TYPE_3D_CYLINDER || type == OBJECT_TYPE_3D_CONE || type == OBJECT_TYPE_3D_CAPSULE) { object->primitiveParams = (PrimitiveParams*)malloc(sizeof(PrimitiveParams)); if (object->primitiveParams) { // Инициализация значениями по умолчанию switch (type) { case OBJECT_TYPE_3D_CUBE: object->primitiveParams->cube.width = 1.0f; object->primitiveParams->cube.height = 1.0f; object->primitiveParams->cube.depth = 1.0f; break; case OBJECT_TYPE_3D_SPHERE: object->primitiveParams->sphere.radius = 1.0f; object->primitiveParams->sphere.segmentsWidth = 16; object->primitiveParams->sphere.segmentsHeight = 16; break; case OBJECT_TYPE_3D_CYLINDER: object->primitiveParams->cylinder.radiusBottom = 1.0f; object->primitiveParams->cylinder.radiusTop = 1.0f; object->primitiveParams->cylinder.height = 2.0f; object->primitiveParams->cylinder.segmentsRadial = 16; object->primitiveParams->cylinder.segmentsHeight = 1; break; case OBJECT_TYPE_3D_CONE: object->primitiveParams->cone.radiusBottom = 1.0f; object->primitiveParams->cone.radiusTop = 0.0f; object->primitiveParams->cone.height = 2.0f; object->primitiveParams->cone.segments = 16; break; case OBJECT_TYPE_3D_CAPSULE: object->primitiveParams->capsule.radius = 0.5f; object->primitiveParams->capsule.cylinderHeight = 1.0f; object->primitiveParams->capsule.segmentsRadial = 16; object->primitiveParams->capsule.segmentsHeight = 16; break; default: break; } } } return object; } // Уничтожение объекта void SceneObjectDestroy(SceneObject* object) { if (!object) return; // Очистка ресурсов движка в зависимости от типа if (object->type == OBJECT_TYPE_2D_QUAD && object->render_object.shape) { GameObjectDestroy((GameObject*)object->render_object.shape); free(object->render_object.shape); } else if (object->type != OBJECT_TYPE_2D_QUAD && object->render_object.primitive) { GameObjectDestroy((GameObject*)object->render_object.primitive); free(object->render_object.primitive); } // Очистка параметров примитива if (object->primitiveParams) { free(object->primitiveParams); object->primitiveParams = NULL; } free(object); } // Обновление трансформации объекта void SceneObjectUpdateTransform(SceneObject* object, Transform* transform) { if (!object || !transform) return; object->transform.position = transform->position; object->transform.rotation = transform->rotation; object->transform.scale = transform->scale; // Обновление в движке if (object->type == OBJECT_TYPE_2D_QUAD && object->render_object.shape) { Transform2DSetPosition((GameObject2D*)object->render_object.shape, transform->position.x, transform->position.y); Transform2DSetScale((GameObject2D*)object->render_object.shape, transform->scale.x, transform->scale.y); } else if (object->type != OBJECT_TYPE_2D_QUAD && object->render_object.primitive) { Transform3DSetPosition((GameObject3D*)object->render_object.primitive, transform->position.x, transform->position.y, transform->position.z); Transform3DSetRotation((GameObject3D*)object->render_object.primitive, transform->rotation.x, transform->rotation.y, transform->rotation.z); Transform3DSetScale((GameObject3D*)object->render_object.primitive, transform->scale.x, transform->scale.y, transform->scale.z); } } // Получение трансформации объекта Transform* SceneObjectGetTransform(SceneObject* object) { if (!object) return NULL; return &object->transform; } // Установка имени объекта void SceneObjectSetName(SceneObject* object, const char* name) { if (!object || !name) return; strncpy(object->name, name, 63); object->name[63] = '\0'; } // Получение имени объекта const char* SceneObjectGetName(SceneObject* object) { if (!object) return NULL; return object->name; } // Инициализация сцены void SObjSceneInit(Scene* scene) { if (!scene) return; scene->first_object = NULL; scene->selected_object = NULL; scene->object_count = 0; strcpy(scene->name, "UnnamedScene"); } // Очистка сцены void SObjSceneCleanUp(Scene* scene) { if (!scene) return; SceneObject* current = scene->first_object; while (current) { SceneObject* next = current->next; SceneObjectDestroy(current); current = next; } scene->first_object = NULL; scene->selected_object = NULL; scene->object_count = 0; } // Добавление объекта в сцену SceneObject* SObjSceneAddObject(Scene* scene, const char* name, ObjectType type) { if (!scene) return NULL; SceneObject* object = SceneObjectCreate(name, type); if (!object) return NULL; // Добавление в начало списка object->next = scene->first_object; if (scene->first_object) { scene->first_object->prev = object; } object->prev = NULL; scene->first_object = object; scene->object_count++; return object; } // Удаление объекта из сцены void SObjSceneRemoveObject(Scene* scene, SceneObject* object) { if (!scene || !object) return; // Обновление связей списка if (object->prev) { object->prev->next = object->next; } else { scene->first_object = object->next; } if (object->next) { object->next->prev = object->prev; } // Если удаленный объект был выбран, сброс выделения if (scene->selected_object == object) { scene->selected_object = NULL; } SceneObjectDestroy(object); scene->object_count--; } // Получение выбранного объекта SceneObject* SObjSceneGetSelectedObject(Scene* scene) { if (!scene) return NULL; return scene->selected_object; } // Выделение объекта void SObjSceneSelectObject(Scene* scene, SceneObject* object) { if (!scene) return; scene->selected_object = object; } // Обновление сцены void SObjSceneUpdate(Scene* scene, float dTime) { // Для будущей реализации (анимация и т.д.) } // Отрисовка сцены void SObjSceneDraw(Scene* scene) { if (!scene) return; SceneObject* current = scene->first_object; while (current) { if (current->type == OBJECT_TYPE_2D_QUAD && current->render_object.shape) { GameObjectDraw((GameObject*)current->render_object.shape); } else if (current->type != OBJECT_TYPE_2D_QUAD && current->render_object.primitive) { GameObjectDraw((GameObject*)current->render_object.primitive); } current = current->next; } } // Функции для работы с параметрами примитивов // Установка параметров примитива void SceneObjectSetPrimitiveParams(SceneObject* object, const PrimitiveParams* params) { if (!object || !params) return; // Выделение памяти для параметров if (!object->primitiveParams) { object->primitiveParams = (PrimitiveParams*)malloc(sizeof(PrimitiveParams)); if (!object->primitiveParams) return; } memcpy(object->primitiveParams, params, sizeof(PrimitiveParams)); // Обновление параметров в движке SceneObjectUpdatePrimitiveParams(object); } // Получение параметров примитива const PrimitiveParams* SceneObjectGetPrimitiveParams(SceneObject* object) { if (!object) return NULL; return object->primitiveParams; } // Обновление параметров примитива в движке // Обновление параметров примитива в движке void SceneObjectUpdatePrimitiveParams(SceneObject* object) { if (!object || !object->primitiveParams) return; // Вычисляем новый масштаб в зависимости от типа vec3 new_scale = vec3_f(1.0f, 1.0f, 1.0f); switch (object->type) { case OBJECT_TYPE_3D_CUBE: { new_scale.x = object->primitiveParams->cube.width; new_scale.y = object->primitiveParams->cube.height; new_scale.z = object->primitiveParams->cube.depth; break; } case OBJECT_TYPE_3D_SPHERE: { float r = object->primitiveParams->sphere.radius; new_scale.x = r; new_scale.y = r; new_scale.z = r; break; } case OBJECT_TYPE_3D_CYLINDER: { // Используем радиус основания для X и Z, высоту для Y new_scale.x = object->primitiveParams->cylinder.radiusBottom; new_scale.y = object->primitiveParams->cylinder.height; new_scale.z = object->primitiveParams->cylinder.radiusBottom; break; } case OBJECT_TYPE_3D_CONE: { new_scale.x = object->primitiveParams->cone.radiusBottom; new_scale.y = object->primitiveParams->cone.height; new_scale.z = object->primitiveParams->cone.radiusBottom; break; } case OBJECT_TYPE_3D_CAPSULE: { float r = object->primitiveParams->capsule.radius; float h = object->primitiveParams->capsule.cylinderHeight; new_scale.x = r; new_scale.y = h + 2.0f * r; // общая высота = высота цилиндра + 2*радиус полусфер new_scale.z = r; break; } default: // Для 2D-объектов и других типов ничего не делаем return; } // Сохраняем новый масштаб в трансформации объекта object->transform.scale = new_scale; // Применяем масштаб к объекту движка if (object->type == OBJECT_TYPE_2D_QUAD && object->render_object.shape) { Transform2DSetScale((GameObject2D*)object->render_object.shape, new_scale.x, new_scale.y); } else if (object->type != OBJECT_TYPE_2D_QUAD && object->render_object.primitive) { Transform3DSetScale((GameObject3D*)object->render_object.primitive, new_scale.x, new_scale.y, new_scale.z); } }