summaryrefslogtreecommitdiff
path: root/gfx/src/scene/object.c
blob: 406c81fb7036310236b81f645fbada66422a3dcf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#include "object_impl.h"

#include <gfx/render_backend.h>

#include "mesh_impl.h"
#include "node_impl.h"
#include "scene_memory.h"

#include <assert.h>

static aabb3 calc_object_aabb(const SceneObject* object) {
  assert(object);

  bool  first = true;
  aabb3 box;

  mesh_link_idx ml = object->mesh_link;
  while (ml.val) {
    const MeshLink* mesh_link = mem_get_mesh_link(ml);
    const mesh_idx  mi        = mesh_link->mesh;
    if (mi.val) {
      const Mesh* mesh     = mem_get_mesh(mi);
      const aabb3 mesh_box = gfx_get_geometry_aabb(mesh->geometry);
      if (first) {
        box   = mesh_box;
        first = false;
      } else {
        box = aabb3_sum(box, mesh_box);
      }
    }
    ml = mesh_link->next;
  }

  return box;
}

static void add_object_mesh(SceneObject* object, Mesh* mesh) {
  assert(object);
  assert(mesh);

  MeshLink* link    = mem_alloc_mesh_link();
  link->mesh        = mem_get_mesh_index(mesh);
  link->next        = object->mesh_link;
  object->mesh_link = mem_get_mesh_link_index(link);
}

SceneObject* gfx_make_object(const ObjectDesc* desc) {
  assert(desc);

  SceneObject* object = mem_alloc_object();
  for (size_t i = 0; i < desc->num_meshes; ++i) {
    add_object_mesh(object, desc->meshes[i]);
  }
  object->box = calc_object_aabb(object);
  return object;
}

void gfx_destroy_object(SceneObject** object) {
  assert(object);

  if (*object) {
    if ((*object)->parent.val) {
      gfx_del_node((*object)->parent);
    }
    mem_free_object(object);
  }
}

void gfx_set_object_skeleton(SceneObject* object, const Skeleton* skeleton) {
  assert(object);
  assert(skeleton);
  object->skeleton = mem_get_skeleton_index(skeleton);
}

const Skeleton* gfx_get_object_skeleton(const SceneObject* object) {
  assert(object);
  return (object->skeleton.val == 0) ? 0 : mem_get_skeleton(object->skeleton);
}

aabb3 gfx_get_object_aabb(const SceneObject* object) {
  assert(object);
  return object->box;
}