@@ -3,7 +3,6 @@ class_name VMFSolid extends RefCounted
33var id : int = - 1 ;
44var sides : Array [VMFSide ] = [];
55var has_displacement : bool = false ;
6- var intersections : Dictionary = {};
76var min : Vector3 = Vector3 (INF , INF , INF );
87var max : Vector3 = Vector3 (- INF , - INF , - INF );
98var vertices : Array [Vector3 ] = [];
@@ -31,23 +30,66 @@ func define_sides(raw: Dictionary) -> void:
3130
3231 if side_instance .is_displacement :
3332 has_displacement = true ;
34-
33+
34+ var needs_computation := false ;
35+ for s in sides :
36+ if s .vertices .size () == 0 :
37+ needs_computation = true ;
38+ break ;
39+
40+ if needs_computation :
41+ _compute_vertices_from_planes ();
42+
3543 for side in sides :
3644 side .calculate_vertices ();
3745
38- intersections = {};
3946 vertices = [];
4047
41- func get_planes_intersection_point (side : VMFSide , side2 : VMFSide , side3 : VMFSide ) -> Variant :
42- var d : Array [int ] = [side .id , side2 .id , side3 .id ];
43- d .sort ();
48+ for side in sides :
49+ for v in side .vertices :
50+ if v .x < min .x : min .x = v .x ;
51+ if v .y < min .y : min .y = v .y ;
52+ if v .z < min .z : min .z = v .z ;
53+ if v .x > max .x : max .x = v .x ;
54+ if v .y > max .y : max .y = v .y ;
55+ if v .z > max .z : max .z = v .z ;
56+
57+ ## Computes vertices for all sides that don't have pre-computed vertices (i.e. no vertices_plus).
58+ ## Iterates all unique plane triples once (C(n,3)), tests each intersection against all planes,
59+ ## then distributes valid vertices to the three involved sides and sorts them.
60+ func _compute_vertices_from_planes () -> void :
61+ var n := sides .size ();
62+ var side_verts : Array [Dictionary ] = [];
63+ side_verts .resize (n );
64+ for i in range (n ):
65+ side_verts [i ] = {};
66+
67+ for i in range (n ):
68+ for j in range (i + 1 , n ):
69+ for k in range (j + 1 , n ):
70+ var v : Variant = sides [i ].plane .intersect_3 (sides [j ].plane , sides [k ].plane );
71+ if v == null : continue ;
72+ var vertex := v as Vector3 ;
73+
74+ var valid := true ;
75+ for s in sides :
76+ if s .plane .distance_to (vertex ) > 0.01 :
77+ valid = false ;
78+ break ;
79+ if not valid : continue ;
80+
81+ var vhash := hash (Vector3i (vertex ));
82+ side_verts [i ][vhash ] = vertex ;
83+ side_verts [j ][vhash ] = vertex ;
84+ side_verts [k ][vhash ] = vertex ;
4485
45- var ihash := hash ( d );
46- var is_intersection_defined : bool = ihash in intersections ;
86+ for i in range ( n ):
87+ if sides [ i ]. vertices . size () > 0 : continue ;
4788
48- if is_intersection_defined :
49- return intersections [ihash ];
50- else :
51- var vertex : Variant = side .plane .intersect_3 (side2 .plane , side3 .plane );
52- intersections [ihash ] = vertex ;
53- return vertex ;
89+ var raw : Array = side_verts [i ].values ();
90+ var side_normal := sides [i ].plane .normal ;
91+ var pp := sides [i ].plane_points ;
92+ var center := (pp [0 ] + pp [1 ] + pp [2 ]) / 3.0 ;
93+ var sorter := VMFVectorSorter .new (side_normal , center );
94+ raw .sort_custom (sorter .sort );
95+ sides [i ].vertices = PackedVector3Array (raw );
0 commit comments