27 #define TINYOBJ_LOADER_C_IMPLEMENTATION
28 #include <tinyobj_loader_c.h>
35 int num_vertices_local = *num_vertices;
37 for (
int i = 1; i < num_vertices_local;)
39 float* p0 = positions + (i - 1) * 3;
40 float* p1 = positions + (i % num_vertices_local) * 3;
41 float* p2 = positions + ((i + 1) % num_vertices_local) * 3;
44 VectorSubtract(p1, p0, e1);
45 VectorSubtract(p2, p1, e2);
46 float l1 = VectorLength(e1);
47 float l2 = VectorLength(e2);
49 qboolean remove = qfalse;
56 VectorScale(e1, 1.f / l1, e1);
57 VectorScale(e2, 1.f / l2, e2);
59 float dot = DotProduct(e1, e2);
66 if (num_vertices_local - i >= 1)
68 memcpy(p1, p2, (num_vertices_local - i - 1) * 3 *
sizeof(
float));
72 float* t1 = tex_coords + (i % num_vertices_local) * 2;
73 float* t2 = tex_coords + ((i + 1) % num_vertices_local) * 2;
74 memcpy(t1, t2, (num_vertices_local - i - 1) * 2 *
sizeof(
float));
86 *num_vertices = num_vertices_local;
89 #define DUMP_WORLD_MESH_TO_OBJ 0
90 #if DUMP_WORLD_MESH_TO_OBJ
91 static FILE* obj_dump_file = NULL;
92 static int obj_vertex_num = 0;
100 float *tex_coord_out,
101 uint32_t *material_out)
103 static const int max_vertices = 32;
104 float positions [3 * 32];
105 float tex_coords[2 * 32];
106 mtexinfo_t *texinfo = surf->texinfo;
107 assert(surf->numsurfedges < max_vertices);
109 float sc[2] = { 1.f, 1.f };
110 if (texinfo->material)
112 image_t* image_diffuse = texinfo->material->image_diffuse;
113 sc[0] = 1.0f / image_diffuse->width;
114 sc[1] = 1.0f / image_diffuse->height;
117 float pos_center[3] = { 0 };
120 for (
int i = 0; i < surf->numsurfedges; i++) {
121 msurfedge_t *src_surfedge = surf->firstsurfedge + i;
122 medge_t *src_edge = src_surfedge->edge;
123 mvertex_t *src_vert = src_edge->v[src_surfedge->vert];
125 float *p = positions + i * 3;
126 float *t = tex_coords + i * 2;
128 VectorCopy(src_vert->point, p);
130 pos_center[0] += src_vert->point[0];
131 pos_center[1] += src_vert->point[1];
132 pos_center[2] += src_vert->point[2];
134 t[0] = (DotProduct(p, texinfo->axis[0]) + texinfo->offset[0]) * sc[0];
135 t[1] = (DotProduct(p, texinfo->axis[1]) + texinfo->offset[1]) * sc[1];
137 #if DUMP_WORLD_MESH_TO_OBJ
140 fprintf(obj_dump_file,
"v %.3f %.3f %.3f\n", src_vert->point[0], src_vert->point[1], src_vert->point[2]);
145 #if DUMP_WORLD_MESH_TO_OBJ
148 fprintf(obj_dump_file,
"f ");
149 for (
int i = 0; i < surf->numsurfedges; i++) {
150 fprintf(obj_dump_file,
"%d ", obj_vertex_num);
153 fprintf(obj_dump_file,
"\n");
157 pos_center[0] /= (float)surf->numsurfedges;
158 pos_center[1] /= (
float)surf->numsurfedges;
159 pos_center[2] /= (float)surf->numsurfedges;
161 tc_center[0] = (DotProduct(pos_center, texinfo->axis[0]) + texinfo->offset[0]) * sc[0];
162 tc_center[1] = (DotProduct(pos_center, texinfo->axis[1]) + texinfo->offset[1]) * sc[1];
164 int num_vertices = surf->numsurfedges;
174 #define CP_V(idx, src) \
176 if(positions_out) { \
177 memcpy(positions_out + (idx) * 3, src, sizeof(float) * 3); \
181 #define CP_T(idx, src) \
183 if(tex_coord_out) { \
184 memcpy(tex_coord_out + (idx) * 2, src, sizeof(float) * 2); \
191 material_out[k] = material_id; \
198 int tess_center = num_vertices > 4 && !
is_sky;
200 const int num_triangles = tess_center
204 for (
int i = 0; i < num_triangles; i++)
206 int i1 = (i + 2 - tess_center) % num_vertices;
207 int i2 = (i + 1 - tess_center) % num_vertices;
209 CP_V(k, tess_center ? pos_center : positions);
210 CP_T(k, tess_center ? tc_center : tex_coords);
214 CP_V(k, positions + i1 * 3);
215 CP_T(k, tex_coords + i1 * 2);
219 CP_V(k, positions + i2 * 3);
220 CP_T(k, tex_coords + i2 * 2);
237 for (
int i = 0; i < bsp->nummodels; i++) {
238 if (surf >= bsp->models[i].firstface
239 && surf < bsp->models[i].firstface + bsp->models[i].numfaces)
284 const float* v0 = positions + 0;
285 const float* v1 = positions + 3;
286 const float* v2 = positions + 6;
290 VectorCopy(v0, center);
291 VectorAdd(center, v1, center);
292 VectorAdd(center, v2, center);
293 VectorScale(center, 1.f / 3.f, center);
297 vec3_t e1, e2, normal;
298 VectorSubtract(v1, v0, e1);
299 VectorSubtract(v2, v0, e2);
300 CrossProduct(e1, e2, normal);
306 VectorAdd(center, normal, center);
310 VectorMA(center, -2.f, normal, anti_center);
313 return (length > 0.f);
319 for (
int nstyle = 0; nstyle < 4; nstyle++)
321 if (surf->styles[nstyle] != 0 && surf->styles[nstyle] != 255)
323 return surf->styles[nstyle];
333 for (
int i = 0; i < surf->numsurfedges - 2; i++)
335 float* v0 = surf->firstsurfedge[i + 0].edge->v[surf->firstsurfedge[i + 0].vert]->point;
336 float* v1 = surf->firstsurfedge[i + 1].edge->v[surf->firstsurfedge[i + 1].vert]->point;
337 float* v2 = surf->firstsurfedge[(i + 2) % surf->numsurfedges].edge->v[surf->firstsurfedge[(i + 2) % surf->numsurfedges].vert]->point;
339 VectorSubtract(v1, v0, e0);
340 VectorSubtract(v2, v1, e1);
341 CrossProduct(e0, e1, plane);
342 float len = VectorLength(plane);
345 VectorScale(plane, 1.0f / len, plane);
346 plane[3] = -DotProduct(plane, v0);
385 for (
int i = 0; i < bsp->visrowsize; i++)
391 #define FOREACH_BIT_BEGIN(SET,ROWSIZE,VAR) \
392 for (int _byte_idx = 0; _byte_idx < ROWSIZE; _byte_idx++) { \
393 if (SET[_byte_idx]) { \
394 for (int _bit_idx = 0; _bit_idx < 8; _bit_idx++) { \
395 if (SET[_byte_idx] & (1 << _bit_idx)) { \
396 int VAR = (_byte_idx << 3) | _bit_idx;
398 #define FOREACH_BIT_END } } } }
400 static void connect_pvs(bsp_t* bsp,
int cluster_a,
char* pvs_a,
int cluster_b,
char* pvs_b)
403 if (vis_cluster_a != cluster_a && vis_cluster_a != cluster_b)
410 if (vis_cluster_b != cluster_a && vis_cluster_b != cluster_b)
422 for (
int cluster = 0; cluster < bsp->vis->numclusters; cluster++)
427 if (vis_cluster != cluster)
430 Q_SetBit(vis_pvs, cluster);
438 size_t matrix_size = bsp->visrowsize * bsp->vis->numclusters;
440 bsp->pvs2_matrix = Z_Mallocz(matrix_size);
442 for (
int cluster = 0; cluster < bsp->vis->numclusters; cluster++)
446 memcpy(dest_pvs, pvs, bsp->visrowsize);
459 mface_t *
surfaces = model_idx < 0 ? bsp->faces : bsp->models[model_idx].firstface;
460 int num_faces = model_idx < 0 ? bsp->numfaces : bsp->models[model_idx].numfaces;
461 qboolean any_pvs_patches = qfalse;
463 for (
int i = 0; i < num_faces; i++) {
470 uint32_t material_id = surf->texinfo->material ? surf->texinfo->material->
flags : 0;
471 uint32_t surf_flags = surf->drawflags | surf->texinfo->c.flags;
485 if (surf_flags & SURF_SKY)
494 if (surf_flags & SURF_WARP)
497 if (surf_flags & SURF_FLOWING)
500 if (!filter(material_id))
517 Com_Error(ERR_FATAL,
"error: exceeding max vertex limit\n");
525 for (
int it = *idx_ctr / 3, k = 0; k < cnt; k += 3, ++it)
533 vec3_t center, anti_center;
547 if (!bsp->pvs_patched)
551 int anti_cluster =
BSP_PointLeaf(bsp->nodes, anti_center)->cluster;
553 if (cluster >= 0 && anti_cluster >= 0 && cluster != anti_cluster)
556 char* pvs_anti_cluster =
BSP_GetPvs(bsp, anti_cluster);
558 if (!Q_IsBitSet(pvs_cluster, anti_cluster) || !Q_IsBitSet(pvs_anti_cluster, cluster))
560 connect_pvs(bsp, cluster, pvs_cluster, anti_cluster, pvs_anti_cluster);
561 any_pvs_patches = qtrue;
587 #define MAX_POLY_VERTS 32
596 return a->
x * b->
x + a->
y * b->
y;
602 return a->
x * b->
y - a->
y * b->
x;
624 return x < 0 ? -1 : x > 0;
637 float dyx =
cross2(&dy, &dx);
639 dyx =
cross2(&d, &dx) / dyx;
640 if (dyx <= 0 || dyx >= 1)
return 0;
642 res->
x = y0->
x + dyx * dy.
x;
643 res->
y = y0->
y + dyx * dy.
y;
672 for (i = 0; i < sub->
len; i++) {
675 if (side0 + side1 == 0 && side0)
679 if (i == sub->
len - 1)
break;
697 for (i = 0; i < clipper->
len - 1; i++) {
698 tmp = p2; p2 = p1; p1 = tmp;
714 if (*num_lights == *allocated)
716 *allocated = max(*allocated * 2, 128);
719 return *lights + (*num_lights)++;
722 static inline qboolean
731 mface_t *
surfaces = model_idx < 0 ? bsp->faces : bsp->models[model_idx].firstface;
732 int num_faces = model_idx < 0 ? bsp->numfaces : bsp->models[model_idx].numfaces;
734 for (
int i = 0; i < num_faces; i++)
741 mtexinfo_t *texinfo = surf->texinfo;
743 if(!texinfo->material)
746 uint32_t material_id = texinfo->material->
flags;
751 const image_t *image = texinfo->material->image_emissive;
762 if (image->entire_texture_emissive)
769 float positions[3 * 32];
771 for (
int i = 0; i < surf->numsurfedges; i++)
773 msurfedge_t *src_surfedge = surf->firstsurfedge + i;
774 medge_t *src_edge = src_surfedge->edge;
775 mvertex_t *src_vert = src_edge->v[src_surfedge->vert];
777 float *p = positions + i * 3;
779 VectorCopy(src_vert->point, p);
782 int num_vertices = surf->numsurfedges;
785 const int num_triangles = surf->numsurfedges - 2;
787 for (
int i = 0; i < num_triangles; i++)
789 const int e = surf->numsurfedges;
791 int i1 = (i + 2) % e;
792 int i2 = (i + 1) % e;
795 VectorCopy(positions, light.
positions + 0);
796 VectorCopy(positions + i1 * 3, light.
positions + 3);
797 VectorCopy(positions + i2 * 3, light.
positions + 6);
798 VectorCopy(image->light_color, light.
color);
801 light.
style = light_style;
825 image_t* image_diffuse = texinfo->material->image_diffuse;
826 float tex_scale[2] = { 1.0f / image_diffuse->width, 1.0f / image_diffuse->height };
829 vec4_t tex_axis0, tex_axis1;
830 VectorScale(texinfo->axis[0], tex_scale[0], tex_axis0);
831 VectorScale(texinfo->axis[1], tex_scale[1], tex_axis1);
832 tex_axis0[3] = texinfo->offset[0] * tex_scale[0];
833 tex_axis1[3] = texinfo->offset[1] * tex_scale[1];
837 float tex_axis0_inv_square_length = 1.0f / DotProduct(tex_axis0, tex_axis0);
838 float tex_axis1_inv_square_length = 1.0f / DotProduct(tex_axis1, tex_axis1);
842 CrossProduct(tex_axis0, tex_axis1, tex_normal);
845 float surf_normal_dot_tex_normal = DotProduct(tex_normal, plane);
847 if (surf_normal_dot_tex_normal == 0.f)
858 tex_poly.
len = surf->numsurfedges;
860 point2_t tex_min = { FLT_MAX, FLT_MAX };
861 point2_t tex_max = { -FLT_MAX, -FLT_MAX };
863 for (
int i = 0; i < surf->numsurfedges; i++)
865 msurfedge_t *src_surfedge = surf->firstsurfedge + i;
866 medge_t *src_edge = src_surfedge->edge;
867 mvertex_t *src_vert = src_edge->v[src_surfedge->vert];
870 t.
x = DotProduct(src_vert->point, tex_axis0) + tex_axis0[3];
871 t.
y = DotProduct(src_vert->point, tex_axis1) + tex_axis1[3];
875 tex_min.
x = min(tex_min.
x, t.
x);
876 tex_min.
y = min(tex_min.
y, t.
y);
877 tex_max.
x = max(tex_max.
x, t.
x);
878 tex_max.
y = max(tex_max.
y, t.
y);
884 for (
float y_tile = floorf(tex_min.
y); y_tile <= ceilf(tex_max.
y); y_tile++)
886 for (
float x_tile = floorf(tex_min.
x); x_tile <= ceilf(tex_max.
x); x_tile++)
888 float x_min = x_tile + image->min_light_texcoord[0];
889 float x_max = x_tile + image->max_light_texcoord[0];
890 float y_min = y_tile + image->min_light_texcoord[1];
891 float y_max = y_tile + image->max_light_texcoord[1];
897 clipper.
v[0].
x = x_min; clipper.
v[0].
y = y_min;
898 clipper.
v[1].
x = x_max; clipper.
v[1].
y = y_min;
899 clipper.
v[2].
x = x_max; clipper.
v[2].
y = y_max;
900 clipper.
v[3].
x = x_min; clipper.
v[3].
y = y_max;
907 if (instance.
len < 3)
916 for (
int vert = 0; vert < instance.
len; vert++)
920 vec3_t p0, p1, point_on_texture_plane;
921 VectorScale(tex_axis0, (instance.
v[vert].
x - tex_axis0[3]) * tex_axis0_inv_square_length, p0);
922 VectorScale(tex_axis1, (instance.
v[vert].
y - tex_axis1[3]) * tex_axis1_inv_square_length, p1);
923 VectorAdd(p0, p1, point_on_texture_plane);
934 float bn = DotProduct(point_on_texture_plane, plane);
936 float ray_t = -(bn + plane[3]) / surf_normal_dot_tex_normal;
939 VectorScale(tex_normal, ray_t, p2);
940 VectorAdd(p2, point_on_texture_plane, instance_positions[vert]);
945 const int num_triangles = instance.
len - 2;
947 for (
int i = 0; i < num_triangles; i++)
949 const int e = instance.
len;
951 int i1 = (i + 2) % e;
952 int i2 = (i + 1) % e;
955 light->
material = texinfo->material;
956 light->
style = light_style;
957 VectorCopy(instance_positions[0], light->
positions + 0);
958 VectorCopy(instance_positions[i1], light->
positions + 3);
959 VectorCopy(instance_positions[i2], light->
positions + 6);
960 VectorCopy(image->light_color, light->
color);
990 for (
int i = 0; i < bsp->numfaces; i++)
992 mface_t *surf = bsp->faces + i;
997 int flags = surf->drawflags;
998 if (surf->texinfo) flags |= surf->texinfo->c.flags;
1000 qboolean
is_sky = !!(flags & SURF_SKY);
1006 float positions[3 * 32];
1008 for (
int i = 0; i < surf->numsurfedges; i++)
1010 msurfedge_t *src_surfedge = surf->firstsurfedge + i;
1011 medge_t *src_edge = src_surfedge->edge;
1012 mvertex_t *src_vert = src_edge->v[src_surfedge->vert];
1014 float *p = positions + i * 3;
1016 VectorCopy(src_vert->point, p);
1019 int num_vertices = surf->numsurfedges;
1022 const int num_triangles = num_vertices - 2;
1024 for (
int i = 0; i < num_triangles; i++)
1026 int i1 = (i + 2) % num_vertices;
1027 int i2 = (i + 1) % num_vertices;
1030 VectorCopy(positions, light.
positions + 0);
1031 VectorCopy(positions + i1 * 3, light.
positions + 3);
1032 VectorCopy(positions + i2 * 3, light.
positions + 6);
1036 VectorSet(light.
color, -1.f, -1.f, -1.f);
1041 VectorCopy(surf->texinfo->material->image_emissive->light_color, light.
color);
1042 light.
material = surf->texinfo->material;
1067 for (
int i = 0; i < model->
idx_count / 3; i++)
1085 uint32_t projected0, projected1;
1086 float invL1Norm = 1.0f / (fabs(normal[0]) + fabs(normal[1]) + fabs(normal[2]));
1090 if (normal[2] < 0.0f) {
1091 enc0 = (1.0f - abs(normal[1] * invL1Norm)) * ((normal[0] < 0.0f) ? -1.0f : 1.0f);
1092 enc1 = (1.0f - abs(normal[0] * invL1Norm)) * ((normal[1] < 0.0f) ? -1.0f : 1.0f);
1095 enc0 = normal[0] * invL1Norm;
1096 enc1 = normal[1] * invL1Norm;
1102 projected0 = ((
floatBitsToUint(enc0) & 0x80000000u) >> 16) | ((enci0 & 0x7fffffu) >> 8);
1103 projected1 = ((
floatBitsToUint(enc1) & 0x80000000u) >> 16) | ((enci1 & 0x7fffffu) >> 8);
1105 if ((projected0 & 0x7fffu) == 0) projected0 = 0;
1106 if ((projected1 & 0x7fffu) == 0) projected1 = 0;
1107 return (projected1 << 16) | projected0;
1111 compute_aabb(
const float* positions,
int numvert,
float* aabb_min,
float* aabb_max)
1113 VectorSet(aabb_min, FLT_MAX, FLT_MAX, FLT_MAX);
1114 VectorSet(aabb_max, -FLT_MAX, -FLT_MAX, -FLT_MAX);
1116 for (
int i = 0; i < numvert; i++)
1118 float const* position = positions + i * 3;
1120 aabb_min[0] = min(aabb_min[0], position[0]);
1121 aabb_min[1] = min(aabb_min[1], position[1]);
1122 aabb_min[2] = min(aabb_min[2], position[2]);
1124 aabb_max[0] = max(aabb_max[0], position[0]);
1125 aabb_max[1] = max(aabb_max[1], position[1]);
1126 aabb_max[2] = max(aabb_max[2], position[2]);
1141 for (
int idx_tri = 0; idx_tri < ntriangles; ++idx_tri)
1143 uint32_t iA = wm->
indices[idx_tri * 3 + 0];
1144 uint32_t iB = wm->
indices[idx_tri * 3 + 1];
1145 uint32_t iC = wm->
indices[idx_tri * 3 + 2];
1147 float const * pA = wm->
positions + (iA * 3);
1148 float const * pB = wm->
positions + (iB * 3);
1149 float const * pC = wm->
positions + (iC * 3);
1151 float const * tA = wm->
tex_coords + (iA * 2);
1152 float const * tB = wm->
tex_coords + (iB * 2);
1153 float const * tC = wm->
tex_coords + (iC * 2);
1156 VectorSubtract(pB, pA, dP0);
1157 VectorSubtract(pC, pA, dP1);
1160 Vector2Subtract(tB, tA, dt0);
1161 Vector2Subtract(tC, tA, dt1);
1163 float r = 1.f / (dt0[0] * dt1[1] - dt1[0] * dt0[1]);
1166 (dt1[1] * dP0[0] - dt0[1] * dP1[0]) * r,
1167 (dt1[1] * dP0[1] - dt0[1] * dP1[1]) * r,
1168 (dt1[1] * dP0[2] - dt0[1] * dP1[2]) * r };
1171 (dt0[0] * dP1[0] - dt1[0] * dP0[0]) * r,
1172 (dt0[0] * dP1[1] - dt1[0] * dP0[1]) * r,
1173 (dt0[0] * dP1[2] - dt1[0] * dP0[2]) * r };
1176 CrossProduct(dP0, dP1, normal);
1182 VectorScale(normal, DotProduct(normal, sdir), t);
1183 VectorSubtract(sdir, t, t);
1186 VectorSet(&wm->
tangents[idx_tri * 3], tangent[0], tangent[1], tangent[2]);
1189 CrossProduct(normal, t, cross);
1190 float dot = DotProduct(cross, tdir);
1197 float texel_density = 0.f;
1207 float WL0 = VectorLength(dP0);
1208 float WL1 = VectorLength(dP1);
1209 float TL0 = sqrt(dt0[0] * dt0[0] + dt0[1] * dt0[1]);
1210 float TL1 = sqrt(dt1[0] * dt1[0] + dt1[1] * dt1[1]);
1211 float L0 = (WL0 > 0) ? (TL0 / WL0) : 0.f;
1212 float L1 = (WL1 > 0) ? (TL1 / WL1) : 0.f;
1214 texel_density = max(L0, L1);
1228 char filename[MAX_QPATH];
1229 Q_snprintf(filename,
sizeof(filename),
"maps/sky/%s.txt", map_name);
1231 qboolean found_map = qfalse;
1233 char* filebuf = NULL;
1234 FS_LoadFile(filename, &filebuf);
1244 FS_LoadFile(
"sky_clusters.txt", &filebuf);
1247 Com_WPrintf(
"Couldn't read sky_clusters.txt\n");
1252 char const * ptr = (
char const *)filebuf;
1255 while (
sgets(linebuf,
sizeof(linebuf), &ptr))
1257 {
char* t = strchr(linebuf,
'#');
if (t) *t = 0; }
1258 {
char* t = strchr(linebuf,
'\n');
if (t) *t = 0; }
1260 const char* delimiters =
" \t\r\n";
1262 const char* word = strtok(linebuf, delimiters);
1265 if (word[0] >=
'a' && word[0] <=
'z' || word[0] >=
'A' && word[0] <=
'Z')
1267 qboolean matches = strcmp(word, map_name) == 0;
1269 if (!found_map && matches)
1273 else if (found_map && !matches)
1283 if (!strcmp(word,
"!all_lava"))
1287 int cluster = atoi(word);
1292 word = strtok(NULL, delimiters);
1304 char* filebuf = NULL;
1305 FS_LoadFile(
"cameras.txt", &filebuf);
1308 Com_WPrintf(
"Couldn't read cameras.txt\n");
1312 char const * ptr = (
char const *)filebuf;
1314 qboolean found_map = qfalse;
1316 while (
sgets(linebuf,
sizeof(linebuf), &ptr))
1318 {
char* t = strchr(linebuf,
'#');
if (t) *t = 0; }
1319 {
char* t = strchr(linebuf,
'\n');
if (t) *t = 0; }
1323 if (linebuf[0] >=
'a' && linebuf[0] <=
'z' || linebuf[0] >=
'A' && linebuf[0] <=
'Z')
1325 const char* delimiters =
" \t\r\n";
1326 const char* word = strtok(linebuf, delimiters);
1327 qboolean matches = strcmp(word, map_name) == 0;
1329 if (!found_map && matches)
1333 else if (found_map && !matches)
1339 else if (found_map && sscanf(linebuf,
"(%f, %f, %f) (%f, %f, %f)", &pos[0], &pos[1], &pos[2], &dir[0], &dir[1], &dir[2]) == 6)
1361 int numclusters = bsp->vis->numclusters;
1363 char clusters_with_sky[VIS_MAX_BYTES];
1365 memset(clusters_with_sky, 0, VIS_MAX_BYTES);
1372 clusters_with_sky[cluster >> 3] |= (1 << (cluster & 7));
1375 for (
int cluster = 0; cluster < numclusters; cluster++)
1377 if (clusters_with_sky[cluster >> 3] & (1 << (cluster & 7)))
1381 for (
int i = 0; i < bsp->visrowsize; i++)
1406 for (
int i = 0; i < 3; i++)
1408 float const* position = wm->
positions + tri * 9 + i * 3;
1410 aabb->
mins[0] = min(aabb->
mins[0], position[0]);
1411 aabb->
mins[1] = min(aabb->
mins[1], position[1]);
1412 aabb->
mins[2] = min(aabb->
mins[2], position[2]);
1414 aabb->
maxs[0] = max(aabb->
maxs[0], position[0]);
1415 aabb->
maxs[1] = max(aabb->
maxs[1], position[1]);
1416 aabb->
maxs[2] = max(aabb->
maxs[2], position[2]);
1424 corner[0] = (corner_idx & 1) ? aabb->
maxs[0] : aabb->
mins[0];
1425 corner[1] = (corner_idx & 2) ? aabb->
maxs[1] : aabb->
mins[1];
1426 corner[2] = (corner_idx & 4) ? aabb->
maxs[2] : aabb->
mins[2];
1441 vec3_t e1, e2, normal;
1442 VectorSubtract(v1, v0, e1);
1443 VectorSubtract(v2, v0, e2);
1444 CrossProduct(e1, e2, normal);
1447 float plane_distance = -DotProduct(normal, v0);
1449 qboolean all_culled = qtrue;
1452 for (
int corner_idx = 0; corner_idx < 8; corner_idx++)
1457 float side = DotProduct(normal, corner) + plane_distance;
1459 all_culled = qfalse;
1473 #define MAX_LIGHTS_PER_CLUSTER 1024
1497 (*num_cluster_lights)++;
1506 for (
int cluster = 0; cluster < wm->
num_clusters; cluster++)
1518 int list_offset = 0;
1519 for (
int cluster = 0; cluster < wm->
num_clusters; cluster++)
1521 assert(list_offset >= 0);
1527 count *
sizeof(
int));
1528 list_offset += count;
1534 #undef MAX_LIGHTS_PER_CLUSTER
1540 char filename[MAX_QPATH];
1541 Q_snprintf(filename,
sizeof(filename),
"maps/sky/%s.obj", map_name);
1543 void* file_buffer = NULL;
1544 ssize_t file_size = FS_LoadFile(filename, &file_buffer);
1548 tinyobj_attrib_t attrib;
1549 tinyobj_shape_t* shapes = NULL;
1551 tinyobj_material_t* materials = NULL;
1552 size_t num_materials;
1554 unsigned int flags = TINYOBJ_FLAG_TRIANGULATE;
1555 int ret = tinyobj_parse_obj(&attrib, &shapes, &num_shapes, &materials,
1556 &num_materials, (
const char*)file_buffer, file_size, flags);
1558 FS_FreeFile(file_buffer);
1560 if (ret != TINYOBJ_SUCCESS) {
1561 Com_WPrintf(
"Couldn't parse sky polygon definition file %s.\n", filename);
1565 int face_offset = 0;
1566 for (
int nprim = 0; nprim < attrib.num_face_num_verts; nprim++)
1568 int face_num_verts = attrib.face_num_verts[nprim];
1569 int i0 = attrib.faces[face_offset + 0].v_idx;
1570 int i1 = attrib.faces[face_offset + 1].v_idx;
1571 int i2 = attrib.faces[face_offset + 2].v_idx;
1574 VectorCopy(attrib.vertices + i0 * 3, v0);
1575 VectorCopy(attrib.vertices + i1 * 3, v1);
1576 VectorCopy(attrib.vertices + i2 * 3, v2);
1578 int wm_index = *idx_ctr;
1579 int wm_prim = wm_index / 3;
1581 VectorCopy(v0, wm->
positions + wm_index * 3 + 0);
1582 VectorCopy(v1, wm->
positions + wm_index * 3 + 3);
1583 VectorCopy(v2, wm->
positions + wm_index * 3 + 6);
1604 VectorSet(light->
color, -1.f, -1.f, -1.f);
1612 face_offset += face_num_verts;
1615 tinyobj_attrib_free(&attrib);
1616 tinyobj_shapes_free(shapes, num_shapes);
1617 tinyobj_materials_free(materials, num_materials);
1625 const char* full_game_map_name = map_name;
1626 if (strcmp(map_name,
"demo1") == 0)
1627 full_game_map_name =
"base1";
1628 else if (strcmp(map_name,
"demo2") == 0)
1629 full_game_map_name =
"base2";
1630 else if (strcmp(map_name,
"demo3") == 0)
1631 full_game_map_name =
"base3";
1661 #if DUMP_WORLD_MESH_TO_OBJ
1663 char filename[MAX_QPATH];
1664 Q_snprintf(filename,
sizeof(filename),
"C:\\temp\\%s.obj", map_name);
1665 obj_dump_file = fopen(filename,
"w");
1685 for (
int k = 0; k < bsp->nummodels; k++) {
1692 #if DUMP_WORLD_MESH_TO_OBJ
1693 fclose(obj_dump_file);
1694 obj_dump_file = NULL;
1697 if (!bsp->pvs_patched)
1703 Com_EPrintf(
"Couldn't save patched PVS for %s.\n", bsp->name);
1710 wm->
indices = Z_Malloc(idx_ctr *
sizeof(
int));
1732 vec3_t margin = { 1.f, 1.f, 1.f };
1741 for (
int k = 0; k < bsp->nummodels; k++)
1777 memset(wm, 0,
sizeof(*wm));
1783 for (
int i = 0; i < bsp->numtexinfo; i++) {
1784 mtexinfo_t *info = bsp->texinfo + i;
1786 if (info->c.flags & SURF_WARP)
1787 flags = IF_TURBULENT;
1791 char buffer[MAX_QPATH];
1792 Q_concat(buffer,
sizeof(buffer),
"textures/", info->name,
".wal", NULL);
1797 Com_EPrintf(
"error finding material '%s'\n", buffer);
1800 image_t* image_normals = NULL;
1801 image_t* image_emissive = NULL;
1803 if (image_diffuse != R_NOTEXTURE)
1806 Q_concat(buffer,
sizeof(buffer),
"textures/", info->name,
"_n.tga", NULL);
1808 image_normals =
IMG_Find(buffer, IT_WALL, flags);
1809 if (image_normals == R_NOTEXTURE) image_normals = NULL;
1811 if (image_normals && !image_normals->processing_complete)
1817 Q_concat(buffer,
sizeof(buffer),
"textures/", info->name,
"_light.tga", NULL);
1819 image_emissive =
IMG_Find(buffer, IT_WALL, flags | IF_SRGB);
1820 if (image_emissive == R_NOTEXTURE) image_emissive = NULL;
1831 info->material = mat;
1835 for (
int i = 0; i < bsp->numtexinfo; i++)
1837 mtexinfo_t *texinfo = bsp->texinfo + i;
1840 if (texinfo->numframes > 1)
1842 assert(texinfo->next);
1843 assert(texinfo->next->material);