use std::array

This commit is contained in:
Garux
2025-12-03 00:55:25 +05:00
parent e8f27e1ad9
commit 7d712c9ab8
24 changed files with 337 additions and 350 deletions
+24 -32
View File
@@ -11,13 +11,13 @@ public:
BasicVector2(){
}
template<typename OtherElement>
BasicVector2( const BasicVector2<OtherElement>& other ){
x() = static_cast<Element>( other.x() );
y() = static_cast<Element>( other.y() );
BasicVector2( const BasicVector2<OtherElement>& other ) : m_elements{
static_cast<Element>( other.x() ),
static_cast<Element>( other.y() ) }
{}
BasicVector2( const Element& x_, const Element& y_ ) : m_elements{ x_, y_ }{
}
BasicVector2( const Element& x_, const Element& y_ ){
x() = x_;
y() = y_;
explicit BasicVector2( const Element& value ) : m_elements{ value, value }{
}
Element& x(){
@@ -58,17 +58,17 @@ public:
BasicVector3(){
}
template<typename OtherElement>
BasicVector3( const BasicVector3<OtherElement>& other ){
x() = static_cast<Element>( other.x() );
y() = static_cast<Element>( other.y() );
z() = static_cast<Element>( other.z() );
}
BasicVector3( const BasicVector3<OtherElement>& other ) : m_elements{
static_cast<Element>( other.x() ),
static_cast<Element>( other.y() ),
static_cast<Element>( other.z() ) }
{}
template<typename OtherElement>
explicit BasicVector3( const BasicVector2<OtherElement>& vec2 ){
x() = static_cast<Element>( vec2.x() );
y() = static_cast<Element>( vec2.y() );
z() = 0;
}
explicit BasicVector3( const BasicVector2<OtherElement>& vec2, const Element& z_ ) : m_elements{
static_cast<Element>( vec2.x() ),
static_cast<Element>( vec2.y() ),
z_ }
{}
BasicVector3( const Element& x_, const Element& y_, const Element& z_ ) : m_elements{ x_, y_, z_ }{
}
explicit BasicVector3( const Element& value ) : m_elements{ value, value, value }{
@@ -128,17 +128,15 @@ public:
BasicVector4(){
}
BasicVector4( Element x_, Element y_, Element z_, Element w_ ){
x() = x_;
y() = y_;
z() = z_;
w() = w_;
BasicVector4( Element x_, Element y_, Element z_, Element w_ ) : m_elements{ x_, y_, z_, w_ }{
}
BasicVector4( const BasicVector3<Element>& self, Element w_ ){
x() = self.x();
y() = self.y();
z() = self.z();
w() = w_;
BasicVector4( const BasicVector3<Element>& vec3, Element w_ ) : m_elements{
vec3.x(),
vec3.y(),
vec3.z(),
w_ }
{}
explicit BasicVector4( const Element& value ) : m_elements{ value, value, value, value }{
}
Element& x(){
@@ -166,12 +164,6 @@ public:
return m_elements[3];
}
Element index( std::size_t i ) const {
return m_elements[i];
}
Element& index( std::size_t i ){
return m_elements[i];
}
Element operator[]( std::size_t i ) const {
return m_elements[i];
}
+4 -4
View File
@@ -1117,9 +1117,9 @@ public:
}
}
const PlanePoints vertices{ v0, v1, v2 };
const DoubleVector3 sts[3]{ DoubleVector3( p0->m_texcoord ),
DoubleVector3( p1->m_texcoord ),
DoubleVector3( p2->m_texcoord ) };
const DoubleVector3 sts[3]{ DoubleVector3( p0->m_texcoord, 0 ),
DoubleVector3( p1->m_texcoord, 0 ),
DoubleVector3( p2->m_texcoord, 0 ) };
Texdef_Construct_local2tex_from_ST( vertices, sts, m_local2tex );
m_tex2local = matrix4_affine_inverse( m_local2tex );
BP_from_ST( m_bp, vertices, sts, plane3_for_points( vertices ).normal() );
@@ -1170,7 +1170,7 @@ void Patch_SetTexdef( const float* hShift, const float* vShift, const float* hSc
matrix4_multiply_by_matrix4( local2tex, c.m_tex2local );
patch.undoSave();
for( auto& p : patch.getControlPoints() )
p.m_texcoord = matrix4_transformed_point( local2tex, Vector3( p.m_texcoord ) ).vec2();
p.m_texcoord = matrix4_transformed_point( local2tex, Vector3( p.m_texcoord, 0 ) ).vec2();
patch.controlPointsChanged();
}
else{ // fallback //. fixme: this is not cool; may be more valid cases in PatchTexdefConstructor, as in find one good triangle in problematic case
+17 -17
View File
@@ -5212,7 +5212,7 @@ private:
}
else if( m_patch ){
for( const auto& v : m_patchCtrl )
functor( matrix4_transformed_point( m_faceTex2local, Vector3( v.m_texcoord ) ) );
functor( matrix4_transformed_point( m_faceTex2local, Vector3( v.m_texcoord, 0 ) ) );
}
}
template<typename Functor>
@@ -5224,7 +5224,7 @@ private:
}
else if( m_patch ){
for( const auto& v : m_patchCtrl )
functor( Vector3( v.m_texcoord ) );
functor( Vector3( v.m_texcoord, 0 ) );
}
}
bool projection_valid() const {
@@ -5341,9 +5341,9 @@ private:
}
}
const PlanePoints vertices{ v0, v1, v2 };
const DoubleVector3 sts[3]{ DoubleVector3( p0->m_texcoord ),
DoubleVector3( p1->m_texcoord ),
DoubleVector3( p2->m_texcoord ) };
const DoubleVector3 sts[3]{ DoubleVector3( p0->m_texcoord, 0 ),
DoubleVector3( p1->m_texcoord, 0 ),
DoubleVector3( p2->m_texcoord, 0 ) };
Texdef_Construct_local2tex_from_ST( vertices, sts, m_local2tex );
m_tex2local = matrix4_affine_inverse( m_local2tex );
}
@@ -5375,7 +5375,7 @@ private:
m_patchRenderPoints.m_points.clear();
m_patchRenderPoints.m_points.reserve( m_patchWidth * m_patchHeight );
for( std::size_t i = 0; i < m_patchCtrl.size(); ++i ){
m_patchRenderPoints.m_points.emplace_back( vertex3f_for_vector3( Vector3( m_patchCtrl[i].m_texcoord ) ), patchCtrl_isInside( i )? m_cPin : m_cGree );
m_patchRenderPoints.m_points.emplace_back( vertex3f_for_vector3( Vector3( m_patchCtrl[i].m_texcoord, 0 ) ), patchCtrl_isInside( i )? m_cPin : m_cGree );
}
m_patchRenderLattice.m_lines.clear();
@@ -5384,16 +5384,16 @@ private:
for ( std::size_t c = 0; c < m_patchWidth - 1; ++c ){
const Vector2& a = m_patch->ctrlAt( r, c ).m_texcoord;
const Vector2& b = m_patch->ctrlAt( r, c + 1 ).m_texcoord;
m_patchRenderLattice.m_lines.emplace_back( vertex3f_for_vector3( Vector3( a ) ), m_cOrang );
m_patchRenderLattice.m_lines.emplace_back( vertex3f_for_vector3( Vector3( b ) ), m_cOrang );
m_patchRenderLattice.m_lines.emplace_back( vertex3f_for_vector3( Vector3( a, 0 ) ), m_cOrang );
m_patchRenderLattice.m_lines.emplace_back( vertex3f_for_vector3( Vector3( b, 0 ) ), m_cOrang );
}
}
for ( std::size_t c = 0; c < m_patchWidth; ++c ){
for ( std::size_t r = 0; r < m_patchHeight - 1; ++r ){
const Vector2& a = m_patch->ctrlAt( r, c ).m_texcoord;
const Vector2& b = m_patch->ctrlAt( r + 1, c ).m_texcoord;
m_patchRenderLattice.m_lines.emplace_back( vertex3f_for_vector3( Vector3( a ) ), m_cOrang );
m_patchRenderLattice.m_lines.emplace_back( vertex3f_for_vector3( Vector3( b ) ), m_cOrang );
m_patchRenderLattice.m_lines.emplace_back( vertex3f_for_vector3( Vector3( a, 0 ) ), m_cOrang );
m_patchRenderLattice.m_lines.emplace_back( vertex3f_for_vector3( Vector3( b, 0 ) ), m_cOrang );
}
}
@@ -5457,7 +5457,7 @@ private:
} );
if( updateOrigin )
m_origin = matrix4_transformed_point( m_faceTex2local, Vector3( min ) );
m_origin = matrix4_transformed_point( m_faceTex2local, Vector3( min, 0 ) );
const Vector3 uv_origin = matrix4_transformed_point( m_faceLocal2tex, m_origin );
@@ -5949,7 +5949,7 @@ private:
else if( m_patch ){
const Matrix4 uvTransform = transform_local2object( matrix4_affine_inverse( transform ), m_faceLocal2tex, m_faceTex2local );
for( std::size_t i = 0; i < m_patchCtrl.size(); ++i ){
const Vector3 uv = matrix4_transformed_point( uvTransform, Vector3( m_patchCtrl[i].m_texcoord ) );
const Vector3 uv = matrix4_transformed_point( uvTransform, Vector3( m_patchCtrl[i].m_texcoord, 0 ) );
m_patch->getControlPointsTransformed()[i].m_texcoord = uv.vec2();
}
// m_patch->controlPointsChanged();
@@ -6593,7 +6593,7 @@ public:
const Matrix4 translation = matrix4_translation_for_vec3( result );
for( std::size_t i : indices ){
const Vector3 uv = matrix4_transformed_point( translation, Vector3( m_patchCtrl[i].m_texcoord ) );
const Vector3 uv = matrix4_transformed_point( translation, Vector3( m_patchCtrl[i].m_texcoord, 0 ) );
m_patch->getControlPointsTransformed()[i].m_texcoord = uv.vec2();
m_patchRenderPoints.m_points[i].vertex = vertex3f_for_vector3( uv );
}
@@ -6603,16 +6603,16 @@ public:
for ( std::size_t c = 0; c < m_patchWidth - 1; ++c ){
const Vector2& a = m_patch->getControlPointsTransformed()[r * m_patchWidth + c].m_texcoord;
const Vector2& b = m_patch->getControlPointsTransformed()[r * m_patchWidth + c + 1].m_texcoord;
m_patchRenderLattice.m_lines[( r * ( m_patchWidth - 1 ) + c ) * 2].vertex = vertex3f_for_vector3( Vector3( a ) );
m_patchRenderLattice.m_lines[( r * ( m_patchWidth - 1 ) + c ) * 2 + 1].vertex = vertex3f_for_vector3( Vector3( b ) );
m_patchRenderLattice.m_lines[( r * ( m_patchWidth - 1 ) + c ) * 2].vertex = vertex3f_for_vector3( Vector3( a, 0 ) );
m_patchRenderLattice.m_lines[( r * ( m_patchWidth - 1 ) + c ) * 2 + 1].vertex = vertex3f_for_vector3( Vector3( b, 0 ) );
}
}
for ( std::size_t c = 0; c < m_patchWidth; ++c ){
for ( std::size_t r = 0; r < m_patchHeight - 1; ++r ){
const Vector2& a = m_patch->getControlPointsTransformed()[r * m_patchWidth + c].m_texcoord;
const Vector2& b = m_patch->getControlPointsTransformed()[( r + 1 ) * m_patchWidth + c].m_texcoord;
m_patchRenderLattice.m_lines[( m_patchWidth - 1 ) * m_patchHeight * 2 + ( c * ( m_patchHeight - 1 ) + r ) * 2].vertex = vertex3f_for_vector3( Vector3( a ) );
m_patchRenderLattice.m_lines[( m_patchWidth - 1 ) * m_patchHeight * 2 + ( c * ( m_patchHeight - 1 ) + r ) * 2 + 1].vertex = vertex3f_for_vector3( Vector3( b ) );
m_patchRenderLattice.m_lines[( m_patchWidth - 1 ) * m_patchHeight * 2 + ( c * ( m_patchHeight - 1 ) + r ) * 2].vertex = vertex3f_for_vector3( Vector3( a, 0 ) );
m_patchRenderLattice.m_lines[( m_patchWidth - 1 ) * m_patchHeight * 2 + ( c * ( m_patchHeight - 1 ) + r ) * 2 + 1].vertex = vertex3f_for_vector3( Vector3( b, 0 ) );
}
}
+7 -7
View File
@@ -1407,9 +1407,9 @@ void Face_setTexture( Face& face, const char* shader, const FaceTexture& clipboa
if( pc.empty() )
return;
PlanePoints vertices{ pc[0]->m_vertex, pc[1]->m_vertex, pc[2]->m_vertex };
const DoubleVector3 sts[3]{ DoubleVector3( pc[0]->m_texcoord ),
DoubleVector3( pc[1]->m_texcoord ),
DoubleVector3( pc[2]->m_texcoord ) };
const DoubleVector3 sts[3]{ DoubleVector3( pc[0]->m_texcoord, 0 ),
DoubleVector3( pc[1]->m_texcoord, 0 ),
DoubleVector3( pc[2]->m_texcoord, 0 ) };
{ // rotate patch points to face plane
const Plane3 plane = plane3_for_points( vertices );
const DoubleRay line = plane3_intersect_plane3( face.getPlane().plane3(), plane );
@@ -1463,9 +1463,9 @@ void Patch_setTexture( Patch& patch, const char* shader, const FaceTexture& clip
return;
PlanePoints vertices{ pc[0]->m_vertex, pc[1]->m_vertex, pc[2]->m_vertex };
const DoubleVector3 sts[3]{ DoubleVector3( pc[0]->m_texcoord ),
DoubleVector3( pc[1]->m_texcoord ),
DoubleVector3( pc[2]->m_texcoord ) };
const DoubleVector3 sts[3]{ DoubleVector3( pc[0]->m_texcoord, 0 ),
DoubleVector3( pc[1]->m_texcoord, 0 ),
DoubleVector3( pc[2]->m_texcoord, 0 ) };
Matrix4 local2tex0; // face tex projection
{
TextureProjection proj0( clipboard.m_projection );
@@ -1493,7 +1493,7 @@ void Patch_setTexture( Patch& patch, const char* shader, const FaceTexture& clip
const Matrix4 mat = matrix4_multiplied_by_matrix4( local2tex0, tex2local ); // unproject st->world, project to new st
patch.undoSave();
for( auto& p : patch ){
p.m_texcoord = matrix4_transformed_point( mat, Vector3( p.m_texcoord ) ).vec2();
p.m_texcoord = matrix4_transformed_point( mat, Vector3( p.m_texcoord, 0 ) ).vec2();
}
patch.controlPointsChanged();
Patch_textureChanged();
+38 -38
View File
@@ -109,7 +109,7 @@ struct ibspDrawSurface_t
int lightmapWidth, lightmapHeight;
Vector3 lightmapOrigin;
Vector3 lightmapVecs[ 3 ];
std::array<Vector3, 3> lightmapVecs;
int patchWidth;
int patchHeight;
@@ -127,30 +127,30 @@ struct ibspDrawSurface_t
lightmapWidth ( other.lightmapWidth ),
lightmapHeight( other.lightmapHeight ),
lightmapOrigin( other.lightmapOrigin ),
lightmapVecs { other.lightmapVecs[0], other.lightmapVecs[1], other.lightmapVecs[2] },
lightmapVecs ( other.lightmapVecs ),
patchWidth ( other.patchWidth ),
patchHeight ( other.patchHeight ) {}
patchHeight ( other.patchHeight )
{}
operator bspDrawSurface_t() const {
static_assert( MAX_LIGHTMAPS == 4 );
return{
shaderNum,
fogNum,
surfaceType,
firstVert,
numVerts,
firstIndex,
numIndexes,
{ LS_NORMAL, LS_NONE, LS_NONE, LS_NONE },
{ LS_NORMAL, LS_NONE, LS_NONE, LS_NONE },
{ lightmapNum, -3, -3, -3 },
{ lightmapX, 0, 0, 0 },
{ lightmapY, 0, 0, 0 },
lightmapWidth,
lightmapHeight,
lightmapOrigin,
{ lightmapVecs[0], lightmapVecs[1], lightmapVecs[2] },
patchWidth,
patchHeight
return bspDrawSurface_t{
.shaderNum = shaderNum,
.fogNum = fogNum,
.surfaceType = surfaceType,
.firstVert = firstVert,
.numVerts = numVerts,
.firstIndex = firstIndex,
.numIndexes = numIndexes,
.lightmapStyles { LS_NORMAL, LS_NONE, LS_NONE, LS_NONE },
.vertexStyles { LS_NORMAL, LS_NONE, LS_NONE, LS_NONE },
.lightmapNum { lightmapNum, -3, -3, -3 },
.lightmapX { lightmapX, 0, 0, 0 },
.lightmapY { lightmapY, 0, 0, 0 },
.lightmapWidth = lightmapWidth,
.lightmapHeight = lightmapHeight,
.lightmapOrigin = lightmapOrigin,
.lightmapVecs = lightmapVecs,
.patchWidth = patchWidth,
.patchHeight = patchHeight
};
}
};
@@ -170,15 +170,15 @@ struct ibspDrawVert_t
st ( other.st ),
lightmap( other.lightmap[0] ),
normal ( other.normal ),
color ( other.color[0] ) {}
color ( other.color[0] )
{}
operator bspDrawVert_t() const {
static_assert( MAX_LIGHTMAPS == 4 );
return {
xyz,
st,
{ lightmap, Vector2( 0, 0 ), Vector2( 0, 0 ), Vector2( 0, 0 ) },
normal,
{ color, Color4b( 0, 0, 0, 0 ), Color4b( 0, 0, 0, 0 ), Color4b( 0, 0, 0, 0 ) }
return bspDrawVert_t{
.xyz = xyz,
.st = st,
.lightmap{ lightmap, Vector2( 0 ), Vector2( 0 ), Vector2( 0 ) },
.normal = normal,
.color { color, Color4b( 0 ), Color4b( 0 ), Color4b( 0 ) }
};
}
};
@@ -194,14 +194,14 @@ struct ibspGridPoint_t
ibspGridPoint_t( const bspGridPoint_t& other ) :
ambient ( other.ambient[0] ),
directed( other.directed[0] ),
latLong { other.latLong[0], other.latLong[1] } {}
latLong { other.latLong[0], other.latLong[1] }
{}
operator bspGridPoint_t() const {
static_assert( MAX_LIGHTMAPS == 4 );
return {
{ ambient, ambient, ambient, ambient },
{ directed, directed, directed, directed },
{ LS_NORMAL, LS_NONE, LS_NONE, LS_NONE },
{ latLong[0], latLong[1] }
return bspGridPoint_t{
.ambient = makeArray4( ambient ),
.directed = makeArray4( directed ),
.styles { LS_NORMAL, LS_NONE, LS_NONE, LS_NONE },
.latLong { latLong[0], latLong[1] }
};
}
};
+2 -2
View File
@@ -117,7 +117,7 @@ static void AddLightGridLumps( FILE *file, rbspHeader_t& header ){
const bspGridPoint_t& out = gridPoints[ j ];
/* compare styles */
if ( memcmp( in.styles, out.styles, MAX_LIGHTMAPS ) ) {
if ( in.styles != out.styles ) {
continue;
}
@@ -137,7 +137,7 @@ static void AddLightGridLumps( FILE *file, rbspHeader_t& header ){
{
for ( int c = 0; c < 3; ++c )
{
if ( abs( (int) in.ambient[ k ][ c ] - (int) out.ambient[ k ][ c ] ) > LG_EPSILON ||
if ( abs( (int) in.ambient [ k ][ c ] - (int) out.ambient [ k ][ c ] ) > LG_EPSILON ||
abs( (int) in.directed[ k ][ c ] - (int) out.directed[ k ][ c ] ) > LG_EPSILON ) {
bad = true;
break;
+5 -1
View File
@@ -156,7 +156,11 @@ static void ConvertSurface( FILE *f, int modelNum, int surfaceNum, const Vector3
fprintf( f, "\t*PROP_CASTSHADOW\t1\r\n" );
fprintf( f, "\t*PROP_RECVSHADOW\t1\r\n" );
if ( lightmapsAsTexcoord ) {
const int lmNum = ds.lightmapNum[0] >= 0? ds.lightmapNum[0]: lmIndices[ds.shaderNum] >= 0? lmIndices[ds.shaderNum] : ds.lightmapNum[0];
const int lmNum = ds.lightmapNum[0] >= 0?
ds.lightmapNum[0]
: lmIndices[ds.shaderNum] >= 0?
lmIndices[ds.shaderNum]
: ds.lightmapNum[0];
if ( lmNum >= 0 && lmNum + (int)deluxemap < numLightmapsASE ) {
fprintf( f, "\t*MATERIAL_REF\t%d\r\n", lmNum + deluxemap );
}
+28
View File
@@ -71,12 +71,26 @@ rapidjson::Value value_for( const T (&array)[N], Allocator& allocator ){
return value;
}
template<typename T, size_t N, typename Allocator>
rapidjson::Value value_for( const std::array<T, N>& array, Allocator& allocator ){
rapidjson::Value value( rapidjson::kArrayType );
for( auto&& val : array )
value.PushBack( value_for( val, allocator ), allocator );
return value;
}
template<typename T, size_t N, typename Allocator>
rapidjson::Value value_for_array( const T (&array)[N], Allocator& allocator ){
rapidjson::Value value( rapidjson::kArrayType );
for( auto&& val : array )
value.PushBack( val, allocator );
return value;
}
template<typename T, size_t N, typename Allocator>
rapidjson::Value value_for_array( const std::array<T, N>& array, Allocator& allocator ){
rapidjson::Value value( rapidjson::kArrayType );
for( auto&& val : array )
value.PushBack( val, allocator );
return value;
}
template<typename T>
void value_to( const rapidjson::Value& value, BasicVector2<T>& vec ){
@@ -105,6 +119,11 @@ void value_to( const rapidjson::Value& value, T (&array)[N] ){
value_to( value.GetArray().operator[]( i ), val );
}
template<typename T, size_t N>
void value_to( const rapidjson::Value& value, std::array<T, N>& array ){
for_indexed( auto&& val : array )
value_to( value.GetArray().operator[]( i ), val );
}
template<typename T, size_t N>
void value_to_array( const rapidjson::Value& value, T (&array)[N] ){
for_indexed( auto&& val : array ){
if constexpr ( std::is_same_v<T, byte> )
@@ -113,6 +132,15 @@ void value_to_array( const rapidjson::Value& value, T (&array)[N] ){
val = value.GetArray().operator[]( i ).Get<T>();
}
}
template<typename T, size_t N>
void value_to_array( const rapidjson::Value& value, std::array<T, N>& array ){
for_indexed( auto&& val : array ){
if constexpr ( std::is_same_v<T, byte> )
val = value.GetArray().operator[]( i ).Get<int>();
else
val = value.GetArray().operator[]( i ).Get<T>();
}
}
static void write_doc( const char *filename, rapidjson::Document& doc ){
+5 -1
View File
@@ -65,7 +65,11 @@ static void ConvertSurfaceToOBJ( FILE *f, int modelNum, int surfaceNum, const Ve
/* export shader */
if ( lightmapsAsTexcoord ) {
const int lmNum = ds.lightmapNum[0] >= 0? ds.lightmapNum[0]: lmIndices[ds.shaderNum] >= 0? lmIndices[ds.shaderNum] : ds.lightmapNum[0];
const int lmNum = ds.lightmapNum[0] >= 0?
ds.lightmapNum[0]
: lmIndices[ds.shaderNum] >= 0?
lmIndices[ds.shaderNum]
: ds.lightmapNum[0];
if ( objLastShaderNum != lmNum ) {
fprintf( f, "usemtl lm_%04d\r\n", lmNum + deluxemap );
objLastShaderNum = lmNum + deluxemap;
+1 -4
View File
@@ -518,10 +518,7 @@ static void ProjectDecalOntoWinding( const decalProjector_t& dp, const mapDrawSu
dv.st[ 1 ] = vector3_dot( dv.xyz, dp.texMat[ 1 ].vec3() ) + dp.texMat[ 1 ][ 3 ];
/* set color */
for ( int j = 0; j < MAX_LIGHTMAPS; ++j )
{
dv.color[ j ] = { 255, 255, 255, color_to_byte( alpha ) };
}
dv.color.fill( Color4b( 255, 255, 255, color_to_byte( alpha ) ) );
}
}
+35 -42
View File
@@ -1183,10 +1183,9 @@ int LightContributionToSample( trace_t *trace ){
determines the amount of light reaching a sample (luxel or vertex)
*/
void LightingAtSample( trace_t *trace, byte (&styles)[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ], const Vector3& ambientColor ){
void LightingAtSample( trace_t *trace, Array4<byte>& styles, Array4<Vector3>& colors, const Vector3& ambientColor ){
/* clear colors */
for ( Vector3& color : colors )
color.set( 0 );
colors.fill( Vector3( 0 ) );
/* ydnar: normalmap */
if ( normalmap ) {
@@ -1460,14 +1459,12 @@ struct contribution_t
static void TraceGrid( int num ){
int i, j, x, y, z, mod, numCon, numStyles;
Vector3 cheapColor, thisdir;
rawGridPoint_t *gp;
bspGridPoint_t *bgp;
contribution_t contributions[ MAX_CONTRIBUTIONS ];
trace_t trace;
/* get grid points */
gp = &rawGridPoints[ num ];
bgp = &bspGridPoints[ num ];
rawGridPoint_t& gp = rawGridPoints[ num ];
bspGridPoint_t& bgp = bspGridPoints[ num ];
/* get grid origin */
mod = num;
@@ -1548,7 +1545,7 @@ static void TraceGrid( int num ){
/* push average direction around */
addSize = vector3_length( trace.color );
gp->dir += trace.direction * addSize;
gp.dir += trace.direction * addSize;
/* stop after a while */
if ( numCon >= ( MAX_CONTRIBUTIONS - 1 ) ) {
@@ -1598,7 +1595,7 @@ static void TraceGrid( int num ){
/* push average direction around */
addSize = vector3_length( contributions[ numCon ].color );
gp->dir += dir * addSize;
gp.dir += dir * addSize;
numCon++;
}
@@ -1606,7 +1603,7 @@ static void TraceGrid( int num ){
/////////////////////
/* normalize to get primary light direction */
thisdir = VectorNormalized( gp->dir );
thisdir = VectorNormalized( gp.dir );
/* now that we have identified the primary light direction,
go back and separate all the light into directed and ambient */
@@ -1622,7 +1619,7 @@ static void TraceGrid( int num ){
/* find appropriate style */
for ( j = 0; j < numStyles; ++j )
{
if ( gp->styles[ j ] == contributions[ i ].style ) {
if ( gp.styles[ j ] == contributions[ i ].style ) {
break;
}
}
@@ -1631,8 +1628,8 @@ static void TraceGrid( int num ){
if ( j >= numStyles ) {
/* add a new style */
if ( numStyles < MAX_LIGHTMAPS ) {
gp->styles[ numStyles ] = contributions[ i ].style;
bgp->styles[ numStyles ] = contributions[ i ].style;
gp.styles[ numStyles ] = contributions[ i ].style;
bgp.styles[ numStyles ] = contributions[ i ].style;
numStyles++;
//% Sys_Printf( "(%d, %d) ", num, contributions[ i ].style );
}
@@ -1644,7 +1641,7 @@ static void TraceGrid( int num ){
}
/* add the directed color */
gp->directed[ j ] += contributions[ i ].color * d;
gp.directed[ j ] += contributions[ i ].color * d;
/* ambient light will be at 1/4 the value of directed light */
/* (ydnar: nuke this in favor of more dramatic lighting?) */
@@ -1652,9 +1649,9 @@ static void TraceGrid( int num ){
// d = 0.25f;
/* (Hobbes: always setting it to .25 is hardly any better) */
d = 0.25f * ( 1.0f - d );
gp->ambient[ j ] += contributions[ i ].color * d;
gp.ambient[ j ] += contributions[ i ].color * d;
gp->ambient[ j ] += contributions[ i ].ambient;
gp.ambient[ j ] += contributions[ i ].ambient;
/*
* div0:
@@ -1677,40 +1674,40 @@ static void TraceGrid( int num ){
#if 0
/* do some fudging to keep the ambient from being too low (2003-07-05: 0.25 -> 0.125) */
if ( !bouncing ) {
VectorMA( gp->ambient[ i ], 0.125f, gp->directed[ i ], gp->ambient[ i ] );
VectorMA( gp.ambient[ i ], 0.125f, gp.directed[ i ], gp.ambient[ i ] );
}
#endif
/* set minimum light and copy off to bytes */
Vector3 color = gp->ambient[ i ];
Vector3 color = gp.ambient[ i ];
for ( j = 0; j < 3; ++j )
value_maximize( color[ j ], minGridLight[ j ] );
/* vortex: apply gridscale and gridambientscale here */
bgp->ambient[ i ] = ColorToBytes( color, gridScale * gridAmbientScale );
bgp->directed[ i ] = ColorToBytes( gp->directed[ i ], gridScale );
bgp.ambient[ i ] = ColorToBytes( color, gridScale * gridAmbientScale );
bgp.directed[ i ] = ColorToBytes( gp.directed[ i ], gridScale );
/*
* HACK: if there's a non-zero directed component, this
* lightgrid cell is useful. However, q3 skips grid
* cells with zero ambient. So let's force ambient to be
* nonzero unless directed is zero too.
*/
if( bgp->ambient[i][0] + bgp->ambient[i][1] + bgp->ambient[i][2] == 0
&& bgp->directed[i][0] + bgp->directed[i][1] + bgp->directed[i][2] != 0 )
bgp->ambient[i].set( 1 );
if( bgp.ambient[i][0] + bgp.ambient[i][1] + bgp.ambient[i][2] == 0
&& bgp.directed[i][0] + bgp.directed[i][1] + bgp.directed[i][2] != 0 )
bgp.ambient[i].set( 1 );
}
/* debug code */
#if 0
//% Sys_FPrintf( SYS_VRB, "%10d %10d %10d ", &gp->ambient[ 0 ][ 0 ], &gp->ambient[ 0 ][ 1 ], &gp->ambient[ 0 ][ 2 ] );
//% Sys_FPrintf( SYS_VRB, "%10d %10d %10d ", &gp.ambient[ 0 ][ 0 ], &gp.ambient[ 0 ][ 1 ], &gp.ambient[ 0 ][ 2 ] );
Sys_FPrintf( SYS_VRB, "%9d Amb: (%03.1f %03.1f %03.1f) Dir: (%03.1f %03.1f %03.1f)\n",
num,
gp->ambient[ 0 ][ 0 ], gp->ambient[ 0 ][ 1 ], gp->ambient[ 0 ][ 2 ],
gp->directed[ 0 ][ 0 ], gp->directed[ 0 ][ 1 ], gp->directed[ 0 ][ 2 ] );
gp.ambient[ 0 ][ 0 ], gp.ambient[ 0 ][ 1 ], gp.ambient[ 0 ][ 2 ],
gp.directed[ 0 ][ 0 ], gp.directed[ 0 ][ 1 ], gp.directed[ 0 ][ 2 ] );
#endif
/* store direction */
NormalToLatLong( thisdir, bgp->latLong );
NormalToLatLong( thisdir, bgp.latLong );
}
@@ -1772,17 +1769,16 @@ static void SetupGrid( const Vector3& ambientColor ){
/* allocate and clear lightgrid */
{
static_assert( MAX_LIGHTMAPS == 4 );
rawGridPoints = decltype( rawGridPoints )( numGridPoints, rawGridPoint_t{
{ ambientColor, ambientColor, ambientColor, ambientColor },
{ g_vector3_identity, g_vector3_identity, g_vector3_identity, g_vector3_identity },
g_vector3_identity,
{ LS_NORMAL, LS_NONE, LS_NONE, LS_NONE } } );
.ambient = makeArray4( ambientColor ),
.directed = makeArray4( Vector3( 0 ) ),
.dir = Vector3( 0 ),
.styles{ LS_NORMAL, LS_NONE, LS_NONE, LS_NONE } } );
bspGridPoints = decltype( bspGridPoints )( numGridPoints, bspGridPoint_t{
{ Vector3b( 0 ), Vector3b( 0 ), Vector3b( 0 ), Vector3b( 0 ) },
{ Vector3b( 0 ), Vector3b( 0 ), Vector3b( 0 ), Vector3b( 0 ) },
{ LS_NORMAL, LS_NONE, LS_NONE, LS_NONE },
{ 0, 0 } } );
.ambient = makeArray4( Vector3b( 0 ) ),
.directed = makeArray4( Vector3b( 0 ) ),
.styles{ LS_NORMAL, LS_NONE, LS_NONE, LS_NONE },
.latLong{ 0, 0 } } );
}
/* note it */
@@ -1867,12 +1863,9 @@ static void WriteBSPFileAfterLight( const char *bspFileName ){
out.shaderNum = EmitShader( String64( lmPathStart, "nomipmaps", su ), nullptr, nullptr );
out.fogNum = FOG_INVALID;
for ( int i = 0; i < MAX_LIGHTMAPS; ++i )
{
out.lightmapNum[ i ] = -3;
out.lightmapStyles[ i ] = LS_NONE;
out.vertexStyles[ i ] = LS_NONE;
}
out.lightmapStyles.fill( LS_NONE );
out.vertexStyles.fill( LS_NONE );
out.lightmapNum.fill( -3 );
}
bakDrawSurfaces.insert( bakDrawSurfaces.cend(), bspDrawSurfaces.cbegin(), bspDrawSurfaces.cend() );
+5 -5
View File
@@ -37,15 +37,15 @@ struct radVert_t
{
Vector3 xyz;
Vector2 st;
Vector2 lightmap[ MAX_LIGHTMAPS ];
Array4<Vector2> lightmap;
Vector3 normal;
Color4f color[ MAX_LIGHTMAPS ];
Array4<Color4f> color;
radVert_t() = default;
radVert_t( const bspDrawVert_t& dv )
: xyz( dv.xyz ),
st( dv.st ),
lightmap{ dv.lightmap[0], dv.lightmap[1], dv.lightmap[2], dv.lightmap[3] },
lightmap( dv.lightmap ),
normal( dv.normal )
{}
};
@@ -292,8 +292,8 @@ static void RadSample( int lightmapNum, const bspDrawSurface_t& ds, const rawLig
blend *= 1.0 / ( blend[ 0 ] + blend[ 1 ] + blend[ 2 ] );
/* create a blended sample */
Vector2 st( 0, 0 );
Vector2 lightmap( 0, 0 );
Vector2 st( 0 );
Vector2 lightmap( 0 );
alphaI = 0;
for ( l = 0; l < 3; ++l )
{
+16 -19
View File
@@ -2856,11 +2856,8 @@ void IlluminateRawLightmap( int rawLightmapNum ){
#define VERTEX_NUDGE 4.0f
void IlluminateVertexes( int num ){
int i, x, y, z, x1, y1, z1, sx, sy, radius, maxRadius;
int lightmapNum, numAvg;
int i, x, y, z, x1, y1, z1, sx, sy;
float samples, dirt;
Vector3 colors[ MAX_LIGHTMAPS ], avgColors[ MAX_LIGHTMAPS ];
bspDrawVert_t *verts;
trace_t trace;
float floodLightAmount;
Vector3 floodColor;
@@ -2892,9 +2889,10 @@ void IlluminateVertexes( int num ){
CreateTraceLightsForSurface( num, &trace );
/* setup */
verts = &yDrawVerts[ ds.firstVert ];
numAvg = 0;
memset( avgColors, 0, sizeof( avgColors ) );
bspDrawVert_t *verts = &yDrawVerts[ ds.firstVert ];
int numAvg = 0;
Array4<Vector3> colors;
Array4<Vector3> avgColors = makeArray4( Vector3( 0 ) );
/* walk the surface verts */
for ( i = 0; i < ds.numVerts; ++i )
@@ -2960,7 +2958,7 @@ void IlluminateVertexes( int num ){
LightingAtSample( &trace, ds.vertexStyles, colors, info.ambientColor );
/* store */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
for ( int lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
/* r7 dirt */
colors[ lightmapNum ] *= dirt;
@@ -3022,7 +3020,7 @@ void IlluminateVertexes( int num ){
LightingAtSample( &trace, ds.vertexStyles, colors, info.ambientColor );
/* store */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
for ( int lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
/* r7 dirt */
colors[ lightmapNum ] *= dirt;
@@ -3046,7 +3044,7 @@ void IlluminateVertexes( int num ){
/* add to average? */
if ( vector3_component_greater( getRadVertexLuxel( 0, ds.firstVert + i ), info.ambientColor ) ) {
numAvg++;
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
for ( int lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
avgColors[ lightmapNum ] += getRadVertexLuxel( lightmapNum, ds.firstVert + i );
}
@@ -3059,7 +3057,7 @@ void IlluminateVertexes( int num ){
/* set average color */
if ( numAvg > 0 ) {
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
for ( int lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
avgColors[ lightmapNum ] *= ( 1.0f / numAvg );
}
else
@@ -3072,7 +3070,7 @@ void IlluminateVertexes( int num ){
{
/* store average in occluded vertexes */
if ( getRadVertexLuxel( 0, ds.firstVert + i )[ 0 ] < 0 ) {
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
for ( int lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
getRadVertexLuxel( lightmapNum, ds.firstVert + i ) = avgColors[ lightmapNum ];
@@ -3082,7 +3080,7 @@ void IlluminateVertexes( int num ){
}
/* store it */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
for ( int lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
/* get luxels */
Vector3& vertLuxel = getVertexLuxel( lightmapNum, ds.firstVert + i );
@@ -3110,18 +3108,17 @@ void IlluminateVertexes( int num ){
----------------------------------------------------------------- */
/* set styles from lightmap */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
ds.vertexStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
ds.vertexStyles = lm->styles;
/* get max search radius */
maxRadius = std::max( lm->sw, lm->sh );
const int maxRadius = std::max( lm->sw, lm->sh );
/* walk the surface verts */
verts = &yDrawVerts[ ds.firstVert ];
bspDrawVert_t *verts = &yDrawVerts[ ds.firstVert ];
for ( i = 0; i < ds.numVerts; ++i )
{
/* do each lightmap */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
for ( int lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
/* early out */
if ( lm->superLuxels[ lightmapNum ] == nullptr ) {
@@ -3160,7 +3157,7 @@ void IlluminateVertexes( int num ){
/* increasing radius */
radVertLuxel.set( 0 );
samples = 0;
for ( radius = 0; radius < maxRadius && samples <= 0; ++radius )
for ( int radius = 0; radius < maxRadius && samples <= 0; ++radius )
{
/* sample within radius */
for ( sy = ( y - radius ); sy <= ( y + radius ); ++sy )
+61 -73
View File
@@ -331,9 +331,7 @@ static void FinishRawLightmap( rawLightmap_t& lm ){
}
/* set styles */
lm.styles[ 0 ] = LS_NORMAL;
for ( i = 1; i < MAX_LIGHTMAPS; ++i )
lm.styles[ i ] = LS_NONE;
lm.styles = { LS_NORMAL, LS_NONE, LS_NONE, LS_NONE };
/* set supersampling size */
lm.sw = lm.w * superSample;
@@ -452,7 +450,7 @@ static void FinishRawLightmap( rawLightmap_t& lm ){
*/
static bool AddPatchToRawLightmap( int num, rawLightmap_t& lm ){
float sBasis, tBasis, s, t;
float sBasis, tBasis;
float length, widthTable[ MAX_EXPANDED_AXIS ] = {0}, heightTable[ MAX_EXPANDED_AXIS ] = {0};
@@ -511,10 +509,10 @@ static bool AddPatchToRawLightmap( int num, rawLightmap_t& lm ){
bspDrawVert_t *verts = &yDrawVerts[ ds.firstVert ];
for ( int y = 0; y < ds.patchHeight; ++y )
{
t = ( tBasis * y ) + 0.5f;
const float t = ( tBasis * y ) + 0.5f;
for ( int x = 0; x < ds.patchWidth; ++x )
{
s = ( sBasis * x ) + 0.5f;
const float s = ( sBasis * x ) + 0.5f;
verts[ ( y * ds.patchWidth ) + x ].lightmap[ 0 ][ 0 ] = s * superSample;
verts[ ( y * ds.patchWidth ) + x ].lightmap[ 0 ][ 1 ] = t * superSample;
@@ -552,8 +550,8 @@ static bool AddPatchToRawLightmap( int num, rawLightmap_t& lm ){
static bool AddSurfaceToRawLightmap( int num, rawLightmap_t& lm ){
int axisNum;
float s, t, len, sampleSize;
Vector3 mins, maxs, origin, faxis, size, delta, normalized, vecs[ 2 ];
float len, sampleSize;
Vector3 mins, maxs, origin, faxis, size, normalized, vecs[ 2 ];
Plane3f plane;
bspDrawVert_t *verts;
@@ -733,9 +731,9 @@ static bool AddSurfaceToRawLightmap( int num, rawLightmap_t& lm ){
/* set the lightmap texture coordinates in yDrawVerts in [0, superSample * lm.customWidth] space */
for ( int i = 0; i < ds2.numVerts; ++i )
{
delta = verts[ i ].xyz - origin;
s = vector3_dot( delta, vecs[ 0 ] ) + 0.5f;
t = vector3_dot( delta, vecs[ 1 ] ) + 0.5f;
const Vector3 delta = verts[ i ].xyz - origin;
const float s = vector3_dot( delta, vecs[ 0 ] ) + 0.5f;
const float t = vector3_dot( delta, vecs[ 1 ] ) + 0.5f;
verts[ i ].lightmap[ 0 ][ 0 ] = s * superSample;
verts[ i ].lightmap[ 0 ][ 1 ] = t * superSample;
@@ -1794,8 +1792,7 @@ static void FindOutLightmaps( rawLightmap_t *lm, bool fastAllocate ){
/* set default lightmap number (-3 = LIGHTMAP_BY_VERTEX) */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
lm->outLightmapNums[ lightmapNum ] = -3;
lm->outLightmapNums.fill( -3 );
/* can this lightmap be approximated with vertex color? */
if ( ApproximateLightmap( lm ) ) {
@@ -2258,14 +2255,12 @@ static void FillOutLightmap( outLightmap_t *olm ){
void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
int i, j, k, x, y, lx, ly, sx, sy, mappedSamples;
int style, lightmapNum, lightmapNum2;
int lightmapNum, lightmapNum2;
float samples, occludedSamples;
Vector3 sample, occludedSample, dirSample;
byte *lb;
int numUsed, numTwins, numTwinLuxels, numStored;
float lmx, lmy, efficiency;
bspDrawSurface_t *ds, *parent, dsTemp;
surfaceInfo_t *info;
rawLightmap_t *lm, *lm2;
outLightmap_t *olm;
bspDrawVert_t *dv, *ydv, *dvParent;
@@ -2744,12 +2739,9 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
/* set all twin refs to null */
for ( i = 0; i < numRawLightmaps; ++i )
{
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
rawLightmaps[ i ].twins[ lightmapNum ] = nullptr;
rawLightmaps[ i ].twinNums[ lightmapNum ] = -1;
rawLightmaps[ i ].numStyledTwins = 0;
}
rawLightmaps[ i ].twins.fill( nullptr );
rawLightmaps[ i ].twinNums.fill( -1 );
rawLightmaps[ i ].numStyledTwins = 0;
}
/* walk the list of raw lightmaps */
@@ -3000,33 +2992,32 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
for ( size_t i = 0; i < bspDrawSurfaces.size(); ++i )
{
/* get the surface and info */
ds = &bspDrawSurfaces[ i ];
info = &surfaceInfos[ i ];
lm = info->lm;
bspDrawSurface_t& ds = bspDrawSurfaces[ i ];
const surfaceInfo_t& info = surfaceInfos[ i ];
lm = info.lm;
olm = nullptr;
/* handle surfaces with identical parent */
if ( info->parentSurfaceNum >= 0 ) {
if ( info.parentSurfaceNum >= 0 ) {
/* preserve original data and get parent */
parent = &bspDrawSurfaces[ info->parentSurfaceNum ];
memcpy( &dsTemp, ds, sizeof( *ds ) );
const bspDrawSurface_t dsTemp( ds );
const bspDrawSurface_t& parent = bspDrawSurfaces[ info.parentSurfaceNum ];
/* overwrite child with parent data */
memcpy( ds, parent, sizeof( *ds ) );
ds = parent;
/* restore key parts */
ds->fogNum = dsTemp.fogNum;
ds->firstVert = dsTemp.firstVert;
ds->firstIndex = dsTemp.firstIndex;
memcpy( ds->lightmapVecs, dsTemp.lightmapVecs, sizeof( dsTemp.lightmapVecs ) );
ds.fogNum = dsTemp.fogNum;
ds.firstVert = dsTemp.firstVert;
ds.firstIndex = dsTemp.firstIndex;
ds.lightmapVecs = dsTemp.lightmapVecs;
/* set vertex data */
dv = &bspDrawVerts[ ds->firstVert ];
dvParent = &bspDrawVerts[ parent->firstVert ];
for ( j = 0; j < ds->numVerts; ++j )
dv = &bspDrawVerts[ ds.firstVert ];
dvParent = &bspDrawVerts[ parent.firstVert ];
for ( j = 0; j < ds.numVerts; ++j )
{
memcpy( dv[ j ].lightmap, dvParent[ j ].lightmap, sizeof( dv[ j ].lightmap ) );
memcpy( dv[ j ].color, dvParent[ j ].color, sizeof( dv[ j ].color ) );
dv[ j ].lightmap = dvParent[ j ].lightmap;
dv[ j ].color = dvParent[ j ].color;
}
/* skip the rest */
@@ -3035,11 +3026,8 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
/* handle vertex lit or approximated surfaces */
else if ( lm == nullptr || lm->outLightmapNums[ 0 ] < 0 ) {
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
ds->lightmapNum[ lightmapNum ] = -3;
ds->lightmapStyles[ lightmapNum ] = ds->vertexStyles[ lightmapNum ];
}
ds.lightmapStyles = ds.vertexStyles;
ds.lightmapNum.fill( -3 );
}
/* handle lightmapped surfaces */
@@ -3049,11 +3037,11 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
/* set style */
ds->lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
ds.lightmapStyles[ lightmapNum ] = lm->styles[ lightmapNum ];
/* handle unused style */
if ( lm->styles[ lightmapNum ] == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
ds->lightmapNum[ lightmapNum ] = -3;
ds.lightmapNum[ lightmapNum ] = -3;
continue;
}
@@ -3061,11 +3049,11 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
olm = &outLightmaps[ lm->outLightmapNums[ lightmapNum ] ];
/* set bsp lightmap number */
ds->lightmapNum[ lightmapNum ] = olm->lightmapNum;
ds.lightmapNum[ lightmapNum ] = olm->lightmapNum;
/* deluxemap debugging makes the deluxemap visible */
if ( deluxemap && debugDeluxemap && lightmapNum == 0 ) {
ds->lightmapNum[ lightmapNum ]++;
ds.lightmapNum[ lightmapNum ]++;
}
/* calc lightmap origin in texture space */
@@ -3073,9 +3061,9 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
lmy = (float) lm->lightmapY[ lightmapNum ] / olm->customHeight;
/* calc lightmap st coords */
dv = &bspDrawVerts[ ds->firstVert ];
ydv = &yDrawVerts[ ds->firstVert ];
for ( j = 0; j < ds->numVerts; ++j )
dv = &bspDrawVerts[ ds.firstVert ];
ydv = &yDrawVerts[ ds.firstVert ];
for ( j = 0; j < ds.numVerts; ++j )
{
if ( lm->solid[ lightmapNum ] ) {
dv[ j ].lightmap[ lightmapNum ][ 0 ] = lmx + ( 0.5f / olm->customWidth );
@@ -3091,21 +3079,21 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
}
/* store vertex colors */
dv = &bspDrawVerts[ ds->firstVert ];
for ( j = 0; j < ds->numVerts; ++j )
dv = &bspDrawVerts[ ds.firstVert ];
for ( j = 0; j < ds.numVerts; ++j )
{
/* walk lightmaps */
for ( lightmapNum = 0; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
Vector3 color;
/* handle unused style */
if ( ds->vertexStyles[ lightmapNum ] == LS_NONE ) {
if ( ds.vertexStyles[ lightmapNum ] == LS_NONE ) {
color.set( 0 );
}
else
{
/* get vertex color */
color = getVertexLuxel( lightmapNum, ds->firstVert + j );
color = getVertexLuxel( lightmapNum, ds.firstVert + j );
/* set minimum light */
if ( lightmapNum == 0 ) {
@@ -3115,29 +3103,29 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
}
/* store to bytes */
if ( !info->si->noVertexLight ) {
dv[ j ].color[ lightmapNum ].rgb() = ColorToBytes( color, info->si->vertexScale );
if ( !info.si->noVertexLight ) {
dv[ j ].color[ lightmapNum ].rgb() = ColorToBytes( color, info.si->vertexScale );
}
}
}
/* surfaces with styled lightmaps and a style marker get a custom generated shader (fixme: make this work with external lightmaps) */
if ( olm != nullptr && lm != nullptr && lm->styles[ 1 ] != LS_NONE && g_game->load != LoadRBSPFile ) { //% info->si->styleMarker > 0 )
if ( olm != nullptr && lm != nullptr && lm->styles[ 1 ] != LS_NONE && g_game->load != LoadRBSPFile ) { //% info.si->styleMarker > 0 )
char key[ 32 ], styleStage[ 512 ], styleStages[ 4096 ], rgbGen[ 128 ], alphaGen[ 128 ];
/* setup */
sprintf( styleStages, "\n\t// Q3Map2 custom lightstyle stage(s)\n" );
dv = &bspDrawVerts[ ds->firstVert ];
dv = &bspDrawVerts[ ds.firstVert ];
/* depthFunc equal? */
const bool dfEqual = ( info->si->styleMarker == 2 || info->si->implicitMap == EImplicitMap::Masked );
const bool dfEqual = ( info.si->styleMarker == 2 || info.si->implicitMap == EImplicitMap::Masked );
/* generate stages for styled lightmaps */
for ( lightmapNum = 1; lightmapNum < MAX_LIGHTMAPS; ++lightmapNum )
{
/* early out */
style = lm->styles[ lightmapNum ];
const int style = lm->styles[ lightmapNum ];
if ( style == LS_NONE || lm->outLightmapNums[ lightmapNum ] < 0 ) {
continue;
}
@@ -3222,16 +3210,16 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
}
/* create custom shader */
const shaderInfo_t& csi = CustomShader( info->si, info->si->styleMarker == 2? "q3map_styleMarker2" : "q3map_styleMarker", styleStages );
const shaderInfo_t& csi = CustomShader( info.si, info.si->styleMarker == 2? "q3map_styleMarker2" : "q3map_styleMarker", styleStages );
/* emit remap command */
//% EmitVertexRemapShader( csi.shader, info->si->shader );
//% EmitVertexRemapShader( csi.shader, info.si->shader );
/* store it */
//% Sys_Printf( "Emitting: %s (%d", csi.shader, strlen( csi.shader ) );
const int cont = bspShaders[ ds->shaderNum ].contentFlags;
const int surf = bspShaders[ ds->shaderNum ].surfaceFlags;
ds->shaderNum = EmitShader( csi.shader, &cont, &surf );
const int cont = bspShaders[ ds.shaderNum ].contentFlags;
const int surf = bspShaders[ ds.shaderNum ].surfaceFlags;
ds.shaderNum = EmitShader( csi.shader, &cont, &surf );
//% Sys_Printf( ")\n" );
}
@@ -3245,21 +3233,21 @@ void StoreSurfaceLightmaps( bool fastAllocate, bool storeForReal ){
sprintf( lightmapName, "maps/%s/" EXTERNAL_LIGHTMAP "\n\t\ttcgen lightmap", mapName.c_str(), olm->extLightmapNum );
/* create custom shader */
const shaderInfo_t& csi = CustomShader( info->si, "$lightmap", lightmapName );
const shaderInfo_t& csi = CustomShader( info.si, "$lightmap", lightmapName );
/* store it */
//% Sys_Printf( "Emitting: %s (%d", csi.shader, strlen( csi.shader ) );
const int cont = bspShaders[ ds->shaderNum ].contentFlags;
const int surf = bspShaders[ ds->shaderNum ].surfaceFlags;
ds->shaderNum = EmitShader( csi.shader, &cont, &surf );
const int cont = bspShaders[ ds.shaderNum ].contentFlags;
const int surf = bspShaders[ ds.shaderNum ].surfaceFlags;
ds.shaderNum = EmitShader( csi.shader, &cont, &surf );
//% Sys_Printf( ")\n" );
}
/* use the normal plain-jane shader */
else{
const int cont = bspShaders[ ds->shaderNum ].contentFlags;
const int surf = bspShaders[ ds->shaderNum ].surfaceFlags;
ds->shaderNum = EmitShader( info->si->shader, &cont, &surf );
const int cont = bspShaders[ ds.shaderNum ].contentFlags;
const int surf = bspShaders[ ds.shaderNum ].surfaceFlags;
ds.shaderNum = EmitShader( info.si->shader, &cont, &surf );
}
}
+1 -1
View File
@@ -252,7 +252,7 @@ struct AssModel
if( m_mesh->HasTextureCoords( 0 ) )
st[n] = { m_mesh->mTextureCoords[0][i].x, m_mesh->mTextureCoords[0][i].y };
else
st[n] = { 0, 0 };
st[n] = Vector2( 0 );
}
visitor( xyz, st );
}
+2 -5
View File
@@ -223,10 +223,7 @@ void ParsePatch( bool onlyLights, entity_t& mapEnt, int mapPrimitiveNum ){
Parse1DMatrix( 5, m[ i ][ j ].xyz.data() );
/* ydnar: fix colors */
for ( auto& color : m[ i ][ j ].color )
{
color.set( 255 );
}
m[ i ][ j ].color.fill( Color4b( 255 ) );
}
MatchToken( ")" );
}
@@ -252,7 +249,7 @@ void ParsePatch( bool onlyLights, entity_t& mapEnt, int mapPrimitiveNum ){
/* ydnar: delete and warn about degenerate patches */
Vector4 delta( 0, 0, 0, 0 );
Vector4 delta( 0 );
degenerate = true;
/* find first valid vector */
+51 -30
View File
@@ -216,6 +216,25 @@ inline bool style_is_valid( int style ){ return LS_NORMAL <= style && style < LS
#define LIGHTMAP_HEIGHT 128
static_assert( MAX_LIGHTMAPS == 4 );
template<class T>
using Array4 = std::array<T, MAX_LIGHTMAPS>;
template<class T>
constexpr auto makeArray4( T&& value ){
return std::array<std::decay_t<T>, MAX_LIGHTMAPS>{ value, value, value, value };
}
template<std::size_t N, class T>
constexpr auto make_array( T&& value ){
return [&]<std::size_t... Indices>( std::index_sequence<Indices...> ) {
return std::array<std::decay_t<T>, N> { ( void(Indices), value )... };
} ( std::make_index_sequence<N>() );
}
struct bspLump_t
{
@@ -304,18 +323,18 @@ struct bspDrawVert_t
{
Vector3 xyz;
Vector2 st;
Vector2 lightmap[ MAX_LIGHTMAPS ]; /* RBSP */
Array4<Vector2> lightmap; /* RBSP */
Vector3 normal;
Color4b color[ MAX_LIGHTMAPS ]; /* RBSP */
Array4<Color4b> color; /* RBSP */
};
inline const bspDrawVert_t c_bspDrawVert_t0 =
{
.xyz{ 0 },
.st{ 0, 0 },
.lightmap{ { 0, 0 }, { 0, 0 }, { 0, 0 }, { 0, 0 } },
.st{ 0 },
.lightmap = makeArray4( Vector2( 0 ) ),
.normal{ 0 },
.color{ { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 } }
.color = makeArray4( Color4b( 0 ) )
};
using TriRef = std::array<const bspDrawVert_t *, 3>;
@@ -338,9 +357,9 @@ enum bspSurfaceType_t
struct bspGridPoint_t
{
Vector3b ambient[ MAX_LIGHTMAPS ]; /* RBSP - array */
Vector3b directed[ MAX_LIGHTMAPS ]; /* RBSP - array */
byte styles[ MAX_LIGHTMAPS ]; /* RBSP - whole */
Array4<Vector3b> ambient; /* RBSP - array */
Array4<Vector3b> directed; /* RBSP - array */
Array4<byte> styles; /* RBSP - whole */
byte latLong[ 2 ];
};
@@ -357,14 +376,15 @@ struct bspDrawSurface_t
int firstIndex;
int numIndexes;
byte lightmapStyles[ MAX_LIGHTMAPS ]; /* RBSP */
byte vertexStyles[ MAX_LIGHTMAPS ]; /* RBSP */
int lightmapNum[ MAX_LIGHTMAPS ]; /* RBSP */
int lightmapX[ MAX_LIGHTMAPS ], lightmapY[ MAX_LIGHTMAPS ]; /* RBSP */
Array4<byte> lightmapStyles; /* RBSP */
Array4<byte> vertexStyles; /* RBSP */
Array4<int> lightmapNum; /* RBSP */
Array4<int> lightmapX; /* RBSP */
Array4<int> lightmapY; /* RBSP */
int lightmapWidth, lightmapHeight;
Vector3 lightmapOrigin;
Vector3 lightmapVecs[ 3 ]; /* on patches, [ 0 ] and [ 1 ] are lodbounds */
std::array<Vector3, 3> lightmapVecs; /* on patches, [ 0 ] and [ 1 ] are lodbounds */
int patchWidth;
int patchHeight;
@@ -598,7 +618,7 @@ struct shaderInfo_t_data
int skyIndex = -1; /* shaders that are used and emit sun/skylight get unique emitter index */
Vector3 color{ 0 }; /* normalized color */
Color4f averageColor = { 0, 0, 0, 0 };
Color4f averageColor{ 0 };
byte lightStyle;
/* vortex: per-surface floodlight */
@@ -1275,19 +1295,20 @@ struct rawLightmap_t
Plane3f *plane;
int w, h, sw, sh, used;
bool solid[ MAX_LIGHTMAPS ];
Vector3 solidColor[ MAX_LIGHTMAPS ];
Array4<bool> solid;
Array4<Vector3> solidColor;
int numStyledTwins;
rawLightmap_t *twins[ MAX_LIGHTMAPS ];
Array4<rawLightmap_t*> twins;
int outLightmapNums[ MAX_LIGHTMAPS ];
int twinNums[ MAX_LIGHTMAPS ];
int lightmapX[ MAX_LIGHTMAPS ], lightmapY[ MAX_LIGHTMAPS ];
byte styles[ MAX_LIGHTMAPS ];
Vector3 *bspLuxels[ MAX_LIGHTMAPS ];
Vector3 *radLuxels[ MAX_LIGHTMAPS ];
SuperLuxel *superLuxels[ MAX_LIGHTMAPS ];
Array4<int> outLightmapNums;
Array4<int> twinNums;
Array4<int> lightmapX;
Array4<int> lightmapY;
Array4<byte> styles;
Array4<Vector3*> bspLuxels;
Array4<Vector3*> radLuxels;
Array4<SuperLuxel*> superLuxels;
byte *superFlags;
Vector3 *superOrigins;
Vector3 *superNormals;
@@ -1368,10 +1389,10 @@ struct rawLightmap_t
struct rawGridPoint_t
{
Vector3 ambient[ MAX_LIGHTMAPS ];
Vector3 directed[ MAX_LIGHTMAPS ];
Array4<Vector3> ambient;
Array4<Vector3> directed;
Vector3 dir;
byte styles[ MAX_LIGHTMAPS ];
Array4<byte> styles;
};
@@ -1770,7 +1791,7 @@ int VisMain( Args& args );
/* light.c */
float PointToPolygonFormFactor( const Vector3& point, const Vector3& normal, const winding_t& w );
int LightContributionToSample( trace_t *trace );
void LightingAtSample( trace_t * trace, byte (&styles)[ MAX_LIGHTMAPS ], Vector3 (&colors)[ MAX_LIGHTMAPS ], const Vector3& ambientColor );
void LightingAtSample( trace_t * trace, Array4<byte>& styles, Array4<Vector3>& colors, const Vector3& ambientColor );
int LightMain( Args& args );
@@ -2233,8 +2254,8 @@ inline rawLightmap_t *rawLightmaps;
inline int *sortLightmaps;
/* vertex luxels */
inline Vector3 *vertexLuxels[ MAX_LIGHTMAPS ];
inline Vector3 *radVertexLuxels[ MAX_LIGHTMAPS ];
inline Array4<Vector3*> vertexLuxels;
inline Array4<Vector3*> radVertexLuxels;
inline Vector3& getVertexLuxel( int lightmapNum, int vertexNum ){
return vertexLuxels[lightmapNum][vertexNum];
+3 -3
View File
@@ -60,8 +60,8 @@ void ColorMod( const std::forward_list<colorMod_t>& colormod, const Span<bspDraw
{
float c;
/* default */
Color4f mult( 1, 1, 1, 1 );
Color4f add( 0, 0, 0, 0 );
Color4f mult( 1 );
Color4f add( 0 );
const Vector3 cm_vec3 = vector3_from_array( cm.data );
/* switch on type */
@@ -691,7 +691,7 @@ static void LoadShaderImages( shaderInfo_t& si ){
/* create default and average colors */
const int count = si.lightImage->width * si.lightImage->height;
Color4f color( 0, 0, 0, 0 );
Color4f color( 0 );
for ( int i = 0; i < count; ++i )
{
color[ 0 ] += si.lightImage->pixels[ i * 4 + 0 ];
+19 -46
View File
@@ -730,14 +730,10 @@ mapDrawSurface_t *DrawSurfaceForSide( const entity_t& e, const brush_t& b, const
dv.normal = mapplanes[ s.planenum ].normal();
/* ydnar: set color */
for ( auto& color : dv.color )
{
color.set( 255 );
/* ydnar: gs mods: handle indexed shader blending */
if( indexed )
color.alpha() = shaderIndexes[ j ];
}
if( indexed )
dv.color.fill( Color4b( 255, 255, 255, shaderIndexes[ j ] ) ); /* ydnar: gs mods: handle indexed shader blending */
else
dv.color.fill( Color4b( 255 ) );
}
/* set cel shader */
@@ -881,14 +877,10 @@ mapDrawSurface_t& DrawSurfaceForMesh( const entity_t& e, parseMesh_t& p ){
}
/* ydnar: set color */
for ( auto& color : dv.color )
{
color.set( 255 );
/* ydnar: gs mods: handle indexed shader blending */
if( indexed )
color.alpha() = shaderIndexes[ i ];
}
if( indexed )
dv.color.fill( Color4b( 255, 255, 255, shaderIndexes[ i ] ) ); /* ydnar: gs mods: handle indexed shader blending */
else
dv.color.fill( Color4b( 255 ) );
/* ydnar: offset */
if ( indexed ) {
@@ -2007,14 +1999,9 @@ static void EmitFlareSurface( mapDrawSurface_t& ds ){
out.fogNum = ds.fogNum;
/* RBSP */
for ( int i = 0; i < MAX_LIGHTMAPS; ++i )
{
out.lightmapNum[ i ] = -3;
out.lightmapStyles[ i ] = LS_NONE;
out.vertexStyles[ i ] = LS_NONE;
}
out.lightmapStyles[ 0 ] = ds.lightStyle;
out.vertexStyles[ 0 ] = ds.lightStyle;
out.lightmapStyles = { byte( ds.lightStyle ), LS_NONE, LS_NONE, LS_NONE };
out.vertexStyles = { byte( ds.lightStyle ), LS_NONE, LS_NONE, LS_NONE };
out.lightmapNum.fill( -3 );
out.lightmapOrigin = ds.lightmapOrigin; /* origin */
out.lightmapVecs[ 0 ] = ds.lightmapVecs[ 0 ]; /* color */
@@ -2086,14 +2073,9 @@ static void EmitPatchSurface( const entity_t& e, mapDrawSurface_t& ds ){
out.fogNum = ds.fogNum;
/* RBSP */
for ( int i = 0; i < MAX_LIGHTMAPS; ++i )
{
out.lightmapNum[ i ] = -3;
out.lightmapStyles[ i ] = LS_NONE;
out.vertexStyles[ i ] = LS_NONE;
}
out.lightmapStyles[ 0 ] = LS_NORMAL;
out.vertexStyles[ 0 ] = LS_NORMAL;
out.lightmapStyles = { LS_NORMAL, LS_NONE, LS_NONE, LS_NONE };
out.vertexStyles = { LS_NORMAL, LS_NONE, LS_NONE, LS_NONE };
out.lightmapNum.fill( -3 );
/* ydnar: gs mods: previously, the lod bounds were stored in lightmapVecs[ 0 ] and [ 1 ], moved to bounds[ 0 ] and [ 1 ] */
out.lightmapOrigin = ds.lightmapOrigin;
@@ -2392,14 +2374,9 @@ static void EmitTriangleSurface( mapDrawSurface_t& ds ){
}
/* RBSP */
for ( int i = 0; i < MAX_LIGHTMAPS; ++i )
{
out.lightmapNum[ i ] = -3;
out.lightmapStyles[ i ] = LS_NONE;
out.vertexStyles[ i ] = LS_NONE;
}
out.lightmapStyles[ 0 ] = LS_NORMAL;
out.vertexStyles[ 0 ] = LS_NORMAL;
out.lightmapStyles = { LS_NORMAL, LS_NONE, LS_NONE, LS_NONE };
out.vertexStyles = { LS_NORMAL, LS_NONE, LS_NONE, LS_NONE };
out.lightmapNum.fill( -3 );
/* lightmap vectors (lod bounds for patches) */
out.lightmapOrigin = ds.lightmapOrigin;
@@ -2496,12 +2473,8 @@ static void MakeDebugPortalSurfs_r( const node_t *node, shaderInfo_t& si ){
/* set it */
dv.xyz = w[ i ];
dv.normal = p->plane.normal();
dv.st = { 0, 0 };
for ( auto& color : dv.color )
{
color.rgb() = debugColors[ c % 12 ];
color.alpha() = 32;
}
dv.st = Vector2( 0 );
dv.color.fill( Color4b( debugColors[ c % 12 ], 32 ) );
}
}
}
+2 -2
View File
@@ -32,9 +32,9 @@ struct surfaceExtra_t
int castShadows = WORLDSPAWN_CAST_SHADOWS;
int recvShadows = WORLDSPAWN_RECV_SHADOWS;
int sampleSize = 0;
Vector3 ambientColor{ 0, 0, 0 };
Vector3 ambientColor{ 0 };
float longestCurve = 0;
Vector3 lightmapAxis{ 0, 0, 0 };
Vector3 lightmapAxis{ 0 };
};
const surfaceExtra_t& GetSurfaceExtra( int num );
+1 -4
View File
@@ -248,10 +248,7 @@ void Foliage( const mapDrawSurface_t& src, entity_t& entity ){
dv.normal = fi.normal;
/* ydnar: set color */
for ( auto& color : dv.color )
{
color.set( 255 );
}
dv.color.fill( Color4b( 255 ) );
}
}
}
+4 -6
View File
@@ -602,9 +602,7 @@ static void FanFaceSurface( mapDrawSurface_t& ds ){
return;
}
Color4f color[ MAX_LIGHTMAPS ];
for ( auto& co : color )
co.set( 0 );
Array4<Color4f> color = makeArray4( Color4f( 0 ) );
/* add up the drawverts to create a centroid */
DoubleVector3 cnt( 0 );
@@ -1366,9 +1364,9 @@ static int AddMetaTriangleToSurface( mapDrawSurface_t& ds, const metaTriangle_t&
/* check texture range overflow */
MinMax newTexMinMax( texMinMax );
{
newTexMinMax.extend( Vector3( tri.m_vertices[ 0 ]->st ) );
newTexMinMax.extend( Vector3( tri.m_vertices[ 1 ]->st ) );
newTexMinMax.extend( Vector3( tri.m_vertices[ 2 ]->st ) );
newTexMinMax.extend( Vector3( tri.m_vertices[ 0 ]->st, 0 ) );
newTexMinMax.extend( Vector3( tri.m_vertices[ 1 ]->st, 0 ) );
newTexMinMax.extend( Vector3( tri.m_vertices[ 2 ]->st, 0 ) );
if( numVerts_original == 0 || texMinMax.surrounds( newTexMinMax ) ){
score += 4 * ST_SCORE;
}
+2 -4
View File
@@ -320,9 +320,8 @@ static void FixSurfaceJunctions( mapDrawSurface_t& ds ) {
const float c = v1.color[ k ][ j ] + frac * ( v2.color[ k ][ j ] - v1.color[ k ][ j ] );
v.color[ k ][ j ] = color_to_byte( c );
}
v.lightmap[ k ] = { 0, 0 }; // do zero init
}
v.lightmap[ 0 ] = vector2_mid( v1.lightmap[ 0 ], v2.lightmap[ 0 ] );
v.lightmap = { vector2_mid( v1.lightmap[ 0 ], v2.lightmap[ 0 ] ), Vector2( 0 ), Vector2( 0 ), Vector2( 0 ) };
bspDrawVert_mark_tjunc( v );
/* next... */
@@ -452,11 +451,10 @@ static bool FixBrokenSurface( mapDrawSurface_t& ds ){
/* lightmap st/colors */
for ( int k = 0; k < MAX_LIGHTMAPS; ++k )
{
avg.lightmap[ k ] = { 0, 0 };
for ( int j = 0; j < 4; ++j )
avg.color[ k ][ j ] = ( dv1.color[ k ][ j ] + dv2.color[ k ][ j ] ) >> 1;
}
avg.lightmap[ 0 ] = vector2_mid( dv1.lightmap[ 0 ], dv2.lightmap[ 0 ] );
avg.lightmap = { vector2_mid( dv1.lightmap[ 0 ], dv2.lightmap[ 0 ] ), Vector2( 0 ), Vector2( 0 ), Vector2( 0 ) };
if( bspDrawVert_is_tjunc( dv1 ) && bspDrawVert_is_tjunc( dv2 ) )
bspDrawVert_mark_tjunc( avg );
+4 -4
View File
@@ -33,17 +33,17 @@
#include "q3map2.h"
inline void bspDrawVert_edge_index_write( bspDrawVert_t& dv, int index ){
dv.lightmap[MAX_LIGHTMAPS - 1][0] = index;
dv.lightmap.back()[0] = index;
}
inline int bspDrawVert_edge_index_read( const bspDrawVert_t& dv ){
return dv.lightmap[MAX_LIGHTMAPS - 1][0];
return dv.lightmap.back()[0];
}
inline void bspDrawVert_mark_tjunc( bspDrawVert_t& dv ){
dv.lightmap[MAX_LIGHTMAPS - 1][1] = 1;
dv.lightmap.back()[1] = 1;
}
inline bool bspDrawVert_is_tjunc( const bspDrawVert_t& dv ){
return dv.lightmap[MAX_LIGHTMAPS - 1][1] == 1;
return dv.lightmap.back()[1] == 1;
}