foo
[retroray] / src / scene.c
1 /*
2 RetroRay - integrated standalone vintage modeller/renderer
3 Copyright (C) 2023  John Tsiombikas <nuclear@mutantstargoat.com>
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU 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.
9
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 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program.  If not, see <https://www.gnu.org/licenses/>.
17 */
18 #include <stdlib.h>
19 #include "scene.h"
20 #include "darray.h"
21 #include "logger.h"
22
23 struct scene *create_scene(void)
24 {
25         struct scene *scn;
26
27         if(!(scn = malloc(sizeof *scn))) {
28                 errormsg("failed to allocate scene\n");
29                 return 0;
30         }
31         scn->objects = darr_alloc(0, sizeof *scn->objects);
32
33         return scn;
34 }
35
36 void free_scene(struct scene *scn)
37 {
38         int i;
39
40         if(!scn) return;
41
42         for(i=0; i<darr_size(scn->objects); i++) {
43                 free_object(scn->objects[i]);
44         }
45         darr_free(scn->objects);
46         free(scn);
47 }
48
49 int scn_add_object(struct scene *scn, struct object *obj)
50 {
51         darr_push(scn->objects, &obj);
52         return 0;
53 }
54
55 int scn_num_objects(struct scene *scn)
56 {
57         return darr_size(scn->objects);
58 }
59
60 struct object *create_object(int type)
61 {
62         struct object *obj;
63         struct sphere *sph;
64         char buf[32];
65         static int objid;
66
67         if(!(obj = malloc(sizeof *obj))) {
68                 errormsg("failed to allocate object\n");
69                 return 0;
70         }
71         obj->type = type;
72
73         cgm_vcons(&obj->pos, 0, 0, 0);
74         cgm_qcons(&obj->rot, 0, 0, 0, 1);
75         cgm_vcons(&obj->scale, 1, 1, 1);
76         cgm_vcons(&obj->pivot, 0, 0, 0);
77         cgm_midentity(obj->xform);
78
79         switch(type) {
80         case OBJ_SPHERE:
81                 sph = (struct sphere*)obj;
82                 sph->rad = 1.0f;
83                 sprintf(buf, "sphere%03d", objid);
84                 break;
85
86         default:
87                 sprintf(buf, "object%03d", objid);
88                 break;
89         }
90
91         set_object_name(obj, buf);
92         objid++;
93         return obj;
94 }
95
96 void free_object(struct object *obj)
97 {
98         if(!obj) return;
99
100         free(obj->name);
101         free(obj);
102 }
103
104 int set_object_name(struct object *obj, const char *name)
105 {
106         char *str = strdup(name);
107         if(!str) return -1;
108
109         free(obj->name);
110         obj->name = str;
111         return 0;
112 }
113
114 void calc_object_matrix(struct object *obj)
115 {
116         int i;
117         float rmat[16];
118         float *mat = obj->xform;
119
120         cgm_mtranslation(mat, obj->pivot.x, obj->pivot.y, obj->pivot.z);
121         cgm_mrotation_quat(rmat, &obj->rot);
122
123         for(i=0; i<3; i++) {
124                 mat[i] = rmat[i];
125                 mat[4 + i] = rmat[4 + i];
126                 mat[8 + i] = rmat[8 + i];
127         }
128
129         mat[0] *= obj->scale.x; mat[4] *= obj->scale.y; mat[8] *= obj->scale.z; mat[12] += obj->pos.x;
130         mat[1] *= obj->scale.x; mat[5] *= obj->scale.y; mat[9] *= obj->scale.z; mat[13] += obj->pos.y;
131         mat[2] *= obj->scale.x; mat[6] *= obj->scale.y; mat[10] *= obj->scale.z; mat[14] += obj->pos.z;
132
133         cgm_mpretranslate(mat, -obj->pivot.x, -obj->pivot.y, -obj->pivot.z);
134
135         /* that's basically: pivot * rotation * translation * scaling * -pivot */
136 }