2 goat3d - 3D scene, and animation file format library.
3 Copyright (C) 2013-2023 John Tsiombikas <nuclear@member.fsf.org>
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 int g3dimpl_obj_init(struct object *o, int type)
24 static int last_mesh, last_light, last_camera;
25 struct goat3d_mesh *m;
26 struct goat3d_light *lt;
27 struct goat3d_camera *cam;
30 if(!(name = malloc(64))) {
36 m = (struct goat3d_mesh*)o;
37 memset(m, 0, sizeof *m);
38 if(!(m->vertices = dynarr_alloc(0, sizeof *m->vertices))) goto err;
39 if(!(m->normals = dynarr_alloc(0, sizeof *m->normals))) goto err;
40 if(!(m->tangents = dynarr_alloc(0, sizeof *m->tangents))) goto err;
41 if(!(m->texcoords = dynarr_alloc(0, sizeof *m->texcoords))) goto err;
42 if(!(m->skin_weights = dynarr_alloc(0, sizeof *m->skin_weights))) goto err;
43 if(!(m->skin_matrices = dynarr_alloc(0, sizeof *m->skin_matrices))) goto err;
44 if(!(m->colors = dynarr_alloc(0, sizeof *m->colors))) goto err;
45 if(!(m->faces = dynarr_alloc(0, sizeof *m->faces))) goto err;
46 if(!(m->bones = dynarr_alloc(0, sizeof *m->bones))) goto err;
47 sprintf(name, "mesh%d", last_mesh++);
51 lt = (struct goat3d_light*)o;
52 memset(lt, 0, sizeof *lt);
53 cgm_vcons(<->color, 1, 1, 1);
54 cgm_vcons(<->attenuation, 1, 0, 0);
55 cgm_vcons(<->dir, 0, 0, 1);
56 lt->inner_cone = cgm_deg_to_rad(30);
57 lt->outer_cone = cgm_deg_to_rad(45);
58 sprintf(name, "light%d", last_light++);
62 cam = (struct goat3d_camera*)o;
63 memset(cam, 0, sizeof *cam);
64 cam->near_clip = 0.5f;
65 cam->far_clip = 500.0f;
66 cgm_vcons(&cam->up, 0, 1, 0);
67 sprintf(name, "camera%d", last_camera++);
76 cgm_qcons(&o->rot, 0, 0, 0, 1);
77 cgm_vcons(&o->scale, 1, 1, 1);
82 g3dimpl_obj_destroy(o);
86 void g3dimpl_obj_destroy(struct object *o)
88 struct goat3d_mesh *m;
92 m = (struct goat3d_mesh*)o;
93 dynarr_free(m->vertices);
94 dynarr_free(m->normals);
95 dynarr_free(m->tangents);
96 dynarr_free(m->texcoords);
97 dynarr_free(m->skin_weights);
98 dynarr_free(m->skin_matrices);
99 dynarr_free(m->colors);
100 dynarr_free(m->faces);
101 dynarr_free(m->bones);
109 void g3dimpl_mesh_bounds(struct aabox *bb, struct goat3d_mesh *m, float *xform)
113 g3dimpl_aabox_init(bb);
115 nverts = dynarr_size(m->vertices);
116 for(i=0; i<nverts; i++) {
117 cgm_vec3 v = m->vertices[i];
118 if(xform) cgm_vmul_m4v3(&v, xform);
120 if(v.x < bb->bmin.x) bb->bmin.x = v.x;
121 if(v.y < bb->bmin.y) bb->bmin.y = v.y;
122 if(v.z < bb->bmin.z) bb->bmin.z = v.z;
124 if(v.x > bb->bmax.x) bb->bmax.x = v.x;
125 if(v.y > bb->bmax.y) bb->bmax.y = v.y;
126 if(v.z > bb->bmax.z) bb->bmax.z = v.z;
130 int g3dimpl_mtl_init(struct goat3d_material *mtl)
132 memset(mtl, 0, sizeof *mtl);
133 if(!(mtl->attrib = dynarr_alloc(0, sizeof *mtl->attrib))) {
139 void g3dimpl_mtl_destroy(struct goat3d_material *mtl)
141 int i, num = dynarr_size(mtl->attrib);
142 for(i=0; i<num; i++) {
143 free(mtl->attrib[i].name);
144 free(mtl->attrib[i].map);
146 dynarr_free(mtl->attrib);
149 struct material_attrib *g3dimpl_mtl_findattr(struct goat3d_material *mtl, const char *name)
151 int i, num = dynarr_size(mtl->attrib);
153 for(i=0; i<num; i++) {
154 if(strcmp(mtl->attrib[i].name, name) == 0) {
155 return mtl->attrib + i;
161 struct material_attrib *g3dimpl_mtl_getattr(struct goat3d_material *mtl, const char *name)
165 struct material_attrib *tmpattr, *ma;
167 if((ma = g3dimpl_mtl_findattr(mtl, name))) {
172 if(!(tmpname = malloc(len + 1))) {
175 memcpy(tmpname, name, len + 1);
177 idx = dynarr_size(mtl->attrib);
178 if(!(tmpattr = dynarr_push(mtl->attrib, 0))) {
182 mtl->attrib = tmpattr;
184 ma = mtl->attrib + idx;
187 cgm_wcons(&ma->value, 1, 1, 1, 1);
192 void g3dimpl_node_bounds(struct aabox *bb, struct goat3d_node *n)
194 struct object *obj = n->obj;
195 struct goat3d_node *cn = n->child;
198 goat3d_get_matrix(n, xform);
200 if(obj && obj->type == OBJTYPE_MESH) {
201 g3dimpl_mesh_bounds(bb, (struct goat3d_mesh*)obj, xform);
203 g3dimpl_aabox_init(bb);
208 g3dimpl_node_bounds(&cbox, cn);
209 g3dimpl_aabox_union(bb, bb, &cbox);