@@ -31,6 +31,33 @@ pub const ErrorInfo = struct {
3131pub const QuakeMapHit = struct {
3232 loc : Vec3 ,
3333 plane : Plane ,
34+ solid : * const Solid ,
35+
36+ // Find which of our faces was hit by getting the closest one
37+ pub fn getFace (self : * const QuakeMapHit ) * Face {
38+ var closest_face_idx : usize = 0 ;
39+ var closest_face_dist : f32 = std .math .floatMax (f32 );
40+ var closest_angle_diff : f32 = 0 ;
41+
42+ for (0.. self .solid .faces .items .len ) | f_idx | {
43+ const check_plane = & self .solid .faces .items [f_idx ].plane ;
44+ const dist = check_plane .distanceToPoint (self .loc );
45+ const angle_diff = check_plane .normal .dot (self .plane .normal );
46+
47+ // ignore hits behind us!
48+ if (dist < -0.001 or angle_diff <= 0.0 )
49+ continue ;
50+
51+ // save the new hit if it is closer
52+ if (dist <= closest_face_dist and angle_diff >= closest_angle_diff ) {
53+ closest_face_idx = f_idx ;
54+ closest_face_dist = dist ;
55+ closest_angle_diff = angle_diff ;
56+ }
57+ }
58+
59+ return & self .solid .faces .items [closest_face_idx ];
60+ }
3461};
3562
3663pub const Property = struct {
@@ -395,6 +422,7 @@ pub const Solid = struct {
395422 worldhit = .{
396423 .loc = h ,
397424 .plane = p ,
425+ .solid = self ,
398426 };
399427
400428 // convex, so should only have one collision
@@ -442,6 +470,7 @@ pub const Solid = struct {
442470 worldhit = .{
443471 .loc = h ,
444472 .plane = p ,
473+ .solid = self ,
445474 };
446475
447476 // convex, so should only have one collision
@@ -486,6 +515,7 @@ pub const Solid = struct {
486515 worldhit = .{
487516 .loc = h .hit_pos ,
488517 .plane = p ,
518+ .solid = self ,
489519 };
490520
491521 // convex, so should only have one collision
@@ -502,6 +532,8 @@ pub const QuakeMaterial = struct {
502532 material : graphics.Material ,
503533 tex_size_x : i32 = 32 ,
504534 tex_size_y : i32 = 32 ,
535+ custom_flags : u32 = 0 , // eg: dirt, metal, etc
536+ hidden : bool = false , // whether to add this to mesh builders
505537};
506538
507539pub const QuakeMap = struct {
@@ -660,7 +692,7 @@ pub const QuakeMap = struct {
660692
661693 /// Builds meshes for the map, bucketed by materials
662694 pub fn buildWorldMeshes (self : * const QuakeMap , allocator : Allocator , transform : Mat4 , materials : * std .StringHashMap (QuakeMaterial ), fallback_material : ? * QuakeMaterial ) ! std .ArrayList (Mesh ) {
663- return try buildMeshesForEntity (& self .worldspawn , allocator , transform , materials , fallback_material );
695+ return try self . buildMeshesForEntity (& self .worldspawn , allocator , transform , materials , fallback_material );
664696 }
665697
666698 /// Builds meshes for all entity solids - in a real scenario, you'll probably want to use buildMeshesForEntity instead
@@ -694,7 +726,9 @@ pub const QuakeMap = struct {
694726 }
695727
696728 /// Builds meshes for a specific entity
697- pub fn buildMeshesForEntity (entity : * const Entity , allocator : Allocator , transform : Mat4 , materials : * std .StringHashMap (QuakeMaterial ), fallback_material : ? * QuakeMaterial ) ! std .ArrayList (Mesh ) {
729+ pub fn buildMeshesForEntity (self : * const QuakeMap , entity : * const Entity , allocator : Allocator , transform : Mat4 , materials : * std .StringHashMap (QuakeMaterial ), fallback_material : ? * QuakeMaterial ) ! std .ArrayList (Mesh ) {
730+ _ = self ;
731+
698732 // Make our mesh buckets - we'll make a new mesh per material!
699733 var mesh_builders = std .StringHashMap (mesh .MeshBuilder ).init (allocator );
700734 defer mesh_builders .deinit ();
@@ -760,6 +794,10 @@ pub const QuakeMap = struct {
760794 // first find our texture scaling
761795 var mat_tex_size = Vec2 .new (32.0 , 32.0 );
762796 if (material ) | mat | {
797+ // skip this face if material is hidden
798+ if (mat .hidden )
799+ return ;
800+
763801 mat_tex_size .x = @floatFromInt (mat .tex_size_x );
764802 mat_tex_size .y = @floatFromInt (mat .tex_size_y );
765803 }
0 commit comments