1 //**************************************************************************
3 //** ## ## ## ## ## #### #### ### ###
4 //** ## ## ## ## ## ## ## ## ## ## #### ####
5 //** ## ## ## ## ## ## ## ## ## ## ## ## ## ##
6 //** ## ## ######## ## ## ## ## ## ## ## ### ##
7 //** ### ## ## ### ## ## ## ## ## ##
8 //** # ## ## # #### #### ## ##
10 //** Copyright (C) 1999-2006 Jānis Legzdiņš
11 //** Copyright (C) 2018-2023 Ketmar Dark
13 //** This program is free software: you can redistribute it and/or modify
14 //** it under the terms of the GNU General Public License as published by
15 //** the Free Software Foundation, version 3 of the License ONLY.
17 //** This program is distributed in the hope that it will be useful,
18 //** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 //** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 //** GNU General Public License for more details.
22 //** You should have received a copy of the GNU General Public License
23 //** along with this program. If not, see <http://www.gnu.org/licenses/>.
25 //**************************************************************************
28 // we have to include it first, so map implementation will see our `GetTypeHash()`
29 #include "../../libs/core/hash/hashfunc.h"
31 struct __attribute__((packed
)) VectorInfo
{
34 unsigned lidx
; // linedef index
37 inline bool operator == (const VectorInfo
&vi
) const noexcept
{ return (memcmp(xy
, &vi
.xy
, sizeof(xy
)) == 0); }
38 inline bool operator != (const VectorInfo
&vi
) const noexcept
{ return (memcmp(xy
, &vi
.xy
, sizeof(xy
)) != 0); }
40 static_assert(sizeof(VectorInfo
) == sizeof(float)*2+sizeof(unsigned)*1+sizeof(void *), "oops");
42 static inline uint32_t GetTypeHash (const VectorInfo
&vi
) noexcept
{ return joaatHashBuf(vi
.xy
, sizeof(vi
.xy
)); }
45 // ////////////////////////////////////////////////////////////////////////// //
46 #include "../gamedefs.h"
49 //==========================================================================
51 // VLevel::BuildDecalsVVList
53 // build v1 and v2 lists (for decals)
55 //==========================================================================
56 void VLevel::BuildDecalsVVList () {
57 if (NumLines
< 1) return; // just in case
59 // build hashes and lists
60 TMapNC
<VectorInfo
, unsigned> vmap
; // value: index in in tarray
61 TArray
<VectorInfo
> va
;
62 va
.setLength(NumLines
*2);
64 for (unsigned i
= 0; i
< (unsigned)NumLines
; ++i
, ++ld
) {
65 ld
->v1linesCount
= ld
->v2linesCount
= 0;
66 ld
->v1lines
= ld
->v2lines
= nullptr;
67 for (unsigned vn
= 0; vn
< 2; ++vn
) {
68 const unsigned aidx
= i
*2+vn
;
69 VectorInfo
*vi
= &va
[aidx
];
70 const TVec
*vertex
= (vn
== 0 ? ld
->v1
: ld
->v2
);
71 vi
->xy
[0] = vertex
->x
;
72 vi
->xy
[1] = vertex
->y
;
76 auto vaidxp
= vmap
.get(*vi
);
78 //vassert(*vaidxp != vi->aidx);
79 VectorInfo
*cv
= &va
[*vaidxp
];
81 //vassert(cv->aidx < aidx);
82 if (*cv
!= *vi
) Sys_Error("VLevel::BuildDecalsVVList: OOPS(0)!");
85 if (*cv
!= *vi
) Sys_Error("VLevel::BuildDecalsVVList: OOPS(1)!");
88 vmap
.put(*vi
, /*vi->*/aidx
);
93 TArray
<line_t
*> wklist
;
94 wklist
.setLength(NumLines
*2);
97 wkhit
.setLength(NumLines
);
101 for (unsigned i
= 0; i
< (unsigned)NumLines
; ++i
, ++ld
) {
102 for (unsigned vn
= 0; vn
< 2; ++vn
) {
103 memset(wkhit
.ptr(), 0, wkhit
.length()*sizeof(wkhit
.ptr()[0]));
107 VectorInfo
*vi
= &va
[i
*2+vn
];
108 auto vaidxp
= vmap
.get(*vi
);
109 if (!vaidxp
) Sys_Error("VLevel::BuildDecalsVVList: internal error (0)");
110 VectorInfo
*cv
= &va
[*vaidxp
];
112 if (!wkhit
[cv
->lidx
]) {
113 if (*cv
!= *vi
) Sys_Error("VLevel::BuildDecalsVVList: OOPS(2)!");
115 wklist
[count
++] = &Lines
[cv
->lidx
];
121 line_t
**list
= new line_t
*[count
];
122 memcpy(list
, wklist
.ptr(), count
*sizeof(line_t
*));
124 ld
->v1linesCount
= count
;
127 ld
->v2linesCount
= count
;
136 //==========================================================================
138 // VLevel::PostProcessForDecals
140 //==========================================================================
141 void VLevel::PostProcessForDecals () {
142 GCon
->Logf(NAME_Dev
, "postprocessing level for faster decals");
144 for (auto &&line
: allLines()) line
.firstseg
= nullptr;
146 GCon
->Logf(NAME_Dev
, "postprocessing level for faster decals: assigning segs");
147 // collect segments, so we won't go thru the all segs in decal spawner
148 for (auto &&seg
: allSegs()) {
149 line_t
*li
= seg
.linedef
;
151 //seg.lsnext = li->firstseg;
152 //li->firstseg = &seg;
153 seg_t
*cs
= li
->firstseg
;
155 while (cs
->lsnext
) cs
= cs
->lsnext
;