Use enumerated_array for unique_side::uvls

This commit is contained in:
Kp 2022-01-15 20:39:10 +00:00
parent 075495aa8b
commit 636e1b6d5e
17 changed files with 210 additions and 189 deletions

View file

@ -18,8 +18,8 @@ extern imsegptridx_t Cursegp; // Pointer to current segment in the mine, the
#define New_segment (Segments.back())
extern sidenum_t Curside; // Side index in 0..MAX_SIDES_PER_SEGMENT of active side.
extern int Curedge; // Current edge on current side, in 0..3
extern int Curvert; // Current vertex on current side, in 0..3
extern side_relative_vertnum Curedge; // Current edge on current side, in 0..3
extern side_relative_vertnum Curvert; // Current vertex on current side, in 0..3
extern sidenum_t AttachSide; // Side on segment to attach
extern int Draw_all_segments; // Set to 1 means draw_world draws all segments in Segments, else draw only connected segments
extern imsegptridx_t Markedsegp; // Marked segment, used in conjunction with *Cursegp to form joints.

View file

@ -46,7 +46,6 @@ DXX_VALPTRIDX_DECLARE_SUBTYPE(dcx::, segment, segnum_t, MAX_SEGMENTS);
namespace dcx {
constexpr std::integral_constant<std::size_t, 8> MAX_VERTICES_PER_SEGMENT{};
constexpr std::integral_constant<std::size_t, 4> MAX_VERTICES_PER_POLY{};
constexpr std::size_t MAX_SEGMENTS_ORIGINAL = 900;
constexpr std::integral_constant<std::size_t, 4 * MAX_SEGMENTS_ORIGINAL> MAX_SEGMENT_VERTICES_ORIGINAL{};
@ -113,8 +112,10 @@ struct unique_side;
struct vertex;
enum class vertnum_t : uint32_t;
enum class side_relative_vertnum : uint8_t;
enum class segment_relative_vertnum : uint8_t;
enum class segment_special : uint8_t;
constexpr constant_xrange<side_relative_vertnum, side_relative_vertnum{0}, side_relative_vertnum{4}> MAX_VERTICES_PER_SIDE{};
}
/* `vertex` has only integer members, so wild reads are unlikely to
@ -147,7 +148,7 @@ struct d_level_shared_vertex_state;
struct d_level_shared_segment_state;
struct d_level_unique_segment_state;
extern const enumerated_array<std::array<segment_relative_vertnum, 4>, MAX_SIDES_PER_SEGMENT, sidenum_t> Side_to_verts; // Side_to_verts[my_side] is list of vertices forming side my_side.
extern const enumerated_array<enumerated_array<segment_relative_vertnum, 4, side_relative_vertnum>, MAX_SIDES_PER_SEGMENT, sidenum_t> Side_to_verts; // Side_to_verts[my_side] is list of vertices forming side my_side.
extern const enumerated_array<sidenum_t, MAX_SIDES_PER_SEGMENT, sidenum_t> Side_opposite; // Side_opposite[my_side] returns side opposite cube from my_side.
void segment_side_wall_tmap_write(PHYSFS_File *fp, const shared_side &sside, const unique_side &uside);

View file

@ -53,7 +53,7 @@ struct vertex_array_list_t : std::array<segment_relative_vertnum, 6> {};
struct vertex_vertnum_pair
{
vertnum_t vertex;
unsigned vertnum;
side_relative_vertnum vertnum;
};
using vertex_vertnum_array_list = std::array<vertex_vertnum_pair, 6>;

View file

@ -62,6 +62,11 @@ static constexpr sidenum_t &operator++(sidenum_t &a)
return a = static_cast<sidenum_t>(static_cast<unsigned>(a) + 1);
}
static constexpr side_relative_vertnum &operator++(side_relative_vertnum &a)
{
return a = static_cast<side_relative_vertnum>(static_cast<uint8_t>(a) + 1);
}
//Structure for storing u,v,light values.
//NOTE: this structure should be the same as the one in 3d.h
struct uvl
@ -76,6 +81,14 @@ enum class side_type : uint8_t
tri_13 = 3, // render side as two triangles, triangulated along edge from 1 to 3
};
enum class side_relative_vertnum : uint8_t
{
_0,
_1,
_2,
_3,
};
enum class segment_relative_vertnum : uint8_t
{
_0,
@ -199,11 +212,17 @@ static constexpr texture2_value build_texture2_value(const texture_index t, cons
#undef TEXTURE2_ROTATION_SHIFT
#undef TEXTURE2_ROTATION_INDEX_MASK
[[nodiscard]]
static constexpr side_relative_vertnum next_side_vertex(const side_relative_vertnum a, unsigned add = 1)
{
return static_cast<side_relative_vertnum>((static_cast<uint8_t>(a) + add) & 3);
}
struct unique_side
{
texture1_value tmap_num;
texture2_value tmap_num2;
std::array<uvl, 4> uvls;
enumerated_array<uvl, 4, side_relative_vertnum> uvls;
};
#ifdef dsx
@ -340,7 +359,7 @@ struct delta_light : prohibit_void_ptr<delta_light>
{
segnum_t segnum;
sidenum_t sidenum;
std::array<ubyte, 4> vert_light;
enumerated_array<uint8_t, 4, side_relative_vertnum> vert_light;
};
// Light at segnum:sidenum casts light on count sides beginning at index (in array Delta_lights)

View file

@ -35,8 +35,8 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
imsegptridx_t Cursegp = segment_none; // Pointer to current segment in mine.
imsegptridx_t Markedsegp = segment_none; // Marked segment, used in conjunction with *Cursegp to form joints.
sidenum_t Curside; // Side index in 0..MAX_SIDES_PER_SEGMENT of active side.
int Curedge; // Current edge on current side, in 0..3
int Curvert; // Current vertex on current side, in 0..3
side_relative_vertnum Curedge; // Current edge on current side, in 0..3
side_relative_vertnum Curvert; // Current vertex on current side, in 0..3
sidenum_t AttachSide = WFRONT; // Side on segment to attach.
sidenum_t Markedside; // Marked side on Markedsegp.

View file

@ -42,15 +42,13 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
// -----------------------------------------------------------------------------
// Return light intensity at an instance of a vertex on a side in a segment.
static fix get_light_intensity(const unique_side &s, const uint_fast32_t vert)
static fix get_light_intensity(const unique_side &s, const side_relative_vertnum vert)
{
Assert(vert <= 3);
return s.uvls[vert].l;
}
static fix get_light_intensity(const unique_segment &segp, const sidenum_t sidenum, const uint_fast32_t vert)
static fix get_light_intensity(const unique_segment &segp, const sidenum_t sidenum, const side_relative_vertnum vert)
{
Assert(sidenum <= MAX_SIDES_PER_SEGMENT);
return get_light_intensity(segp.sides[sidenum], vert);
}
@ -65,14 +63,13 @@ static fix clamp_light_intensity(const fix intensity)
// -----------------------------------------------------------------------------
// Set light intensity at a vertex, saturating in .5 to 15.5
static void set_light_intensity(unique_side &s, const uint_fast32_t vert, const fix intensity)
static void set_light_intensity(unique_side &s, const side_relative_vertnum vert, const fix intensity)
{
Assert(vert <= 3);
s.uvls[vert].l = clamp_light_intensity(intensity);
Update_flags |= UF_WORLD_CHANGED;
}
static void set_light_intensity(unique_segment &segp, const sidenum_t sidenum, const uint_fast32_t vert, const fix intensity)
static void set_light_intensity(unique_segment &segp, const sidenum_t sidenum, const side_relative_vertnum vert, const fix intensity)
{
set_light_intensity(segp.sides[sidenum], vert, intensity);
}
@ -173,24 +170,16 @@ int LightAmbientLighting()
// -----------------------------------------------------------------------------
int LightSelectNextVertex(void)
{
Curvert++;
if (Curvert >= 4)
Curvert = 0;
Curvert = next_side_vertex(Curvert);
Update_flags |= UF_WORLD_CHANGED;
return 1;
}
// -----------------------------------------------------------------------------
int LightSelectNextEdge(void)
{
Curedge++;
if (Curedge >= 4)
Curedge = 0;
Curedge = next_side_vertex(Curedge);
Update_flags |= UF_WORLD_CHANGED;
return 1;
}
@ -203,7 +192,7 @@ int LightCopyIntensity(void)
unique_segment &segp = Cursegp;
intensity = get_light_intensity(segp, Curside, Curvert);
range_for (const int v, xrange(4u))
for (const auto v : MAX_VERTICES_PER_SIDE)
if (v != Curvert)
set_light_intensity(segp, Curside, v, intensity);
@ -220,7 +209,7 @@ int LightCopyIntensitySegment(void)
intensity = get_light_intensity(segp, Curside, Curvert);
for (const auto s : MAX_SIDES_PER_SEGMENT)
range_for (const int v, xrange(4u))
for (const auto v : MAX_VERTICES_PER_SIDE)
if ((s != Curside) || (v != Curvert))
set_light_intensity(segp, s, v, intensity);
@ -249,7 +238,7 @@ int LightIncreaseLightVertex(void)
int LightDecreaseLightSide(void)
{
unique_segment &segp = Cursegp;
range_for (const int v, xrange(4u))
for (const auto v : MAX_VERTICES_PER_SIDE)
set_light_intensity(segp, Curside, v, get_light_intensity(segp, Curside, v) - F1_0 / NUM_LIGHTING_LEVELS);
return 1;
@ -259,7 +248,7 @@ int LightDecreaseLightSide(void)
int LightIncreaseLightSide(void)
{
unique_segment &segp = Cursegp;
range_for (const int v, xrange(4u))
for (const auto v : MAX_VERTICES_PER_SIDE)
set_light_intensity(segp, Curside, v, get_light_intensity(segp, Curside, v) + F1_0 / NUM_LIGHTING_LEVELS);
return 1;
@ -270,7 +259,7 @@ int LightDecreaseLightSegment(void)
{
unique_segment &segp = Cursegp;
for (const auto s : MAX_SIDES_PER_SEGMENT)
range_for (const int v, xrange(4u))
for (const auto v : MAX_VERTICES_PER_SIDE)
set_light_intensity(segp, s, v, get_light_intensity(segp, s, v) - F1_0 / NUM_LIGHTING_LEVELS);
return 1;
@ -281,7 +270,7 @@ int LightIncreaseLightSegment(void)
{
unique_segment &segp = Cursegp;
for (const auto s : MAX_SIDES_PER_SEGMENT)
range_for (const int v, xrange(4u))
for (const auto v : MAX_VERTICES_PER_SIDE)
set_light_intensity(segp, s, v, get_light_intensity(segp, s, v) + F1_0 / NUM_LIGHTING_LEVELS);
return 1;
@ -291,7 +280,7 @@ int LightIncreaseLightSegment(void)
int LightSetDefault(void)
{
unique_segment &segp = Cursegp;
range_for (const int v, xrange(4u))
for (const auto v : MAX_VERTICES_PER_SIDE)
set_light_intensity(segp, Curside, v, DEFAULT_LIGHTING);
return 1;
@ -302,7 +291,7 @@ int LightSetDefault(void)
int LightSetMaximum(void)
{
unique_segment &segp = Cursegp;
range_for (const int v, xrange(4u))
for (const auto v : MAX_VERTICES_PER_SIDE)
set_light_intensity(segp, Curside, v, (NUM_LIGHTING_LEVELS - 1) * F1_0 / NUM_LIGHTING_LEVELS);
return 1;

View file

@ -119,7 +119,7 @@ static void scale_vert(const shared_segment &sp, const vertnum_t vertex_ind, con
auto &sv = Side_to_verts[Curside];
const auto edge = Curedge;
range_for (const int v, xrange(2u))
if (verts[sv[(edge + v) % 4]] == vertex_ind)
if (verts[sv[next_side_vertex(edge, v)]] == vertex_ind)
scale_vert_aux(vertex_ind, vp, scale_factor);
break;
}
@ -186,7 +186,7 @@ static void med_scale_segment_new(const shared_segment &sp, const int dimension,
// ------------------------------------------------------------------------------------------
// Extract a vector from a segment. The vector goes from the start face to the end face.
// The point on each face is the average of the four points forming the face.
static void extract_vector_from_segment_side(const shared_segment &sp, const sidenum_t side, vms_vector &vp, const unsigned vla, const unsigned vlb, const unsigned vra, const unsigned vrb)
static void extract_vector_from_segment_side(const shared_segment &sp, const sidenum_t side, vms_vector &vp, const side_relative_vertnum vla, const side_relative_vertnum vlb, const side_relative_vertnum vra, const side_relative_vertnum vrb)
{
auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
auto &Vertices = LevelSharedVertexState.get_vertices();
@ -207,7 +207,7 @@ static void extract_vector_from_segment_side(const shared_segment &sp, const sid
// to the center of the right face of the segment.
void med_extract_right_vector_from_segment_side(const shared_segment &sp, const sidenum_t sidenum, vms_vector &vp)
{
extract_vector_from_segment_side(sp, sidenum, vp, 3, 2, 0, 1);
extract_vector_from_segment_side(sp, sidenum, vp, side_relative_vertnum::_3, side_relative_vertnum::_2, side_relative_vertnum::_0, side_relative_vertnum::_1);
}
// ------------------------------------------------------------------------------------------
@ -216,7 +216,7 @@ void med_extract_right_vector_from_segment_side(const shared_segment &sp, const
// to the center of the top face of the segment.
void med_extract_up_vector_from_segment_side(const shared_segment &sp, const sidenum_t sidenum, vms_vector &vp)
{
extract_vector_from_segment_side(sp, sidenum, vp, 1, 2, 0, 3);
extract_vector_from_segment_side(sp, sidenum, vp, side_relative_vertnum::_1, side_relative_vertnum::_2, side_relative_vertnum::_0, side_relative_vertnum::_3);
}
namespace {

View file

@ -95,6 +95,7 @@ COPYRIGHT 1993-1998 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
#include "compiler-range_for.h"
#include "d_levelstate.h"
#include "d_zip.h"
//#define _MARK_ON 1
//#include <wsample.h> //should come after inferno.h to get mark setting //Not included here.
@ -536,7 +537,7 @@ static void move_player_2_segment_and_rotate(const vmsegptridx_t seg, const unsi
auto &Objects = LevelUniqueObjectState.Objects;
auto &vmobjptr = Objects.vmptr;
auto &vmobjptridx = Objects.vmptridx;
static int edgenum=0;
static side_relative_vertnum edgenum;
auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
auto &Vertices = LevelSharedVertexState.get_vertices();
@ -547,8 +548,8 @@ static void move_player_2_segment_and_rotate(const vmsegptridx_t seg, const unsi
auto &sv = Side_to_verts[Curside];
auto &verts = Cursegp->verts;
const auto upvec = vm_vec_sub(vcvertptr(verts[sv[edgenum % 4]]), vcvertptr(verts[sv[(edgenum + 3) % 4]]));
edgenum++;
const auto en = std::exchange(edgenum, next_side_vertex(edgenum));
const auto upvec = vm_vec_sub(vcvertptr(verts[sv[en]]), vcvertptr(verts[sv[next_side_vertex(en, 3)]]));
vm_vector_2_matrix(ConsoleObject->orient,vp,&upvec,nullptr);
// vm_vector_2_matrix(&ConsoleObject->orient,&vp,NULL,NULL);
@ -563,7 +564,6 @@ int SetPlayerFromCursegAndRotate()
return 1;
}
//sets the player facing curseg/curside, normal to face0 of curside, and
//far enough away to see all of curside
int SetPlayerFromCursegMinusOne()
@ -573,7 +573,7 @@ int SetPlayerFromCursegMinusOne()
auto &vmobjptridx = Objects.vmptridx;
std::array<g3s_point, 4> corner_p;
fix max,view_dist=f1_0*10;
static int edgenum=0;
static side_relative_vertnum edgenum;
const auto view_vec = vm_vec_negated(Cursegp->shared_segment::sides[Curside].normals[0]);
auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
@ -585,8 +585,8 @@ int SetPlayerFromCursegMinusOne()
auto &sv = Side_to_verts[Curside];
auto &verts = Cursegp->verts;
const auto upvec = vm_vec_sub(vcvertptr(verts[sv[edgenum % 4]]), vcvertptr(verts[sv[(edgenum + 3) % 4]]));
edgenum++;
const auto en = std::exchange(edgenum, next_side_vertex(edgenum));
const auto upvec = vm_vec_sub(vcvertptr(verts[sv[en]]), vcvertptr(verts[sv[next_side_vertex(en, 3)]]));
vm_vector_2_matrix(ConsoleObject->orient,view_vec,&upvec,nullptr);
@ -594,11 +594,12 @@ int SetPlayerFromCursegMinusOne()
g3_start_frame(*grd_curcanv);
g3_set_view_matrix(ConsoleObject->pos,ConsoleObject->orient,Render_zoom);
for (unsigned i = max = 0; i < 4; ++i)
max = 0;
for (auto &&[corner, vert] : zip(corner_p, sv))
{
g3_rotate_point(corner_p[i], vcvertptr(verts[sv[i]]));
if (labs(corner_p[i].p3_x) > max) max = labs(corner_p[i].p3_x);
if (labs(corner_p[i].p3_y) > max) max = labs(corner_p[i].p3_y);
g3_rotate_point(corner, vcvertptr(verts[vert]));
if (labs(corner.p3_x) > max) max = labs(corner.p3_x);
if (labs(corner.p3_y) > max) max = labs(corner.p3_y);
}
view_dist = fixmul(view_dist,fixdiv(fixdiv(max,SIDE_VIEW_FRAC),corner_p[0].p3_z));

View file

@ -166,13 +166,13 @@ static void check_segment(const vmsegptridx_t seg)
range_for (auto &fn, Side_to_verts)
{
std::array<cg3s_point *, 3> vert_list;
vert_list[0] = &Segment_points[seg->verts[fn[0]]];
vert_list[1] = &Segment_points[seg->verts[fn[1]]];
vert_list[2] = &Segment_points[seg->verts[fn[2]]];
vert_list[0] = &Segment_points[seg->verts[fn[side_relative_vertnum::_0]]];
vert_list[1] = &Segment_points[seg->verts[fn[side_relative_vertnum::_1]]];
vert_list[2] = &Segment_points[seg->verts[fn[side_relative_vertnum::_2]]];
g3_check_and_draw_poly(*grd_curcanv, vert_list, color);
vert_list[1] = &Segment_points[seg->verts[fn[2]]];
vert_list[2] = &Segment_points[seg->verts[fn[3]]];
vert_list[1] = &Segment_points[seg->verts[fn[side_relative_vertnum::_2]]];
vert_list[2] = &Segment_points[seg->verts[fn[side_relative_vertnum::_3]]];
g3_check_and_draw_poly(*grd_curcanv, vert_list, color);
}
}
@ -193,17 +193,13 @@ static void draw_seg_side(const shared_segment &seg, const sidenum_t side, const
auto &vcvertptr = Vertices.vcptr;
if (!rotate_list(vcvertptr, svp).uand)
{ //all off screen?
int i;
auto &stv = Side_to_verts[side];
for (i=0;i<3;i++)
draw_line(*grd_curcanv, svp[stv[i]], svp[stv[i+1]], color);
draw_line(*grd_curcanv, svp[stv[i]], svp[stv[0]], color);
for (const auto i : MAX_VERTICES_PER_SIDE)
draw_line(*grd_curcanv, svp[stv[i]], svp[stv[next_side_vertex(i)]], color);
}
}
static void draw_side_edge(const shared_segment &seg, const sidenum_t side, const unsigned edge, const color_palette_index color)
static void draw_side_edge(const shared_segment &seg, const sidenum_t side, const side_relative_vertnum edge, const color_palette_index color)
{
auto &svp = seg.verts;
auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
@ -212,7 +208,7 @@ static void draw_side_edge(const shared_segment &seg, const sidenum_t side, cons
if (!rotate_list(vcvertptr, svp).uand) //on screen?
{
auto &stv = Side_to_verts[side];
draw_line(*grd_curcanv, svp[stv[edge]], svp[stv[(edge + 1) % 4]], color);
draw_line(*grd_curcanv, svp[stv[edge]], svp[stv[next_side_vertex(edge)]], color);
}
}
@ -409,7 +405,7 @@ static void draw_trigger_side(const shared_segment &seg, const sidenum_t side, c
{ //all off screen?
// Draw diagonals
auto &stv = Side_to_verts[side];
draw_line(*grd_curcanv, svp[stv[0]], svp[stv[2]], color);
draw_line(*grd_curcanv, svp[stv[side_relative_vertnum::_0]], svp[stv[side_relative_vertnum::_2]], color);
}
}
@ -424,8 +420,8 @@ static void draw_wall_side(const shared_segment &seg, const sidenum_t side, cons
{ //all off screen?
// Draw diagonals
auto &stv = Side_to_verts[side];
draw_line(*grd_curcanv, svp[stv[0]], svp[stv[2]], color);
draw_line(*grd_curcanv, svp[stv[1]], svp[stv[3]], color);
draw_line(*grd_curcanv, svp[stv[side_relative_vertnum::_0]], svp[stv[side_relative_vertnum::_2]], color);
draw_line(*grd_curcanv, svp[stv[side_relative_vertnum::_1]], svp[stv[side_relative_vertnum::_3]], color);
}
}

View file

@ -1058,9 +1058,9 @@ static fix seg_seg_vertex_distsum(const shared_segment &seg1, const sidenum_t si
distsum = 0;
auto &vcvertptr = Vertices.vcptr;
range_for (const unsigned secondv, xrange(4u))
for (const auto secondv : MAX_VERTICES_PER_SIDE)
{
const unsigned firstv = (4 - secondv + (3 - firstv1)) % 4;
const auto firstv = static_cast<side_relative_vertnum>((4 - underlying_value(secondv) + (3 - firstv1)) % 4);
distsum += vm_vec_dist(vcvertptr(seg1.verts[Side_to_verts[side1][firstv]]),vcvertptr(seg2.verts[Side_to_verts[side2][secondv]]));
}
@ -1142,8 +1142,8 @@ int med_form_joint(const vmsegptridx_t seg1, const sidenum_t side1, const vmsegp
lv = seg2->verts[vi];
// Now, for each vertex in lost_vertices, determine which vertex it maps to.
for (const unsigned v : xrange(4u))
remap_vertices[3 - ((v + bfi) % 4)] = seg1->verts[vp1[v]];
for (const auto v : MAX_VERTICES_PER_SIDE)
remap_vertices[3 - ((underlying_value(v) + bfi) % 4)] = seg1->verts[vp1[v]];
// Now, in all segments, replace all occurrences of vertices in lost_vertices with remap_vertices
@ -1213,8 +1213,8 @@ int med_form_bridge_segment(const vmsegptridx_t seg1, const sidenum_t side1, con
// Copy vertices from seg2 into last 4 vertices of bridge segment.
{
auto &sv = Side_to_verts[side2];
for (const auto v : xrange(4u))
sbs.verts[(segment_relative_vertnum{static_cast<uint8_t>((3 - v) + 4)})] = seg2->verts[sv[v]];
for (const auto v : MAX_VERTICES_PER_SIDE)
sbs.verts[(segment_relative_vertnum{static_cast<uint8_t>((3 - underlying_value(v)) + 4)})] = seg2->verts[sv[v]];
}
// Copy vertices from seg1 into first 4 vertices of bridge segment.
@ -1222,8 +1222,8 @@ int med_form_bridge_segment(const vmsegptridx_t seg1, const sidenum_t side1, con
{
auto &sv = Side_to_verts[side1];
for (const auto v : xrange(4u))
bs->verts[(segment_relative_vertnum{static_cast<uint8_t>((v + bfi) % 4)})] = seg1->verts[sv[v]];
for (const auto v : MAX_VERTICES_PER_SIDE)
bs->verts[(segment_relative_vertnum{static_cast<uint8_t>((underlying_value(v) + bfi) % 4)})] = seg1->verts[sv[v]];
}
// Form connections to children, first initialize all to unconnected.
@ -1458,9 +1458,9 @@ static int check_seg_concavity(const shared_segment &s)
for (unsigned vn = 0; vn <= 4; ++vn)
{
const auto n1 = vm_vec_normal(
vcvertptr(s.verts[sn[vn % 4]]),
vcvertptr(s.verts[sn[(vn + 1) % 4]]),
vcvertptr(s.verts[sn[(vn + 2) % 4]]));
vcvertptr(s.verts[sn[static_cast<side_relative_vertnum>(vn % 4)]]),
vcvertptr(s.verts[sn[static_cast<side_relative_vertnum>((vn + 1) % 4)]]),
vcvertptr(s.verts[sn[static_cast<side_relative_vertnum>((vn + 2) % 4)]]));
//vm_vec_normalize(&n1);
@ -1522,10 +1522,10 @@ void warn_if_concave_segment(const vmsegptridx_t s)
// If not found, return an empty optional.
std::optional<std::pair<vmsegptridx_t, sidenum_t>> med_find_adjacent_segment_side(const vmsegptridx_t sp, sidenum_t side)
{
std::array<vertnum_t, 4> abs_verts;
enumerated_array<vertnum_t, 4, side_relative_vertnum> abs_verts;
// Stuff abs_verts[4] array with absolute vertex indices
range_for (const unsigned v, xrange(4u))
for (const auto v : MAX_VERTICES_PER_SIDE)
abs_verts[v] = sp->verts[Side_to_verts[side][v]];
// Scan all segments, looking for a segment which contains the four abs_verts

View file

@ -96,7 +96,7 @@ static fix get_average_light_at_vertex(const vertnum_t vnum, segnum_t *segs)
const auto vi = std::find(vb, ve, relvnum);
if (vi != ve)
{
const auto v = std::distance(vb, vi);
const auto v = static_cast<side_relative_vertnum>(std::distance(vb, vi));
total_light += uside.uvls[v].l;
num_occurrences++;
}
@ -145,7 +145,7 @@ static void set_average_light_at_vertex(vertnum_t vnum)
const auto vi = std::find(vb, ve, relvnum);
if (vi != ve)
{
const auto v = std::distance(vb, vi);
const auto v = static_cast<side_relative_vertnum>(std::distance(vb, vi));
sidep.uvls[v].l = average_light;
}
} // end if
@ -301,20 +301,26 @@ namespace {
// (Actually, assign them to the coordinates in the faces.)
// va, vb = face-relative vertex indices corresponding to uva, uvb. Ie, they are always in 0..3 and should be looked up in
// Side_to_verts[side] to get the segment relative index.
static void assign_uvs_to_side(fvcvertptr &vcvertptr, const vmsegptridx_t segp, const sidenum_t sidenum, const uvl &uva, const uvl &uvb, int va, int vb)
static void assign_uvs_to_side(fvcvertptr &vcvertptr, const vmsegptridx_t segp, const sidenum_t sidenum, const uvl &uva, const uvl &uvb, const side_relative_vertnum va, const side_relative_vertnum vb)
{
int vlo,vhi;
std::array<uvl, 4> uvls;
uvl ruvmag,fuvmag;
const uvl *uvlo, *uvhi;
fix fmag,mag01;
Assert( (va<4) && (vb<4) );
Assert((abs(va - vb) == 1) || (abs(va - vb) == 3)); // make sure the verticies specify an edge
#ifndef NDEBUG
{
const auto distance_between_side_vertices = underlying_value(va) - underlying_value(vb);
const auto abs_distance_between_side_vertices = std::abs(distance_between_side_vertices);
// make sure the vertices specify an edge
assert(abs_distance_between_side_vertices == 1 || abs_distance_between_side_vertices == 3);
}
#endif
auto &vp = Side_to_verts[sidenum];
side_relative_vertnum vlo, vhi;
// We want vlo precedes vhi, ie vlo < vhi, or vlo = 3, vhi = 0
if (va == ((vb + 1) % 4)) { // va = vb + 1
if (va == next_side_vertex(vb))
{ // va = vb + 1
vlo = vb;
vhi = va;
uvlo = &uvb;
@ -326,7 +332,8 @@ static void assign_uvs_to_side(fvcvertptr &vcvertptr, const vmsegptridx_t segp,
uvhi = &uvb;
}
Assert(((vlo+1) % 4) == vhi); // If we are on an edge, then uvhi is one more than uvlo (mod 4)
assert(next_side_vertex(vlo) == vhi); // If we are on an edge, then uvhi is one more than uvlo (mod 4)
enumerated_array<uvl, 4, side_relative_vertnum> uvls;
uvls[vlo] = *uvlo;
uvls[vhi] = *uvhi;
@ -349,8 +356,10 @@ static void assign_uvs_to_side(fvcvertptr &vcvertptr, const vmsegptridx_t segp,
const auto v0 = segp->verts[vp[vlo]];
const auto v1 = segp->verts[vp[vhi]];
const auto v2 = segp->verts[vp[(vhi+1)%4]];
const auto v3 = segp->verts[vp[(vhi+2)%4]];
const auto vhi1 = next_side_vertex(vhi);
const auto vhi2 = next_side_vertex(vhi, 2);
const auto v2 = segp->verts[vp[vhi1]];
const auto v3 = segp->verts[vp[vhi2]];
// Compute right vector by computing orientation matrix from:
// forward vector = vlo:vhi
@ -358,10 +367,10 @@ static void assign_uvs_to_side(fvcvertptr &vcvertptr, const vmsegptridx_t segp,
const auto &&vp0 = vcvertptr(v0);
const auto &vv1v0 = vm_vec_sub(vcvertptr(v1), vp0);
mag01 = vm_vec_mag(vv1v0);
mag01 = fixmul(mag01, (va == 0 || va == 2) ? Stretch_scale_x : Stretch_scale_y);
mag01 = fixmul(mag01, (va == side_relative_vertnum::_0 || va == side_relative_vertnum::_2) ? Stretch_scale_x : Stretch_scale_y);
if (unlikely(mag01 < F1_0/1024))
editor_status_fmt("U, V bogosity in segment #%hu, probably on side #%i. CLEAN UP YOUR MESS!", static_cast<uint16_t>(segp), sidenum);
editor_status_fmt("U, V bogosity in segment #%hu, probably on side #%i. CLEAN UP YOUR MESS!", segp.get_unchecked_index(), sidenum);
else {
struct frvec {
vms_vector fvec, rvec;
@ -399,8 +408,8 @@ static void assign_uvs_to_side(fvcvertptr &vcvertptr, const vmsegptridx_t segp,
uvi.l
};
};
uvls[(vhi + 1) % 4] = build_uvl(vm_vec_sub(vcvertptr(v2), vcvertptr(v1)), *uvhi);
uvls[(vhi + 2) % 4] = build_uvl(vv3v0, *uvlo);
uvls[vhi1] = build_uvl(vm_vec_sub(vcvertptr(v2), vcvertptr(v1)), *uvhi);
uvls[vhi2] = build_uvl(vv3v0, *uvlo);
// For all faces in side, copy uv coordinates from uvs array to face.
segp->unique_segment::sides[sidenum].uvls = uvls;
}
@ -429,9 +438,9 @@ void assign_default_uvs_to_side(const vmsegptridx_t segp, const sidenum_t side)
auto &vp = Side_to_verts[side];
uv1.u = 0;
auto &vcvertptr = Vertices.vcptr;
uv1.v = Num_tilings * fixmul(Vmag, vm_vec_dist(vcvertptr(segp->verts[vp[1]]), vcvertptr(segp->verts[vp[0]])));
uv1.v = Num_tilings * fixmul(Vmag, vm_vec_dist(vcvertptr(segp->verts[vp[side_relative_vertnum::_1]]), vcvertptr(segp->verts[vp[side_relative_vertnum::_0]])));
assign_uvs_to_side(vcvertptr, segp, side, uv0, uv1, 0, 1);
assign_uvs_to_side(vcvertptr, segp, side, uv0, uv1, side_relative_vertnum::_0, side_relative_vertnum::_1);
}
// -----------------------------------------------------------------------------------------------------------
@ -445,12 +454,11 @@ void stretch_uvs_from_curedge(const vmsegptridx_t segp, const sidenum_t side)
auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
auto &Vertices = LevelSharedVertexState.get_vertices();
uvl uv0,uv1;
int v0, v1;
v0 = Curedge;
v1 = (v0 + 1) % 4;
const auto v0 = Curedge;
const auto v1 = next_side_vertex(v0);
auto &uvls = segp->unique_segment::sides[side].uvls;
const auto &uvls = segp->unique_segment::sides[side].uvls;
uv0.u = uvls[v0].u;
uv0.v = uvls[v0].v;
@ -570,7 +578,6 @@ static void med_assign_uvs_to_side(const vmsegptridx_t con_seg, const sidenum_t
{
auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
auto &Vertices = LevelSharedVertexState.get_vertices();
int vv1, vv2;
constexpr segment_relative_vertnum invalid_vertnum{0xff};
segment_relative_vertnum cv1 = invalid_vertnum, cv2 = invalid_vertnum;
segment_relative_vertnum bv1 = invalid_vertnum, bv2 = invalid_vertnum;
@ -599,7 +606,7 @@ static void med_assign_uvs_to_side(const vmsegptridx_t con_seg, const sidenum_t
// Now, scan 4 vertices in base side and 4 vertices in connected side.
// Set uv1, uv2 to uv coordinates from base side which correspond to vertices bv1, bv2.
// Set vv1, vv2 to relative vertex ids (in 0..3) in connecting side which correspond to cv1, cv2
vv1 = -1; vv2 = -1;
std::optional<side_relative_vertnum> vv1, vv2;
auto &base_uvls = base_seg.u.sides[base_common_side].uvls;
const uvl *uv1 = nullptr, *uv2 = nullptr;
auto &svbase = Side_to_verts[base_common_side];
@ -617,9 +624,9 @@ static void med_assign_uvs_to_side(const vmsegptridx_t con_seg, const sidenum_t
}
assert(uv1->u != uv2->u || uv1->v != uv2->v);
Assert( (vv1 != -1) && (vv2 != -1) );
assert(vv1.has_value() && vv2.has_value());
auto &vcvertptr = Vertices.vcptr;
assign_uvs_to_side(vcvertptr, con_seg, con_common_side, *uv1, *uv2, vv1, vv2);
assign_uvs_to_side(vcvertptr, con_seg, con_common_side, *uv1, *uv2, *vv1, *vv2);
}
@ -640,11 +647,13 @@ static std::pair<sidenum_t, sidenum_t> get_side_ids(const shared_segment &base_s
for (const auto &&[idx, base_vp] : enumerate(Side_to_verts))
{
if (idx != base_side) {
for (const auto v0 : xrange(4u))
for (const auto v0 : MAX_VERTICES_PER_SIDE)
{
auto &verts = base_seg.verts;
if ((verts[base_vp[v0]] == abs_id1 && verts[base_vp[(v0+1) % 4]] == abs_id2) ||
(verts[base_vp[v0]] == abs_id2 && verts[base_vp[ (v0+1) % 4]] == abs_id1))
const auto candidate_abs_v0 = verts[base_vp[v0]];
const auto candidate_abs_v1 = verts[base_vp[next_side_vertex(v0)]];
if ((candidate_abs_v0 == abs_id1 && candidate_abs_v1 == abs_id2) ||
(candidate_abs_v0 == abs_id2 && candidate_abs_v1 == abs_id1))
{
assert(!base_common_side); // This means two different sides shared the same edge with base_side == impossible!
base_common_side = idx;
@ -660,11 +669,13 @@ static std::pair<sidenum_t, sidenum_t> get_side_ids(const shared_segment &base_s
for (const auto &&[idx, con_vp] : enumerate(Side_to_verts))
{
if (idx != con_side) {
for (const auto v0 : xrange(4u))
for (const auto v0 : MAX_VERTICES_PER_SIDE)
{
auto &verts = con_seg.verts;
if ((verts[con_vp[(v0 + 1) % 4]] == abs_id1 && verts[con_vp[v0]] == abs_id2) ||
(verts[con_vp[(v0 + 1) % 4]] == abs_id2 && verts[con_vp[v0]] == abs_id1))
const auto candidate_abs_v0 = verts[con_vp[next_side_vertex(v0)]];
const auto candidate_abs_v1 = verts[con_vp[v0]];
if ((candidate_abs_v0 == abs_id1 && candidate_abs_v1 == abs_id2) ||
(candidate_abs_v0 == abs_id2 && candidate_abs_v1 == abs_id1))
{
assert(!con_common_side); // This means two different sides shared the same edge with con_side == impossible!
con_common_side = idx;
@ -783,7 +794,7 @@ namespace {
static void fix_bogus_uvs_on_side1(const vmsegptridx_t sp, const sidenum_t sidenum, const int uvonly_flag)
{
auto &uvls = sp->unique_segment::sides[sidenum].uvls;
if (uvls[0].u == 0 && uvls[1].u == 0 && uvls[2].u == 0)
if (uvls[side_relative_vertnum::_0].u == 0 && uvls[side_relative_vertnum::_1].u == 0 && uvls[side_relative_vertnum::_2].u == 0)
{
med_propagate_tmaps_to_back_side(sp, static_cast<sidenum_t>(sidenum), uvonly_flag);
}
@ -820,17 +831,15 @@ namespace {
// segment to get the wall in the connected segment which shares the edge, and get tmap_num from there.
static void propagate_tmaps_to_segment_sides(const vcsegptridx_t base_seg, const sidenum_t base_side, const vmsegptridx_t con_seg, const sidenum_t con_side, const int uv_only_flag)
{
int v;
auto &base_vp = Side_to_verts[base_side];
// Do for each edge on connecting face.
for (v=0; v<4; v++) {
for (const auto v : MAX_VERTICES_PER_SIDE)
{
const auto abs_id1 = base_seg->verts[base_vp[v]];
const auto abs_id2 = base_seg->verts[base_vp[(v + 1) % 4]];
const auto abs_id2 = base_seg->verts[base_vp[next_side_vertex(v)]];
propagate_tmaps_to_segment_side(base_seg, base_side, con_seg, con_side, abs_id1, abs_id2, uv_only_flag);
}
}
}
@ -961,7 +970,7 @@ static void cast_light_from_side(const vmsegptridx_t segp, const sidenum_t light
auto &side_normalp = srside.normals[0]; // kinda stupid? always use vector 0.
auto &sv_side = Side_to_verts[static_cast<sidenum_t>(sidenum)];
for (const auto vertnum : xrange(4u))
for (const auto vertnum : MAX_VERTICES_PER_SIDE)
{
const auto segment_relative_vert = sv_side[vertnum];
const auto abs_vertnum = rsegp->verts[segment_relative_vert];

View file

@ -87,13 +87,15 @@ static int DoTexSlideLeft(int value)
auto &uvls = Cursegp->unique_segment::sides[Curside].uvls;
auto &vcvertptr = Vertices.vcptr;
dist = vm_vec_dist(vcvertptr(Cursegp->verts[vp[3]]), vcvertptr(Cursegp->verts[vp[0]]));
dist = vm_vec_dist(vcvertptr(Cursegp->verts[vp[side_relative_vertnum::_3]]), vcvertptr(Cursegp->verts[vp[side_relative_vertnum::_0]]));
dist *= value;
if (dist < F1_0/(64*value))
dist = F1_0/(64*value);
duvl03.u = fixdiv(uvls[3].u - uvls[0].u,dist);
duvl03.v = fixdiv(uvls[3].v - uvls[0].v,dist);
auto &u3 = uvls[side_relative_vertnum::_3];
auto &u0 = uvls[side_relative_vertnum::_0];
duvl03.u = fixdiv(u3.u - u0.u, dist);
duvl03.v = fixdiv(u3.v - u0.v, dist);
range_for (auto &v, uvls)
{
@ -127,14 +129,16 @@ static int DoTexSlideUp(int value)
auto &uvls = Cursegp->unique_segment::sides[Curside].uvls;
auto &vcvertptr = Vertices.vcptr;
dist = vm_vec_dist(vcvertptr(Cursegp->verts[vp[1]]), vcvertptr(Cursegp->verts[vp[0]]));
dist = vm_vec_dist(vcvertptr(Cursegp->verts[vp[side_relative_vertnum::_1]]), vcvertptr(Cursegp->verts[vp[side_relative_vertnum::_0]]));
dist *= value;
if (dist < F1_0/(64*value))
dist = F1_0/(64*value);
duvl03.u = fixdiv(uvls[1].u - uvls[0].u,dist);
duvl03.v = fixdiv(uvls[1].v - uvls[0].v,dist);
auto &u1 = uvls[side_relative_vertnum::_1];
auto &u0 = uvls[side_relative_vertnum::_0];
duvl03.u = fixdiv(u1.u - u0.u, dist);
duvl03.v = fixdiv(u1.v - u0.v, dist);
range_for (auto &v, uvls)
{
@ -169,13 +173,15 @@ static int DoTexSlideDown(int value)
auto &uvls = Cursegp->unique_segment::sides[Curside].uvls;
auto &vcvertptr = Vertices.vcptr;
dist = vm_vec_dist(vcvertptr(Cursegp->verts[vp[1]]), vcvertptr(Cursegp->verts[vp[0]]));
dist = vm_vec_dist(vcvertptr(Cursegp->verts[vp[side_relative_vertnum::_1]]), vcvertptr(Cursegp->verts[vp[side_relative_vertnum::_0]]));
dist *= value;
if (dist < F1_0/(64*value))
dist = F1_0/(64*value);
duvl03.u = fixdiv(uvls[1].u - uvls[0].u,dist);
duvl03.v = fixdiv(uvls[1].v - uvls[0].v,dist);
auto &u1 = uvls[side_relative_vertnum::_1];
auto &u0 = uvls[side_relative_vertnum::_0];
duvl03.u = fixdiv(u1.u - u0.u, dist);
duvl03.v = fixdiv(u1.v - u0.v, dist);
range_for (auto &v, uvls)
{
@ -289,13 +295,15 @@ static int DoTexSlideRight(int value)
auto &uvls = Cursegp->unique_segment::sides[Curside].uvls;
auto &vcvertptr = Vertices.vcptr;
dist = vm_vec_dist(vcvertptr(Cursegp->verts[vp[3]]), vcvertptr(Cursegp->verts[vp[0]]));
dist = vm_vec_dist(vcvertptr(Cursegp->verts[vp[side_relative_vertnum::_3]]), vcvertptr(Cursegp->verts[vp[side_relative_vertnum::_0]]));
dist *= value;
if (dist < F1_0/(64*value))
dist = F1_0/(64*value);
duvl03.u = fixdiv(uvls[3].u - uvls[0].u,dist);
duvl03.v = fixdiv(uvls[3].v - uvls[0].v,dist);
auto &u3 = uvls[side_relative_vertnum::_3];
auto &u0 = uvls[side_relative_vertnum::_0];
duvl03.u = fixdiv(u3.u - u0.u, dist);
duvl03.v = fixdiv(u3.v - u0.v, dist);
range_for (auto &v, uvls)
{
@ -406,12 +414,9 @@ int TexDecreaseTiling()
// direction = -1 or 1 depending on direction
static int TexStretchCommon(int direction)
{
fix *sptr;
if ((Curedge == 0) || (Curedge == 2))
sptr = &Stretch_scale_x;
else
sptr = &Stretch_scale_y;
const auto sptr = (Curedge == side_relative_vertnum::_0 || Curedge == side_relative_vertnum::_2)
? &Stretch_scale_x
: &Stretch_scale_y;
*sptr += direction*F1_0/64;

View file

@ -66,13 +66,13 @@ struct segment_water_depth_array : std::array<uint8_t, MAX_SEGMENTS> {};
class abs_vertex_lists_predicate
{
const enumerated_array<vertnum_t, MAX_VERTICES_PER_SEGMENT, segment_relative_vertnum> &m_vp;
const std::array<segment_relative_vertnum, 4> &m_sv;
const enumerated_array<segment_relative_vertnum, 4, side_relative_vertnum> &m_sv;
public:
abs_vertex_lists_predicate(const shared_segment &seg, const sidenum_t sidenum) :
m_vp(seg.verts), m_sv(Side_to_verts[sidenum])
{
}
vertnum_t operator()(const uint_fast32_t vv) const
vertnum_t operator()(const side_relative_vertnum vv) const
{
return m_vp[m_sv[vv]];
}
@ -82,9 +82,9 @@ class all_vertnum_lists_predicate : public abs_vertex_lists_predicate
{
public:
using abs_vertex_lists_predicate::abs_vertex_lists_predicate;
vertex_vertnum_pair operator()(const uint_fast32_t vv) const
vertex_vertnum_pair operator()(const side_relative_vertnum vv) const
{
return {this->abs_vertex_lists_predicate::operator()(vv), static_cast<unsigned>(vv)};
return {this->abs_vertex_lists_predicate::operator()(vv), vv};
}
};
@ -237,7 +237,7 @@ static uint_fast32_t create_vertex_lists_from_values(T &va, const shared_segment
template <typename T, typename F>
static inline uint_fast32_t create_vertex_lists_by_predicate(T &va, const shared_segment &segp, const shared_side &sidep, const F &&f)
{
return create_vertex_lists_from_values(va, segp, sidep, f(0), f(1), f(2), f(3));
return create_vertex_lists_from_values(va, segp, sidep, f(side_relative_vertnum::_0), f(side_relative_vertnum::_1), f(side_relative_vertnum::_2), f(side_relative_vertnum::_3));
}
}
@ -262,7 +262,7 @@ uint_fast32_t create_all_vertex_lists(vertex_array_list_t &vertices, const share
{
assert(Side_to_verts.valid_index(sidenum));
auto &sv = Side_to_verts[sidenum];
return create_vertex_lists_by_predicate(vertices, segp, sidep, [&sv](const uint_fast32_t vv) {
return create_vertex_lists_by_predicate(vertices, segp, sidep, [&sv](const side_relative_vertnum vv) {
return sv[vv];
});
}
@ -1214,11 +1214,11 @@ static unsigned check_for_degenerate_side(fvcvertptr &vcvertptr, const shared_se
//vm_vec_sub(&vec2, &Vertices[sp->verts[vp[2]]], &Vertices[sp->verts[vp[1]]]);
//vm_vec_normalize(&vec1);
//vm_vec_normalize(&vec2);
const auto vp1 = vp[1];
const auto vp2 = vp[2];
const auto vp1 = vp[side_relative_vertnum::_1];
const auto vp2 = vp[side_relative_vertnum::_2];
auto &vert1 = *vcvertptr(sp.verts[vp1]);
auto &vert2 = *vcvertptr(sp.verts[vp2]);
vm_vec_normalized_dir(vec1, vert1, vcvertptr(sp.verts[vp[0]]));
vm_vec_normalized_dir(vec1, vert1, vcvertptr(sp.verts[vp[side_relative_vertnum::_0]]));
vm_vec_normalized_dir(vec2, vert2, vert1);
const auto cross0 = vm_vec_cross(vec1, vec2);
@ -1231,7 +1231,7 @@ static unsigned check_for_degenerate_side(fvcvertptr &vcvertptr, const shared_se
//vm_vec_normalize(&vec1);
//vm_vec_normalize(&vec2);
vm_vec_normalized_dir(vec1, vert2, vert1);
vm_vec_normalized_dir(vec2, vcvertptr(sp.verts[vp[3]]), vert2);
vm_vec_normalized_dir(vec2, vcvertptr(sp.verts[vp[side_relative_vertnum::_3]]), vert2);
const auto cross1 = vm_vec_cross(vec1, vec2);
dot = vm_vec_dot(vec_to_center, cross1);
@ -1356,10 +1356,10 @@ static void add_side_as_2_triangles(fvcvertptr &vcvertptr, shared_segment &sp, c
if (!IS_CHILD(sp.children[sidenum]))
{
auto &verts = sp.verts;
auto &vvs0 = *vcvertptr(verts[vs[0]]);
auto &vvs1 = *vcvertptr(verts[vs[1]]);
auto &vvs2 = *vcvertptr(verts[vs[2]]);
auto &vvs3 = *vcvertptr(verts[vs[3]]);
auto &vvs0 = *vcvertptr(verts[vs[side_relative_vertnum::_0]]);
auto &vvs1 = *vcvertptr(verts[vs[side_relative_vertnum::_1]]);
auto &vvs2 = *vcvertptr(verts[vs[side_relative_vertnum::_2]]);
auto &vvs3 = *vcvertptr(verts[vs[side_relative_vertnum::_3]]);
const auto &&norm = vm_vec_normal(vvs0, vvs1, vvs2);
const auto &&vec_13 = vm_vec_sub(vvs3, vvs1); // vector from vertex 1 to vertex 3
dot = vm_vec_dot(norm, vec_13);
@ -1372,28 +1372,28 @@ static void add_side_as_2_triangles(fvcvertptr &vcvertptr, shared_segment &sp, c
vm_vec_normal(sidep->normals[0], vvs0, vvs1, *n0v3);
vm_vec_normal(sidep->normals[1], *n1v1, vvs2, vvs3);
} else {
std::array<vertnum_t, 4> v;
enumerated_array<vertnum_t, 4, side_relative_vertnum> v;
range_for (const unsigned i, xrange(4u))
for (const auto i : MAX_VERTICES_PER_SIDE)
v[i] = sp.verts[vs[i]];
verts_for_normal vfn{v[0], v[1], v[2], v[3]};
verts_for_normal vfn{v[side_relative_vertnum::_0], v[side_relative_vertnum::_1], v[side_relative_vertnum::_2], v[side_relative_vertnum::_3]};
get_verts_for_normal(vfn);
vertnum_t s0v2, s1v0;
if ((vfn.vsorted[0] == v[0]) || (vfn.vsorted[0] == v[2])) {
if ((vfn.vsorted[0] == v[side_relative_vertnum::_0]) || (vfn.vsorted[0] == v[side_relative_vertnum::_2])) {
sidep->set_type(side_type::tri_02);
// Now, get vertices for normal for each triangle based on triangulation type.
s0v2 = v[2];
s1v0 = v[0];
s0v2 = v[side_relative_vertnum::_2];
s1v0 = v[side_relative_vertnum::_0];
} else {
sidep->set_type(side_type::tri_13);
// Now, get vertices for normal for each triangle based on triangulation type.
s0v2 = v[3];
s1v0 = v[1];
s0v2 = v[side_relative_vertnum::_3];
s1v0 = v[side_relative_vertnum::_1];
}
assign_side_normal(vcvertptr, sidep->normals[0], v[0], v[1], s0v2);
assign_side_normal(vcvertptr, sidep->normals[1], s1v0, v[2], v[3]);
assign_side_normal(vcvertptr, sidep->normals[0], v[side_relative_vertnum::_0], v[side_relative_vertnum::_1], s0v2);
assign_side_normal(vcvertptr, sidep->normals[1], s1v0, v[side_relative_vertnum::_2], v[side_relative_vertnum::_3]);
}
}
@ -1427,10 +1427,10 @@ namespace {
void create_walls_on_side(fvcvertptr &vcvertptr, shared_segment &sp, const sidenum_t sidenum)
{
auto &vs = Side_to_verts[sidenum];
const auto v0 = sp.verts[vs[0]];
const auto v1 = sp.verts[vs[1]];
const auto v2 = sp.verts[vs[2]];
const auto v3 = sp.verts[vs[3]];
const auto v0 = sp.verts[vs[side_relative_vertnum::_0]];
const auto v1 = sp.verts[vs[side_relative_vertnum::_1]];
const auto v2 = sp.verts[vs[side_relative_vertnum::_2]];
const auto v3 = sp.verts[vs[side_relative_vertnum::_3]];
verts_for_normal vfn{v0, v1, v2, v3};
const auto negate_flag = get_verts_for_normal(vfn);
@ -1758,7 +1758,8 @@ static void change_light(const d_level_shared_destructible_light_state &LevelSha
assert(j.sidenum < MAX_SIDES_PER_SEGMENT);
const auto &&segp = vmsegptr(j.segnum);
auto &uvls = segp->unique_segment::sides[j.sidenum].uvls;
range_for (const int k, xrange(4u)) {
for (const auto k : MAX_VERTICES_PER_SIDE)
{
auto &l = uvls[k].l;
const fix dl = ds * j.vert_light[k];
if ((l += dl) < 0)

View file

@ -91,13 +91,13 @@ constexpr enumerated_array<sidenum_t, MAX_SIDES_PER_SEGMENT, sidenum_t> Side_opp
#define TOLOWER(c) ((((c)>='A') && ((c)<='Z'))?((c)+('a'-'A')):(c))
const enumerated_array<std::array<segment_relative_vertnum, 4>, MAX_SIDES_PER_SEGMENT, sidenum_t> Side_to_verts{{{
{{segment_relative_vertnum::_7, segment_relative_vertnum::_6, segment_relative_vertnum::_2, segment_relative_vertnum::_3}}, // left
{{segment_relative_vertnum::_0, segment_relative_vertnum::_4, segment_relative_vertnum::_7, segment_relative_vertnum::_3}}, // top
{{segment_relative_vertnum::_0, segment_relative_vertnum::_1, segment_relative_vertnum::_5, segment_relative_vertnum::_4}}, // right
{{segment_relative_vertnum::_2, segment_relative_vertnum::_6, segment_relative_vertnum::_5, segment_relative_vertnum::_1}}, // bottom
{{segment_relative_vertnum::_4, segment_relative_vertnum::_5, segment_relative_vertnum::_6, segment_relative_vertnum::_7}}, // back
{{segment_relative_vertnum::_3, segment_relative_vertnum::_2, segment_relative_vertnum::_1, segment_relative_vertnum::_0}}, // front
const enumerated_array<enumerated_array<segment_relative_vertnum, 4, side_relative_vertnum>, MAX_SIDES_PER_SEGMENT, sidenum_t> Side_to_verts{{{
{{{segment_relative_vertnum::_7, segment_relative_vertnum::_6, segment_relative_vertnum::_2, segment_relative_vertnum::_3}}}, // left
{{{segment_relative_vertnum::_0, segment_relative_vertnum::_4, segment_relative_vertnum::_7, segment_relative_vertnum::_3}}}, // top
{{{segment_relative_vertnum::_0, segment_relative_vertnum::_1, segment_relative_vertnum::_5, segment_relative_vertnum::_4}}}, // right
{{{segment_relative_vertnum::_2, segment_relative_vertnum::_6, segment_relative_vertnum::_5, segment_relative_vertnum::_1}}}, // bottom
{{{segment_relative_vertnum::_4, segment_relative_vertnum::_5, segment_relative_vertnum::_6, segment_relative_vertnum::_7}}}, // back
{{{segment_relative_vertnum::_3, segment_relative_vertnum::_2, segment_relative_vertnum::_1, segment_relative_vertnum::_0}}}, // front
}}};
// Texture map stuff

View file

@ -3217,10 +3217,10 @@ static int newdemo_read_frame_information(int rewrite)
w.state = wall_state{state};
w.cloak_value = cloak_value;
auto &uvl = vmsegptr(w.segnum)->unique_segment::sides[w.sidenum].uvls;
uvl[0].l = (static_cast<int>(l0)) << 8;
uvl[1].l = (static_cast<int>(l1)) << 8;
uvl[2].l = (static_cast<int>(l2)) << 8;
uvl[3].l = (static_cast<int>(l3)) << 8;
uvl[side_relative_vertnum::_0].l = (static_cast<int>(l0)) << 8;
uvl[side_relative_vertnum::_1].l = (static_cast<int>(l1)) << 8;
uvl[side_relative_vertnum::_2].l = (static_cast<int>(l2)) << 8;
uvl[side_relative_vertnum::_3].l = (static_cast<int>(l3)) << 8;
}
{
auto &w = *vmwallptr(back_wall_num);
@ -3228,10 +3228,10 @@ static int newdemo_read_frame_information(int rewrite)
w.state = wall_state{state};
w.cloak_value = cloak_value;
auto &uvl = vmsegptr(w.segnum)->unique_segment::sides[w.sidenum].uvls;
uvl[0].l = (static_cast<int>(l0)) << 8;
uvl[1].l = (static_cast<int>(l1)) << 8;
uvl[2].l = (static_cast<int>(l2)) << 8;
uvl[3].l = (static_cast<int>(l3)) << 8;
uvl[side_relative_vertnum::_0].l = (static_cast<int>(l0)) << 8;
uvl[side_relative_vertnum::_1].l = (static_cast<int>(l1)) << 8;
uvl[side_relative_vertnum::_2].l = (static_cast<int>(l2)) << 8;
uvl[side_relative_vertnum::_3].l = (static_cast<int>(l3)) << 8;
}
break;
}

View file

@ -802,7 +802,7 @@ constexpr fix CROSS_WIDTH = i2f(8);
constexpr fix CROSS_HEIGHT = i2f(8);
//draw outline for curside
static void outline_seg_side(grs_canvas &canvas, const shared_segment &seg, const sidenum_t _side, const unsigned edge, const unsigned vert)
static void outline_seg_side(grs_canvas &canvas, const shared_segment &seg, const sidenum_t _side, const side_relative_vertnum edge, const side_relative_vertnum vert)
{
auto &verts = seg.verts;
auto &LevelSharedVertexState = LevelSharedSegmentState.get_vertex_state();
@ -814,7 +814,7 @@ static void outline_seg_side(grs_canvas &canvas, const shared_segment &seg, cons
const uint8_t color = BM_XRGB(0, 63, 0);
auto &sv = Side_to_verts[_side];
g3_draw_line(canvas, Segment_points[verts[sv[edge]]], Segment_points[verts[sv[(edge + 1)%4]]], color);
g3_draw_line(canvas, Segment_points[verts[sv[edge]]], Segment_points[verts[sv[next_side_vertex(edge)]]], color);
//draw a little cross at the current vert
@ -1002,7 +1002,7 @@ static std::optional<sidenum_t> find_seg_side(const shared_segment &seg, const s
static bool compare_child(fvcvertptr &vcvertptr, const vms_vector &Viewer_eye, const shared_segment &seg, const shared_segment &cseg, const sidenum_t edgeside)
{
const auto &cside = cseg.sides[edgeside];
const auto &sv = Side_to_verts[edgeside][cside.get_type() == side_type::tri_13 ? 1 : 0];
const auto &sv = Side_to_verts[edgeside][cside.get_type() == side_type::tri_13 ? side_relative_vertnum::_1 : side_relative_vertnum::_0];
const auto &temp = vm_vec_sub(Viewer_eye, vcvertptr(seg.verts[sv]));
const auto &cnormal = cside.normals;
return vm_vec_dot(cnormal[0], temp) < 0 || vm_vec_dot(cnormal[1], temp) < 0;

View file

@ -66,10 +66,10 @@ void delta_light_read(delta_light *dl, PHYSFS_File *fp)
dl->segnum = PHYSFSX_readShort(fp);
dl->sidenum = build_sidenum_from_untrusted(PHYSFSX_readByte(fp)).value_or(sidenum_t::WLEFT);
PHYSFSX_readByte(fp);
dl->vert_light[0] = PHYSFSX_readByte(fp);
dl->vert_light[1] = PHYSFSX_readByte(fp);
dl->vert_light[2] = PHYSFSX_readByte(fp);
dl->vert_light[3] = PHYSFSX_readByte(fp);
dl->vert_light[side_relative_vertnum::_0] = PHYSFSX_readByte(fp);
dl->vert_light[side_relative_vertnum::_1] = PHYSFSX_readByte(fp);
dl->vert_light[side_relative_vertnum::_2] = PHYSFSX_readByte(fp);
dl->vert_light[side_relative_vertnum::_3] = PHYSFSX_readByte(fp);
}
@ -98,10 +98,10 @@ void delta_light_write(const delta_light *dl, PHYSFS_File *fp)
PHYSFS_writeSLE16(fp, dl->segnum);
PHYSFSX_writeU8(fp, dl->sidenum);
PHYSFSX_writeU8(fp, 0);
PHYSFSX_writeU8(fp, dl->vert_light[0]);
PHYSFSX_writeU8(fp, dl->vert_light[1]);
PHYSFSX_writeU8(fp, dl->vert_light[2]);
PHYSFSX_writeU8(fp, dl->vert_light[3]);
PHYSFSX_writeU8(fp, dl->vert_light[side_relative_vertnum::_0]);
PHYSFSX_writeU8(fp, dl->vert_light[side_relative_vertnum::_1]);
PHYSFSX_writeU8(fp, dl->vert_light[side_relative_vertnum::_2]);
PHYSFSX_writeU8(fp, dl->vert_light[side_relative_vertnum::_3]);
}
void dl_index_write(const dl_index *di, PHYSFS_File *fp)