mirror of
https://github.com/Garux/netradiant-custom.git
synced 2026-09-28 00:00:03 +02:00
refactor mesh_t
This commit is contained in:
@@ -410,40 +410,34 @@ void ProcessDecals(){
|
||||
/* create projectors */
|
||||
if ( distance > 0.125f ) {
|
||||
/* tesselate the patch */
|
||||
const int iterations = IterationsForCurve( p.longestCurve, patchSubdivisions );
|
||||
mesh_t *subdivided = SubdivideMesh2( p.mesh, iterations );
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
mesh_t mesh = TessellatedMesh( p.mesh, IterationsForCurve( p.longestCurve, patchSubdivisions ) );
|
||||
|
||||
/* offset by projector origin */
|
||||
for ( bspDrawVert_t& vert : Span( mesh->verts, mesh->width * mesh->height ) )
|
||||
for ( bspDrawVert_t& vert : Span( mesh.verts, mesh.numVerts() ) )
|
||||
vert.xyz += e.origin;
|
||||
|
||||
/* iterate through the mesh quads */
|
||||
for ( int y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ) /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts */
|
||||
const bspDrawVert_t *dv[ 4 ] = {
|
||||
&mesh->verts[ pw[ r + 0 ] ],
|
||||
&mesh->verts[ pw[ r + 1 ] ],
|
||||
&mesh->verts[ pw[ r + 2 ] ],
|
||||
&mesh->verts[ pw[ r + 3 ] ]
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ]
|
||||
};
|
||||
/* planar? (nuking this optimization as it doesn't work on non-rectangular quads) */
|
||||
if ( 0 && PlaneFromPoints( plane, dv[ 0 ]->xyz, dv[ 1 ]->xyz, dv[ 2 ]->xyz ) &&
|
||||
@@ -465,7 +459,7 @@ void ProcessDecals(){
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
free( mesh );
|
||||
mesh.freeVerts();
|
||||
}
|
||||
}
|
||||
/* remove patches from entity */
|
||||
@@ -611,52 +605,42 @@ static void ProjectDecalOntoPatch( decalProjector_t& dp, mapDrawSurface_t& ds ){
|
||||
return;
|
||||
|
||||
/* tesselate the patch */
|
||||
mesh_t src;
|
||||
src.width = ds.patchWidth;
|
||||
src.height = ds.patchHeight;
|
||||
src.verts = ds.verts.data();
|
||||
const int iterations = IterationsForCurve( ds.longestCurve, patchSubdivisions );
|
||||
mesh_t *subdivided = SubdivideMesh2( src, iterations );
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, ds.verts.data() ), IterationsForCurve( ds.longestCurve, patchSubdivisions ) );
|
||||
|
||||
/* iterate through the mesh quads */
|
||||
for ( int y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ) /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* generate decal for first triangle */
|
||||
winding_t w{
|
||||
mesh->verts[ pw[ r + 0 ] ].xyz,
|
||||
mesh->verts[ pw[ r + 1 ] ].xyz,
|
||||
mesh->verts[ pw[ r + 2 ] ].xyz };
|
||||
mesh.verts[ pw[ r + 0 ] ].xyz,
|
||||
mesh.verts[ pw[ r + 1 ] ].xyz,
|
||||
mesh.verts[ pw[ r + 2 ] ].xyz };
|
||||
ProjectDecalOntoWinding( dp, ds, w );
|
||||
|
||||
/* generate decal for second triangle */
|
||||
winding_t w2{
|
||||
mesh->verts[ pw[ r + 0 ] ].xyz,
|
||||
mesh->verts[ pw[ r + 2 ] ].xyz,
|
||||
mesh->verts[ pw[ r + 3 ] ].xyz };
|
||||
mesh.verts[ pw[ r + 0 ] ].xyz,
|
||||
mesh.verts[ pw[ r + 2 ] ].xyz,
|
||||
mesh.verts[ pw[ r + 3 ] ].xyz };
|
||||
ProjectDecalOntoWinding( dp, ds, w2 );
|
||||
}
|
||||
}
|
||||
|
||||
/* clean up */
|
||||
free( mesh );
|
||||
mesh.freeVerts();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+70
-92
@@ -30,6 +30,7 @@
|
||||
|
||||
/* dependencies */
|
||||
#include "q3map2.h"
|
||||
#include <optional>
|
||||
|
||||
|
||||
|
||||
@@ -43,13 +44,10 @@ static int numFogPatchFragments;
|
||||
converts a patch drawsurface to a mesh_t
|
||||
*/
|
||||
|
||||
static mesh_t *DrawSurfToMesh( const mapDrawSurface_t& ds ){
|
||||
mesh_t *m = safe_malloc( sizeof( *m ) );
|
||||
m->width = ds.patchWidth;
|
||||
m->height = ds.patchHeight;
|
||||
m->verts = safe_malloc( sizeof( m->verts[ 0 ] ) * m->width * m->height );
|
||||
memcpy( m->verts, ds.verts.data(), sizeof( m->verts[ 0 ] ) * m->width * m->height );
|
||||
|
||||
static mesh_t DrawSurfToMesh( const mapDrawSurface_t& ds ){
|
||||
const size_t size = sizeof( ds.verts[ 0 ] ) * ds.patchWidth * ds.patchHeight;
|
||||
mesh_t m( ds.patchWidth, ds.patchHeight, safe_malloc( size ) );
|
||||
memcpy( m.verts, ds.verts.data(), size );
|
||||
return m;
|
||||
}
|
||||
|
||||
@@ -59,24 +57,24 @@ static mesh_t *DrawSurfToMesh( const mapDrawSurface_t& ds ){
|
||||
SplitMeshByPlane()
|
||||
chops a mesh by a plane
|
||||
*/
|
||||
|
||||
static void SplitMeshByPlane( mesh_t *in, const Plane3f& plane, mesh_t **front, mesh_t **back ){
|
||||
/// \returns either {front, back} or {front, {}} or {{}, back}
|
||||
/// frees or reuses \param in
|
||||
static std::pair<std::optional<mesh_t>, std::optional<mesh_t>> SplitMeshByPlane( mesh_t& in, const Plane3f& plane ){
|
||||
int w, h, split;
|
||||
float d[MAX_PATCH_SIZE][MAX_PATCH_SIZE];
|
||||
bspDrawVert_t *dv, *v1, *v2;
|
||||
int c_front, c_back, c_on;
|
||||
mesh_t *f, *b;
|
||||
int i;
|
||||
float frac;
|
||||
int frontAprox, backAprox;
|
||||
|
||||
for ( i = 0; i < 2; ++i ) {
|
||||
dv = in->verts;
|
||||
dv = in.verts;
|
||||
c_front = 0;
|
||||
c_back = 0;
|
||||
c_on = 0;
|
||||
for ( h = 0; h < in->height; ++h ) {
|
||||
for ( w = 0; w < in->width; ++w, ++dv ) {
|
||||
for ( h = 0; h < in.height; ++h ) {
|
||||
for ( w = 0; w < in.width; ++w, ++dv ) {
|
||||
d[h][w] = plane3_distance_to_point( plane, dv->xyz );
|
||||
if ( d[h][w] > ON_EPSILON ) {
|
||||
c_front++;
|
||||
@@ -90,21 +88,16 @@ static void SplitMeshByPlane( mesh_t *in, const Plane3f& plane, mesh_t **front,
|
||||
}
|
||||
}
|
||||
|
||||
*front = nullptr;
|
||||
*back = nullptr;
|
||||
|
||||
if ( !c_front ) {
|
||||
*back = in;
|
||||
return;
|
||||
return { {}, in };
|
||||
}
|
||||
if ( !c_back ) {
|
||||
*front = in;
|
||||
return;
|
||||
return { in, {} };
|
||||
}
|
||||
|
||||
// find a split point
|
||||
split = -1;
|
||||
for ( w = 0; w < in->width - 1; ++w ) {
|
||||
for ( w = 0; w < in.width - 1; ++w ) {
|
||||
if ( ( d[0][w] < 0 ) != ( d[0][w + 1] < 0 ) ) {
|
||||
if ( split == -1 ) {
|
||||
split = w;
|
||||
@@ -116,30 +109,27 @@ static void SplitMeshByPlane( mesh_t *in, const Plane3f& plane, mesh_t **front,
|
||||
if ( split == -1 ) {
|
||||
if ( i == 1 ) {
|
||||
Sys_FPrintf( SYS_WRN | SYS_VRBflag, "No crossing points in patch\n" );
|
||||
*front = in;
|
||||
return;
|
||||
return { in, {} };
|
||||
}
|
||||
|
||||
in = TransposeMesh( in );
|
||||
TransposeMesh( in );
|
||||
InvertMesh( in );
|
||||
continue;
|
||||
}
|
||||
|
||||
// make sure the split point stays the same for all other rows
|
||||
for ( h = 1; h < in->height; ++h ) {
|
||||
for ( w = 0; w < in->width - 1; ++w ) {
|
||||
for ( h = 1; h < in.height; ++h ) {
|
||||
for ( w = 0; w < in.width - 1; ++w ) {
|
||||
if ( ( d[h][w] < 0 ) != ( d[h][w + 1] < 0 ) ) {
|
||||
if ( w != split ) {
|
||||
Sys_Printf( "multiple crossing points for patch -- can't clip\n" );
|
||||
*front = in;
|
||||
return;
|
||||
return { in, {} };
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( ( d[h][split] < 0 ) == ( d[h][split + 1] < 0 ) ) {
|
||||
Sys_Printf( "differing crossing points for patch -- can't clip\n" );
|
||||
*front = in;
|
||||
return;
|
||||
return { in, {} };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -148,63 +138,49 @@ static void SplitMeshByPlane( mesh_t *in, const Plane3f& plane, mesh_t **front,
|
||||
|
||||
|
||||
// create two new meshes
|
||||
f = safe_malloc( sizeof( *f ) );
|
||||
f->width = split + 2;
|
||||
if ( !( f->width & 1 ) ) {
|
||||
f->width++;
|
||||
mesh_t f( split + 2, in.height, nullptr ), b( in.width - split, in.height, nullptr );
|
||||
if ( !( f.width & 1 ) ) {
|
||||
f.width++;
|
||||
frontAprox = 1;
|
||||
}
|
||||
else {
|
||||
frontAprox = 0;
|
||||
}
|
||||
if ( f->width > MAX_PATCH_SIZE ) {
|
||||
if ( f.width > MAX_PATCH_SIZE ) {
|
||||
Error( "MAX_PATCH_SIZE after split" );
|
||||
}
|
||||
f->height = in->height;
|
||||
f->verts = safe_malloc( sizeof( f->verts[0] ) * f->width * f->height );
|
||||
f.verts = safe_malloc( sizeof( f.verts[0] ) * f.numVerts() );
|
||||
|
||||
b = safe_malloc( sizeof( *b ) );
|
||||
b->width = in->width - split;
|
||||
if ( !( b->width & 1 ) ) {
|
||||
b->width++;
|
||||
if ( !( b.width & 1 ) ) {
|
||||
b.width++;
|
||||
backAprox = 1;
|
||||
}
|
||||
else {
|
||||
backAprox = 0;
|
||||
}
|
||||
if ( b->width > MAX_PATCH_SIZE ) {
|
||||
if ( b.width > MAX_PATCH_SIZE ) {
|
||||
Error( "MAX_PATCH_SIZE after split" );
|
||||
}
|
||||
b->height = in->height;
|
||||
b->verts = safe_malloc( sizeof( b->verts[0] ) * b->width * b->height );
|
||||
|
||||
if ( d[0][0] > 0 ) {
|
||||
*front = f;
|
||||
*back = b;
|
||||
}
|
||||
else {
|
||||
*front = b;
|
||||
*back = f;
|
||||
}
|
||||
b.verts = safe_malloc( sizeof( b.verts[0] ) * b.numVerts() );
|
||||
|
||||
// distribute the points
|
||||
for ( w = 0; w < in->width; ++w ) {
|
||||
for ( h = 0; h < in->height; ++h ) {
|
||||
for ( w = 0; w < in.width; ++w ) {
|
||||
for ( h = 0; h < in.height; ++h ) {
|
||||
if ( w <= split ) {
|
||||
f->verts[ h * f->width + w ] = in->verts[ h * in->width + w ];
|
||||
f.verts[ h * f.width + w ] = in.verts[ h * in.width + w ];
|
||||
}
|
||||
else {
|
||||
b->verts[ h * b->width + w - split + backAprox ] = in->verts[ h * in->width + w ];
|
||||
b.verts[ h * b.width + w - split + backAprox ] = in.verts[ h * in.width + w ];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clip the crossing line
|
||||
for ( h = 0; h < in->height; ++h )
|
||||
for ( h = 0; h < in.height; ++h )
|
||||
{
|
||||
dv = &f->verts[ h * f->width + split + 1 ];
|
||||
v1 = &in->verts[ h * in->width + split ];
|
||||
v2 = &in->verts[ h * in->width + split + 1 ];
|
||||
dv = &f.verts[ h * f.width + split + 1 ];
|
||||
v1 = &in.verts[ h * in.width + split ];
|
||||
v2 = &in.verts[ h * in.width + split + 1 ];
|
||||
|
||||
frac = d[h][split] / ( d[h][split] - d[h][split + 1] );
|
||||
|
||||
@@ -215,24 +191,28 @@ static void SplitMeshByPlane( mesh_t *in, const Plane3f& plane, mesh_t **front,
|
||||
LerpDrawVertAmount( v1, v2, frac, dv );
|
||||
|
||||
if ( frontAprox ) {
|
||||
f->verts[ h * f->width + split + 2 ] = *dv;
|
||||
f.verts[ h * f.width + split + 2 ] = *dv;
|
||||
}
|
||||
b->verts[ h * b->width ] = *dv;
|
||||
b.verts[ h * b.width ] = *dv;
|
||||
if ( backAprox ) {
|
||||
b->verts[ h * b->width + 1 ] = *dv;
|
||||
b.verts[ h * b.width + 1 ] = *dv;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
PrintMesh( in );
|
||||
Sys_Printf( "\n" );
|
||||
PrintMesh( f );
|
||||
Sys_Printf( "\n" );
|
||||
PrintMesh( b );
|
||||
Sys_Printf( "\n" );
|
||||
*/
|
||||
|
||||
FreeMesh( in );
|
||||
in.freeVerts();
|
||||
|
||||
if ( d[0][0] > 0 )
|
||||
return { f, b };
|
||||
else
|
||||
return { b, f };
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
@@ -242,74 +222,72 @@ static void SplitMeshByPlane( mesh_t *in, const Plane3f& plane, mesh_t **front,
|
||||
*/
|
||||
|
||||
static bool ChopPatchSurfaceByBrush( mapDrawSurface_t& ds, const brush_t *b ){
|
||||
int i, j;
|
||||
mesh_t *outside[MAX_BRUSH_SIDES];
|
||||
int numOutside;
|
||||
mesh_t *m, *front, *back;
|
||||
mesh_t outside[MAX_BRUSH_SIDES];
|
||||
int numOutside = 0;
|
||||
|
||||
m = DrawSurfToMesh( ds );
|
||||
numOutside = 0;
|
||||
mesh_t m = DrawSurfToMesh( ds );
|
||||
|
||||
// only split by the top and bottom planes to avoid
|
||||
// some messy patch clipping issues
|
||||
|
||||
for ( i = 4; i <= 5; ++i ) {
|
||||
for ( int i = 4; i <= 5; ++i ) {
|
||||
const plane_t& plane = mapplanes[ b->sides[ i ].planenum ];
|
||||
|
||||
SplitMeshByPlane( m, plane.plane, &front, &back );
|
||||
auto [front, back] = SplitMeshByPlane( m, plane.plane );
|
||||
|
||||
if ( !back ) {
|
||||
// nothing actually contained inside
|
||||
for ( j = 0; j < numOutside; ++j ) {
|
||||
FreeMesh( outside[j] );
|
||||
for ( int j = 0; j < numOutside; ++j ) {
|
||||
outside[j].freeVerts();
|
||||
}
|
||||
front->freeVerts();
|
||||
return false;
|
||||
}
|
||||
m = back;
|
||||
m = *back;
|
||||
|
||||
if ( front ) {
|
||||
if ( numOutside == MAX_BRUSH_SIDES ) {
|
||||
Error( "MAX_BRUSH_SIDES" );
|
||||
}
|
||||
outside[ numOutside ] = front;
|
||||
outside[ numOutside ] = *front;
|
||||
numOutside++;
|
||||
}
|
||||
}
|
||||
|
||||
/* all of outside fragments become separate drawsurfs */
|
||||
numFogPatchFragments += numOutside;
|
||||
for ( i = 0; i < numOutside; ++i )
|
||||
for ( int i = 0; i < numOutside; ++i )
|
||||
{
|
||||
/* transpose and invert the chopped patch (fixes potential crash. fixme: why?) */
|
||||
outside[ i ] = TransposeMesh( outside[ i ] );
|
||||
TransposeMesh( outside[ i ] );
|
||||
InvertMesh( outside[ i ] );
|
||||
|
||||
/* ydnar: do this the hacky right way */
|
||||
mapDrawSurface_t& newds = AllocDrawSurface( ESurfaceType::Patch );
|
||||
newds = ds;
|
||||
newds.patchWidth = outside[ i ]->width;
|
||||
newds.patchHeight = outside[ i ]->height;
|
||||
newds.verts.assign( outside[ i ]->verts, outside[ i ]->verts + newds.patchWidth * newds.patchHeight );
|
||||
newds.patchWidth = outside[ i ].width;
|
||||
newds.patchHeight = outside[ i ].height;
|
||||
newds.verts.assign( outside[ i ].verts, outside[ i ].verts + outside[ i ].numVerts() );
|
||||
|
||||
/* free the source mesh */
|
||||
FreeMesh( outside[ i ] );
|
||||
outside[ i ].freeVerts();
|
||||
}
|
||||
|
||||
/* only rejigger this patch if it was chopped */
|
||||
//% Sys_Printf( "Inside: %d x %d\n", m->width, m->height );
|
||||
//% Sys_Printf( "Inside: %d x %d\n", m.width, m.height );
|
||||
if ( numOutside > 0 ) {
|
||||
/* transpose and invert the chopped patch (fixes potential crash. fixme: why?) */
|
||||
m = TransposeMesh( m );
|
||||
TransposeMesh( m );
|
||||
InvertMesh( m );
|
||||
|
||||
/* replace ds with m */
|
||||
ds.patchWidth = m->width;
|
||||
ds.patchHeight = m->height;
|
||||
ds.verts.assign( m->verts, m->verts + ds.patchWidth * ds.patchHeight );
|
||||
ds.patchWidth = m.width;
|
||||
ds.patchHeight = m.height;
|
||||
ds.verts.assign( m.verts, m.verts + m.numVerts() );
|
||||
}
|
||||
|
||||
/* free the source mesh and return */
|
||||
FreeMesh( m );
|
||||
m.freeVerts();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -648,22 +648,13 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, const shader
|
||||
|
||||
/* build a subdivided mesh identical to shadow facets for this patch */
|
||||
/* this MUST MATCH FacetsForPatch() identically! */
|
||||
mesh_t src;
|
||||
src.width = ds.patchWidth;
|
||||
src.height = ds.patchHeight;
|
||||
src.verts = bogus;
|
||||
//% mesh_t *subdivided = SubdivideMesh( src, 8, 512 );
|
||||
mesh_t *subdivided = SubdivideMesh2( src, info.patchIterations );
|
||||
PutMeshOnCurve( *subdivided );
|
||||
//% MakeMeshNormals( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, bogus ), info.patchIterations );
|
||||
free( bogus );
|
||||
|
||||
/* FIXME: build interpolation table into color[ 1 ] */
|
||||
|
||||
/* fix up color indexes */
|
||||
for ( bspDrawVert_t& vert : Span( mesh->verts, mesh->width * mesh->height ) )
|
||||
for ( bspDrawVert_t& vert : Span( mesh.verts, mesh.numVerts() ) )
|
||||
{
|
||||
if ( vert.color[ 0 ][ 0 ] >= ds.numVerts ) {
|
||||
vert.color[ 0 ][ 0 ] = ds.numVerts - 1;
|
||||
@@ -671,27 +662,27 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, const shader
|
||||
}
|
||||
|
||||
/* iterate through the mesh quads */
|
||||
for ( int y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ) /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts */
|
||||
const bspDrawVert_t *dv[ 4 ] = {
|
||||
&mesh->verts[ pw[ r + 0 ] ],
|
||||
&mesh->verts[ pw[ r + 1 ] ],
|
||||
&mesh->verts[ pw[ r + 2 ] ],
|
||||
&mesh->verts[ pw[ r + 3 ] ]
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ]
|
||||
};
|
||||
/* planar? */
|
||||
Plane3f plane;
|
||||
@@ -756,7 +747,7 @@ void RadLightForPatch( int num, int lightmapNum, rawLightmap_t *lm, const shader
|
||||
}
|
||||
|
||||
/* free the mesh */
|
||||
FreeMesh( mesh );
|
||||
mesh.freeVerts();
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -891,56 +891,43 @@ static void PopulateWithBSPModel( const bspModel_t& model, const Matrix4& transf
|
||||
case MST_PATCH:
|
||||
{
|
||||
/* subdivide the surface */
|
||||
mesh_t srcMesh;
|
||||
srcMesh.width = ds.patchWidth;
|
||||
srcMesh.height = ds.patchHeight;
|
||||
srcMesh.verts = &bspDrawVerts[ ds.firstVert ];
|
||||
//% mesh_t *subdivided = SubdivideMesh( srcMesh, 8, 512 );
|
||||
mesh_t *subdivided = SubdivideMesh2( srcMesh, info.patchIterations );
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
|
||||
/* set verts */
|
||||
const bspDrawVert_t *verts = mesh->verts;
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, &bspDrawVerts[ ds.firstVert ] ), info.patchIterations );
|
||||
|
||||
/* subdivide each quad to place the models */
|
||||
for ( int y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ) /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* make first triangle */
|
||||
tw.v[ 0 ].xyz = verts[ pw[ r + 0 ] ].xyz;
|
||||
tw.v[ 0 ].st = verts[ pw[ r + 0 ] ].st;
|
||||
tw.v[ 1 ].xyz = verts[ pw[ r + 1 ] ].xyz;
|
||||
tw.v[ 1 ].st = verts[ pw[ r + 1 ] ].st;
|
||||
tw.v[ 2 ].xyz = verts[ pw[ r + 2 ] ].xyz;
|
||||
tw.v[ 2 ].st = verts[ pw[ r + 2 ] ].st;
|
||||
tw.v[ 0 ].xyz = mesh.verts[ pw[ r + 0 ] ].xyz;
|
||||
tw.v[ 0 ].st = mesh.verts[ pw[ r + 0 ] ].st;
|
||||
tw.v[ 1 ].xyz = mesh.verts[ pw[ r + 1 ] ].xyz;
|
||||
tw.v[ 1 ].st = mesh.verts[ pw[ r + 1 ] ].st;
|
||||
tw.v[ 2 ].xyz = mesh.verts[ pw[ r + 2 ] ].xyz;
|
||||
tw.v[ 2 ].st = mesh.verts[ pw[ r + 2 ] ].st;
|
||||
matrix4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
FilterTraceWindingIntoNodes_r( &tw, nodeNum );
|
||||
|
||||
/* make second triangle */
|
||||
tw.v[ 0 ].xyz = verts[ pw[ r + 0 ] ].xyz;
|
||||
tw.v[ 0 ].st = verts[ pw[ r + 0 ] ].st;
|
||||
tw.v[ 1 ].xyz = verts[ pw[ r + 2 ] ].xyz;
|
||||
tw.v[ 1 ].st = verts[ pw[ r + 2 ] ].st;
|
||||
tw.v[ 2 ].xyz = verts[ pw[ r + 3 ] ].xyz;
|
||||
tw.v[ 2 ].st = verts[ pw[ r + 3 ] ].st;
|
||||
tw.v[ 0 ].xyz = mesh.verts[ pw[ r + 0 ] ].xyz;
|
||||
tw.v[ 0 ].st = mesh.verts[ pw[ r + 0 ] ].st;
|
||||
tw.v[ 1 ].xyz = mesh.verts[ pw[ r + 2 ] ].xyz;
|
||||
tw.v[ 1 ].st = mesh.verts[ pw[ r + 2 ] ].st;
|
||||
tw.v[ 2 ].xyz = mesh.verts[ pw[ r + 3 ] ].xyz;
|
||||
tw.v[ 2 ].st = mesh.verts[ pw[ r + 3 ] ].st;
|
||||
matrix4_transform_point( transform, tw.v[ 0 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 1 ].xyz );
|
||||
matrix4_transform_point( transform, tw.v[ 2 ].xyz );
|
||||
@@ -949,7 +936,7 @@ static void PopulateWithBSPModel( const bspModel_t& model, const Matrix4& transf
|
||||
}
|
||||
|
||||
/* free the subdivided mesh */
|
||||
FreeMesh( mesh );
|
||||
mesh.freeVerts();
|
||||
break;
|
||||
}
|
||||
/* handle triangle surfaces */
|
||||
|
||||
@@ -1218,20 +1218,7 @@ void MapRawLightmap( int rawLightmapNum ){
|
||||
case MST_PATCH:
|
||||
{
|
||||
/* make a mesh from the drawsurf */
|
||||
mesh_t src;
|
||||
src.width = ds.patchWidth;
|
||||
src.height = ds.patchHeight;
|
||||
src.verts = &yDrawVerts[ ds.firstVert ];
|
||||
//% mesh_t *subdivided = SubdivideMesh( src, 8, 512 );
|
||||
mesh_t *subdivided = SubdivideMesh2( src, info->patchIterations );
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
|
||||
/* get verts */
|
||||
const bspDrawVert_t *verts = mesh->verts;
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, &yDrawVerts[ ds.firstVert ] ), info->patchIterations );
|
||||
|
||||
/* debug code */
|
||||
#if 0
|
||||
@@ -1248,59 +1235,59 @@ void MapRawLightmap( int rawLightmapNum ){
|
||||
|
||||
for ( mapNonAxial = 0; mapNonAxial < 2; ++mapNonAxial )
|
||||
{
|
||||
for ( y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ) /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts and map first triangle */
|
||||
MapTriangle( lm, info, TriRef{
|
||||
&verts[ pw[ r + 0 ] ],
|
||||
&verts[ pw[ r + 1 ] ],
|
||||
&verts[ pw[ r + 2 ] ] }, mapNonAxial );
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ] }, mapNonAxial );
|
||||
|
||||
/* get drawverts and map second triangle */
|
||||
MapTriangle( lm, info, TriRef{
|
||||
&verts[ pw[ r + 0 ] ],
|
||||
&verts[ pw[ r + 2 ] ],
|
||||
&verts[ pw[ r + 3 ] ] }, mapNonAxial );
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] }, mapNonAxial );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
for ( y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ) /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* attempt to map quad first */
|
||||
if ( MapQuad( lm, info, QuadRef{
|
||||
&verts[ pw[ r + 0 ] ],
|
||||
&verts[ pw[ r + 1 ] ],
|
||||
&verts[ pw[ r + 2 ] ],
|
||||
&verts[ pw[ r + 3 ] ] } ) ) {
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] } ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -1308,15 +1295,15 @@ void MapRawLightmap( int rawLightmapNum ){
|
||||
{
|
||||
/* get drawverts and map first triangle */
|
||||
MapTriangle( lm, info, TriRef{
|
||||
&verts[ pw[ r + 0 ] ],
|
||||
&verts[ pw[ r + 1 ] ],
|
||||
&verts[ pw[ r + 2 ] ] }, mapNonAxial );
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ] }, mapNonAxial );
|
||||
|
||||
/* get drawverts and map second triangle */
|
||||
MapTriangle( lm, info, TriRef{
|
||||
&verts[ pw[ r + 0 ] ],
|
||||
&verts[ pw[ r + 2 ] ],
|
||||
&verts[ pw[ r + 3 ] ] }, mapNonAxial );
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] }, mapNonAxial );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1324,7 +1311,7 @@ void MapRawLightmap( int rawLightmapNum ){
|
||||
#endif
|
||||
|
||||
/* free the mesh */
|
||||
FreeMesh( mesh );
|
||||
mesh.freeVerts();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -452,7 +452,6 @@ static void FinishRawLightmap( rawLightmap_t& lm ){
|
||||
*/
|
||||
|
||||
static bool AddPatchToRawLightmap( int num, rawLightmap_t& lm ){
|
||||
bspDrawVert_t *verts, *a, *b;
|
||||
float sBasis, tBasis, s, t;
|
||||
float length, widthTable[ MAX_EXPANDED_AXIS ] = {0}, heightTable[ MAX_EXPANDED_AXIS ] = {0};
|
||||
|
||||
@@ -465,43 +464,32 @@ static bool AddPatchToRawLightmap( int num, rawLightmap_t& lm ){
|
||||
const surfaceInfo_t& info = surfaceInfos[ num ];
|
||||
|
||||
/* make a temporary mesh from the drawsurf */
|
||||
mesh_t src;
|
||||
src.width = ds.patchWidth;
|
||||
src.height = ds.patchHeight;
|
||||
src.verts = &yDrawVerts[ ds.firstVert ];
|
||||
//% mesh_t *subdivided = SubdivideMesh( src, 8, 512 );
|
||||
mesh_t *subdivided = SubdivideMesh2( src, info.patchIterations );
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, &yDrawVerts[ ds.firstVert ] ), info.patchIterations );
|
||||
|
||||
/* find the longest distance on each row/column */
|
||||
verts = mesh->verts;
|
||||
for ( int y = 0; y < mesh->height; ++y )
|
||||
for ( int y = 0; y < mesh.height; ++y )
|
||||
{
|
||||
for ( int x = 0; x < mesh->width; ++x )
|
||||
for ( int x = 0; x < mesh.width; ++x )
|
||||
{
|
||||
/* get width */
|
||||
if ( x + 1 < mesh->width ) {
|
||||
a = &verts[ ( y * mesh->width ) + x ];
|
||||
b = &verts[ ( y * mesh->width ) + x + 1 ];
|
||||
value_maximize( widthTable[ x ], (float)vector3_length( a->xyz - b->xyz ) );
|
||||
if ( x + 1 < mesh.width ) {
|
||||
const bspDrawVert_t& a = mesh.verts[ ( y * mesh.width ) + x ];
|
||||
const bspDrawVert_t& b = mesh.verts[ ( y * mesh.width ) + x + 1 ];
|
||||
value_maximize( widthTable[ x ], (float)vector3_length( a.xyz - b.xyz ) );
|
||||
}
|
||||
|
||||
/* get height */
|
||||
if ( y + 1 < mesh->height ) {
|
||||
a = &verts[ ( y * mesh->width ) + x ];
|
||||
b = &verts[ ( ( y + 1 ) * mesh->width ) + x ];
|
||||
value_maximize( heightTable[ y ], (float)vector3_length( a->xyz - b->xyz ) );
|
||||
if ( y + 1 < mesh.height ) {
|
||||
const bspDrawVert_t& a = mesh.verts[ ( y * mesh.width ) + x ];
|
||||
const bspDrawVert_t& b = mesh.verts[ ( ( y + 1 ) * mesh.width ) + x ];
|
||||
value_maximize( heightTable[ y ], (float)vector3_length( a.xyz - b.xyz ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* determine lightmap width */
|
||||
length = 0;
|
||||
for ( int x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
length += widthTable[ x ];
|
||||
lm.w = lm.sampleSize != 0 ? ceil( length / lm.sampleSize ) + 1 : 0;
|
||||
value_maximize( lm.w, ds.patchWidth );
|
||||
@@ -510,7 +498,7 @@ static bool AddPatchToRawLightmap( int num, rawLightmap_t& lm ){
|
||||
|
||||
/* determine lightmap height */
|
||||
length = 0;
|
||||
for ( int y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
length += heightTable[ y ];
|
||||
lm.h = lm.sampleSize != 0 ? ceil( length / lm.sampleSize ) + 1 : 0;
|
||||
value_maximize( lm.h, ds.patchHeight );
|
||||
@@ -518,12 +506,12 @@ static bool AddPatchToRawLightmap( int num, rawLightmap_t& lm ){
|
||||
tBasis = (float) ( lm.h - 1 ) / ( ds.patchHeight - 1 );
|
||||
|
||||
/* free the temporary mesh */
|
||||
FreeMesh( mesh );
|
||||
mesh.freeVerts();
|
||||
|
||||
/* set the lightmap texture coordinates in yDrawVerts */
|
||||
lm.wrap[ 0 ] = true;
|
||||
lm.wrap[ 1 ] = true;
|
||||
verts = &yDrawVerts[ ds.firstVert ];
|
||||
bspDrawVert_t *verts = &yDrawVerts[ ds.firstVert ];
|
||||
for ( int y = 0; y < ds.patchHeight; ++y )
|
||||
{
|
||||
t = ( tBasis * y ) + 0.5f;
|
||||
@@ -1675,56 +1663,43 @@ static bool ApproximateLightmap( rawLightmap_t *lm ){
|
||||
case MST_PATCH:
|
||||
{
|
||||
/* make a mesh from the drawsurf */
|
||||
mesh_t src;
|
||||
src.width = ds.patchWidth;
|
||||
src.height = ds.patchHeight;
|
||||
src.verts = &yDrawVerts[ ds.firstVert ];
|
||||
//% mesh_t *subdivided = SubdivideMesh( src, 8, 512 );
|
||||
mesh_t *subdivided = SubdivideMesh2( src, info.patchIterations );
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
|
||||
/* get verts */
|
||||
const bspDrawVert_t *verts = mesh->verts;
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, &yDrawVerts[ ds.firstVert ] ), info.patchIterations );
|
||||
|
||||
/* map the mesh quads */
|
||||
info.approximated = true;
|
||||
for ( int y = 0; y < ( mesh->height - 1 ) && info.approximated; ++y )
|
||||
for ( int y = 0; y < ( mesh.height - 1 ) && info.approximated; ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh->width - 1 ) && info.approximated; ++x )
|
||||
for ( int x = 0; x < ( mesh.width - 1 ) && info.approximated; ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ) /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts and map first triangle */
|
||||
info.approximated = ApproximateTriangle_r( lm, TriRef{
|
||||
&verts[ pw[ r + 0 ] ],
|
||||
&verts[ pw[ r + 1 ] ],
|
||||
&verts[ pw[ r + 2 ] ] } );
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ] } );
|
||||
|
||||
/* get drawverts and map second triangle */
|
||||
if ( info.approximated ) {
|
||||
info.approximated = ApproximateTriangle_r( lm, TriRef{
|
||||
&verts[ pw[ r + 0 ] ],
|
||||
&verts[ pw[ r + 2 ] ],
|
||||
&verts[ pw[ r + 3 ] ] } );
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* free the mesh */
|
||||
FreeMesh( mesh );
|
||||
mesh.freeVerts();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -1240,7 +1240,7 @@ static void AdjustBrushesForOrigin( entity_t& ent ){
|
||||
/* walk patch list */
|
||||
for ( parseMesh_t& p : ent.patches )
|
||||
{
|
||||
for ( bspDrawVert_t& vert : Span( p.mesh.verts, p.mesh.width * p.mesh.height ) )
|
||||
for ( bspDrawVert_t& vert : Span( p.mesh.verts, p.mesh.numVerts() ) )
|
||||
vert.xyz -= ent.originbrush_origin;
|
||||
}
|
||||
}
|
||||
@@ -1303,7 +1303,7 @@ static void SetEntityBounds( entity_t& e ){
|
||||
}
|
||||
for ( const parseMesh_t& p : e.patches )
|
||||
{
|
||||
for ( const bspDrawVert_t& vert : Span( p.mesh.verts, p.mesh.width * p.mesh.height ) )
|
||||
for ( const bspDrawVert_t& vert : Span( p.mesh.verts, p.mesh.numVerts() ) )
|
||||
minmax.extend( vert.xyz );
|
||||
}
|
||||
|
||||
|
||||
+71
-100
@@ -91,33 +91,24 @@ void LerpDrawVertAmount( bspDrawVert_t *a, bspDrawVert_t *b, float amount, bspDr
|
||||
}
|
||||
|
||||
|
||||
void FreeMesh( mesh_t *m ) {
|
||||
free( m->verts );
|
||||
free( m );
|
||||
}
|
||||
|
||||
void PrintMesh( mesh_t *m ) {
|
||||
for ( int i = 0; i < m->height; ++i ) {
|
||||
for ( int j = 0; j < m->width; ++j ) {
|
||||
void PrintMesh( const mesh_t m ) {
|
||||
for ( int i = 0; i < m.height; ++i ) {
|
||||
for ( int j = 0; j < m.width; ++j ) {
|
||||
Sys_Printf( "(%5.2f %5.2f %5.2f) "
|
||||
, m->verts[i * m->width + j].xyz[0]
|
||||
, m->verts[i * m->width + j].xyz[1]
|
||||
, m->verts[i * m->width + j].xyz[2] );
|
||||
, m.verts[i * m.width + j].xyz[0]
|
||||
, m.verts[i * m.width + j].xyz[1]
|
||||
, m.verts[i * m.width + j].xyz[2] );
|
||||
}
|
||||
Sys_Printf( "\n" );
|
||||
}
|
||||
Sys_Printf( "\n" );
|
||||
}
|
||||
|
||||
|
||||
mesh_t *CopyMesh( mesh_t *mesh ) {
|
||||
mesh_t *out = safe_malloc( sizeof( *out ) );
|
||||
out->width = mesh->width;
|
||||
out->height = mesh->height;
|
||||
|
||||
const size_t size = out->width * out->height * sizeof( *out->verts );
|
||||
out->verts = safe_malloc( size );
|
||||
memcpy( out->verts, mesh->verts, size );
|
||||
|
||||
mesh_t CopyMesh( const mesh_t m ) {
|
||||
const size_t size = m.numVerts() * sizeof( *m.verts );
|
||||
mesh_t out( m.width, m.height, safe_malloc( size ) );
|
||||
memcpy( out.verts, m.verts, size );
|
||||
return out;
|
||||
}
|
||||
|
||||
@@ -127,29 +118,25 @@ mesh_t *CopyMesh( mesh_t *mesh ) {
|
||||
returns a transposed copy of the mesh, freeing the original
|
||||
*/
|
||||
|
||||
mesh_t *TransposeMesh( mesh_t *in ) {
|
||||
mesh_t *out = safe_malloc( sizeof( *out ) );
|
||||
out->width = in->height;
|
||||
out->height = in->width;
|
||||
out->verts = safe_malloc( out->width * out->height * sizeof( bspDrawVert_t ) );
|
||||
void TransposeMesh( mesh_t& m ) {
|
||||
mesh_t out( m.height, m.width, safe_malloc( m.numVerts() * sizeof( *m.verts ) ) ); // swap width/height
|
||||
|
||||
for ( int h = 0; h < in->height; ++h ) {
|
||||
for ( int w = 0; w < in->width; ++w ) {
|
||||
out->verts[ w * in->height + h ] = in->verts[ h * in->width + w ];
|
||||
for ( int h = 0; h < m.height; ++h ) {
|
||||
for ( int w = 0; w < m.width; ++w ) {
|
||||
out.verts[ w * m.height + h ] = m.verts[ h * m.width + w ];
|
||||
}
|
||||
}
|
||||
|
||||
FreeMesh( in );
|
||||
|
||||
return out;
|
||||
m.freeVerts();
|
||||
m = out;
|
||||
}
|
||||
|
||||
void InvertMesh( mesh_t *in ) {
|
||||
for ( int h = 0; h < in->height; ++h ) {
|
||||
for ( int w = 0; w < in->width / 2; ++w ) {
|
||||
void InvertMesh( mesh_t& m ) {
|
||||
for ( int h = 0; h < m.height; ++h ) {
|
||||
for ( int w = 0; w < m.width / 2; ++w ) {
|
||||
std::swap(
|
||||
in->verts[ h * in->width + w ],
|
||||
in->verts[ h * in->width + in->width - 1 - w ]
|
||||
m.verts[ h * m.width + w ],
|
||||
m.verts[ h * m.width + m.width - 1 - w ]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -161,7 +148,7 @@ void InvertMesh( mesh_t *in ) {
|
||||
|
||||
=================
|
||||
*/
|
||||
void MakeMeshNormals( mesh_t in ){
|
||||
void MakeMeshNormals( mesh_t& in ){
|
||||
int i, j, k, dist;
|
||||
int count;
|
||||
int x, y;
|
||||
@@ -267,7 +254,7 @@ void MakeMeshNormals( mesh_t in ){
|
||||
drops the aproximating points onto the curve
|
||||
*/
|
||||
|
||||
void PutMeshOnCurve( mesh_t in ) {
|
||||
void PutMeshOnCurve( mesh_t& in ) {
|
||||
const auto lerp3 = []( const bspDrawVert_t& prev, bspDrawVert_t& mid, const bspDrawVert_t& next ){
|
||||
mid.xyz = ( prev.xyz + mid.xyz * 2 + next.xyz ) * .25;
|
||||
/* ydnar: interpolating st coords */
|
||||
@@ -296,19 +283,13 @@ void PutMeshOnCurve( mesh_t in ) {
|
||||
|
||||
=================
|
||||
*/
|
||||
mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ){
|
||||
mesh_t out;
|
||||
mesh_t SubdivideMesh( const mesh_t in, float maxError, float minLength ){
|
||||
bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
|
||||
mesh_t out( in.width, in.height, expand[0] );
|
||||
|
||||
|
||||
out.width = in.width;
|
||||
out.height = in.height;
|
||||
|
||||
for ( int i = 0; i < in.width; ++i ) {
|
||||
for ( int j = 0; j < in.height; ++j ) {
|
||||
expand[j][i] = in.verts[j * in.width + i];
|
||||
}
|
||||
}
|
||||
for ( int h = 0; h < in.height; ++h )
|
||||
std::copy_n( &in.verts[h * in.width], in.width, expand[h] );
|
||||
|
||||
// horizontal subdivisions
|
||||
for ( int i, j = 0; j + 2 < out.width; j += 2 ) {
|
||||
@@ -399,12 +380,11 @@ mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength ){
|
||||
|
||||
// collapse the verts
|
||||
|
||||
out.verts = &expand[0][0];
|
||||
for ( int i = 1; i < out.height; ++i ) {
|
||||
memmove( &out.verts[i * out.width], expand[i], out.width * sizeof( bspDrawVert_t ) );
|
||||
}
|
||||
|
||||
return CopyMesh( &out );
|
||||
return CopyMesh( out );
|
||||
}
|
||||
|
||||
|
||||
@@ -438,19 +418,14 @@ int IterationsForCurve( float len, int subdivisions ){
|
||||
subdivides each mesh quad a specified number of times
|
||||
*/
|
||||
|
||||
mesh_t *SubdivideMesh2( mesh_t in, int iterations ){
|
||||
mesh_t out;
|
||||
mesh_t SubdivideMesh2( const mesh_t in, int iterations ){
|
||||
bspDrawVert_t expand[ MAX_EXPANDED_AXIS ][ MAX_EXPANDED_AXIS ];
|
||||
mesh_t out( in.width, in.height, expand[0] );
|
||||
|
||||
|
||||
/* initial setup */
|
||||
out.width = in.width;
|
||||
out.height = in.height;
|
||||
for ( int i = 0; i < in.width; ++i )
|
||||
{
|
||||
for ( int j = 0; j < in.height; ++j )
|
||||
expand[ j ][ i ] = in.verts[ j * in.width + i ];
|
||||
}
|
||||
for ( int h = 0; h < in.height; ++h )
|
||||
std::copy_n( &in.verts[h * in.width], in.width, expand[h] );
|
||||
|
||||
/* keep chopping */
|
||||
for ( ; iterations > 0; --iterations )
|
||||
@@ -499,12 +474,11 @@ mesh_t *SubdivideMesh2( mesh_t in, int iterations ){
|
||||
}
|
||||
|
||||
/* collapse the verts */
|
||||
out.verts = &expand[ 0 ][ 0 ];
|
||||
for ( int i = 1; i < out.height; ++i )
|
||||
memmove( &out.verts[ i * out.width ], expand[ i ], out.width * sizeof( bspDrawVert_t ) );
|
||||
|
||||
/* return to sender */
|
||||
return CopyMesh( &out );
|
||||
return CopyMesh( out );
|
||||
}
|
||||
|
||||
|
||||
@@ -530,46 +504,38 @@ inline Vector3 ProjectPointOntoVector( const Vector3& point, const Vector3& vSta
|
||||
RemoveLinearMeshColumsRows
|
||||
================
|
||||
*/
|
||||
mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) {
|
||||
int i, j, k;
|
||||
mesh_t out;
|
||||
|
||||
mesh_t RemoveLinearMeshColumnsRows( const mesh_t in ) {
|
||||
bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
|
||||
mesh_t out( in.width, in.height, expand[0] );
|
||||
|
||||
|
||||
out.width = in->width;
|
||||
out.height = in->height;
|
||||
for ( int h = 0; h < in.height; ++h )
|
||||
std::copy_n( &in.verts[h * in.width], in.width, expand[h] );
|
||||
|
||||
for ( i = 0; i < in->width; ++i ) {
|
||||
for ( j = 0; j < in->height; ++j ) {
|
||||
expand[j][i] = in->verts[j * in->width + i];
|
||||
}
|
||||
}
|
||||
|
||||
for ( j = 1; j < out.width - 1; ++j ) {
|
||||
for ( int j = 1; j < out.width - 1; ++j ) {
|
||||
double maxLength = 0;
|
||||
for ( i = 0; i < out.height; ++i ) {
|
||||
for ( int i = 0; i < out.height; ++i ) {
|
||||
value_maximize( maxLength, vector3_length( expand[i][j].xyz - ProjectPointOntoVector( expand[i][j].xyz, expand[i][j - 1].xyz, expand[i][j + 1].xyz ) ) );
|
||||
}
|
||||
if ( maxLength < 0.1 ) {
|
||||
out.width--;
|
||||
for ( i = 0; i < out.height; ++i ) {
|
||||
for ( k = j; k < out.width; ++k ) {
|
||||
for ( int i = 0; i < out.height; ++i ) {
|
||||
for ( int k = j; k < out.width; ++k ) {
|
||||
expand[i][k] = expand[i][k + 1];
|
||||
}
|
||||
}
|
||||
j--;
|
||||
}
|
||||
}
|
||||
for ( j = 1; j < out.height - 1; ++j ) {
|
||||
for ( int j = 1; j < out.height - 1; ++j ) {
|
||||
double maxLength = 0;
|
||||
for ( i = 0; i < out.width; ++i ) {
|
||||
for ( int i = 0; i < out.width; ++i ) {
|
||||
value_maximize( maxLength, vector3_length( expand[j][i].xyz - ProjectPointOntoVector( expand[j][i].xyz, expand[j - 1][i].xyz, expand[j + 1][i].xyz ) ) );
|
||||
}
|
||||
if ( maxLength < 0.1 ) {
|
||||
out.height--;
|
||||
for ( i = 0; i < out.width; ++i ) {
|
||||
for ( k = j; k < out.height; ++k ) {
|
||||
for ( int i = 0; i < out.width; ++i ) {
|
||||
for ( int k = j; k < out.height; ++k ) {
|
||||
expand[k][i] = expand[k + 1][i];
|
||||
}
|
||||
}
|
||||
@@ -577,34 +543,40 @@ mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in ) {
|
||||
}
|
||||
}
|
||||
// collapse the verts
|
||||
out.verts = &expand[0][0];
|
||||
for ( i = 1; i < out.height; ++i ) {
|
||||
for ( int i = 1; i < out.height; ++i ) {
|
||||
memmove( &out.verts[i * out.width], expand[i], out.width * sizeof( bspDrawVert_t ) );
|
||||
}
|
||||
|
||||
return CopyMesh( &out );
|
||||
return CopyMesh( out );
|
||||
}
|
||||
|
||||
|
||||
mesh_t TessellatedMesh( const mesh_t in, int iterations ){
|
||||
//% mesh_t subdivided = SubdivideMesh( in, 8, 512 );
|
||||
mesh_t subdivided = SubdivideMesh2( in, iterations );
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( subdivided );
|
||||
mesh_t mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
subdivided.freeVerts();
|
||||
//% MakeMeshNormals( mesh );
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
=================
|
||||
SubdivideMeshQuads
|
||||
=================
|
||||
*/
|
||||
static mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int *widthtable, int *heighttable ){
|
||||
static mesh_t SubdivideMeshQuads( const mesh_t in, float minLength, int maxsize, int *widthtable, int *heighttable ){
|
||||
int i, j, k, w, h, maxsubdivisions, subdivisions;
|
||||
mesh_t out;
|
||||
bspDrawVert_t expand[MAX_EXPANDED_AXIS][MAX_EXPANDED_AXIS];
|
||||
mesh_t out( in.width, in.height, expand[0] );
|
||||
|
||||
out.width = in->width;
|
||||
out.height = in->height;
|
||||
|
||||
for ( i = 0; i < in->width; ++i ) {
|
||||
for ( j = 0; j < in->height; ++j ) {
|
||||
expand[j][i] = in->verts[j * in->width + i];
|
||||
}
|
||||
}
|
||||
for ( int h = 0; h < in.height; ++h )
|
||||
std::copy_n( &in.verts[h * in.width], in.width, expand[h] );
|
||||
|
||||
if ( maxsize > MAX_EXPANDED_AXIS ) {
|
||||
Error( "SubdivideMeshQuads: maxsize > MAX_EXPANDED_AXIS" );
|
||||
@@ -612,9 +584,9 @@ static mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int
|
||||
|
||||
// horizontal subdivisions
|
||||
|
||||
maxsubdivisions = ( maxsize - in->width ) / ( in->width - 1 );
|
||||
maxsubdivisions = ( maxsize - in.width ) / ( in.width - 1 );
|
||||
|
||||
for ( w = 0, j = 0; w < in->width - 1; ++w, j += subdivisions + 1 ) {
|
||||
for ( w = 0, j = 0; w < in.width - 1; ++w, j += subdivisions + 1 ) {
|
||||
double maxLength = 0;
|
||||
for ( i = 0; i < out.height; ++i ) {
|
||||
value_maximize( maxLength, vector3_length( expand[i][j + 1].xyz - expand[i][j].xyz ) );
|
||||
@@ -641,9 +613,9 @@ static mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int
|
||||
}
|
||||
}
|
||||
|
||||
maxsubdivisions = ( maxsize - in->height ) / ( in->height - 1 );
|
||||
maxsubdivisions = ( maxsize - in.height ) / ( in.height - 1 );
|
||||
|
||||
for ( h = 0, j = 0; h < in->height - 1; ++h, j += subdivisions + 1 ) {
|
||||
for ( h = 0, j = 0; h < in.height - 1; ++h, j += subdivisions + 1 ) {
|
||||
double maxLength = 0;
|
||||
for ( i = 0; i < out.width; ++i ) {
|
||||
value_maximize( maxLength, vector3_length( expand[j + 1][i].xyz - expand[j][i].xyz ) );
|
||||
@@ -671,10 +643,9 @@ static mesh_t *SubdivideMeshQuads( mesh_t *in, float minLength, int maxsize, int
|
||||
}
|
||||
|
||||
// collapse the verts
|
||||
out.verts = &expand[0][0];
|
||||
for ( i = 1; i < out.height; ++i ) {
|
||||
memmove( &out.verts[i * out.width], expand[i], out.width * sizeof( bspDrawVert_t ) );
|
||||
}
|
||||
|
||||
return CopyMesh( &out );
|
||||
return CopyMesh( out );
|
||||
}
|
||||
|
||||
@@ -210,8 +210,8 @@ void ParsePatch( bool onlyLights, entity_t& mapEnt, int mapPrimitiveNum ){
|
||||
Parse1DMatrix( 5, info );
|
||||
m.width = info[0];
|
||||
m.height = info[1];
|
||||
const int size = ( m.width * m.height );
|
||||
bspDrawVert_t *verts = m.verts = safe_malloc( size * sizeof( m.verts[0] ) );
|
||||
const int numVerts = m.numVerts();
|
||||
bspDrawVert_t *verts = m.verts = safe_malloc( numVerts * sizeof( m.verts[0] ) );
|
||||
|
||||
if ( m.width < 0 || m.width > MAX_PATCH_SIZE || m.height < 0 || m.height > MAX_PATCH_SIZE ) {
|
||||
Error( "ParsePatch: bad size" );
|
||||
@@ -259,7 +259,7 @@ void ParsePatch( bool onlyLights, entity_t& mapEnt, int mapPrimitiveNum ){
|
||||
degenerate = true;
|
||||
|
||||
/* find first valid vector */
|
||||
for ( int i = 1; i < size && delta[ 3 ] == 0; ++i )
|
||||
for ( int i = 1; i < numVerts && delta[ 3 ] == 0; ++i )
|
||||
{
|
||||
delta.vec3() = m.verts[ 0 ].xyz - m.verts[ i ].xyz;
|
||||
delta[ 3 ] = VectorNormalize( delta.vec3() );
|
||||
@@ -272,7 +272,7 @@ void ParsePatch( bool onlyLights, entity_t& mapEnt, int mapPrimitiveNum ){
|
||||
else
|
||||
{
|
||||
/* if all vectors match this or are zero, then this is a degenerate patch */
|
||||
for ( int i = 1; i < size && degenerate; ++i )
|
||||
for ( int i = 1; i < numVerts && degenerate; ++i )
|
||||
{
|
||||
Vector4 delta2( m.verts[ 0 ].xyz - m.verts[ i ].xyz, 0 );
|
||||
delta2[ 3 ] = VectorNormalize( delta2.vec3() );
|
||||
@@ -292,7 +292,7 @@ void ParsePatch( bool onlyLights, entity_t& mapEnt, int mapPrimitiveNum ){
|
||||
/* warn and select degenerate patch */
|
||||
if ( degenerate ) {
|
||||
xml_Select( "degenerate patch", mapEnt.mapEntityNum, mapPrimitiveNum, false );
|
||||
free( m.verts );
|
||||
m.freeVerts();
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -400,8 +400,8 @@ void PatchMapDrawSurfs( entity_t& e ){
|
||||
|
||||
meshes[m1].bordering[m2] =
|
||||
meshes[m2].bordering[m1] =
|
||||
std::ranges::any_of( Span( mesh1.verts, mesh1.width * mesh1.height ), [mesh2]( const bspDrawVert_t& v1 ){
|
||||
return std::ranges::any_of( Span( mesh2.verts, mesh2.width * mesh2.height ), [v1]( const bspDrawVert_t& v2 ){
|
||||
std::ranges::any_of( Span( mesh1.verts, mesh1.numVerts() ), [mesh2]( const bspDrawVert_t& v1 ){
|
||||
return std::ranges::any_of( Span( mesh2.verts, mesh2.numVerts() ), [v1]( const bspDrawVert_t& v2 ){
|
||||
return vector3_equal_epsilon( v1.xyz, v2.xyz, 1.f );
|
||||
} );
|
||||
} );
|
||||
@@ -428,7 +428,7 @@ void PatchMapDrawSurfs( entity_t& e ){
|
||||
{
|
||||
if ( m.group ) {
|
||||
m.grouped = true;
|
||||
std::for_each_n( m.mesh.mesh.verts, m.mesh.mesh.width * m.mesh.mesh.height,
|
||||
std::for_each_n( m.mesh.mesh.verts, m.mesh.mesh.numVerts(),
|
||||
[&bounds]( const bspDrawVert_t& v ){ bounds.extend( v.xyz ); } );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,6 +762,15 @@ struct mesh_t
|
||||
{
|
||||
int width, height;
|
||||
bspDrawVert_t *verts;
|
||||
|
||||
mesh_t() = default;
|
||||
mesh_t( int width, int height, bspDrawVert_t *verts ) : width( width ), height( height ), verts( verts ){}
|
||||
size_t numVerts() const {
|
||||
return width * height;
|
||||
}
|
||||
void freeVerts(){
|
||||
free( verts );
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -1513,17 +1522,17 @@ bool WindingIsTiny( const winding_t& w );
|
||||
/* mesh.c */
|
||||
bspDrawVert_t LerpDrawVert( const bspDrawVert_t& a, const bspDrawVert_t& b );
|
||||
void LerpDrawVertAmount( bspDrawVert_t *a, bspDrawVert_t *b, float amount, bspDrawVert_t *out );
|
||||
void FreeMesh( mesh_t *m );
|
||||
mesh_t *CopyMesh( mesh_t *mesh );
|
||||
void PrintMesh( mesh_t *m );
|
||||
mesh_t *TransposeMesh( mesh_t *in );
|
||||
void InvertMesh( mesh_t *m );
|
||||
mesh_t *SubdivideMesh( mesh_t in, float maxError, float minLength );
|
||||
mesh_t CopyMesh( const mesh_t m );
|
||||
void PrintMesh( const mesh_t m );
|
||||
void TransposeMesh( mesh_t& m );
|
||||
void InvertMesh( mesh_t& m );
|
||||
mesh_t SubdivideMesh( const mesh_t in, float maxError, float minLength );
|
||||
int IterationsForCurve( float len, int subdivisions );
|
||||
mesh_t *SubdivideMesh2( mesh_t in, int iterations );
|
||||
mesh_t *RemoveLinearMeshColumnsRows( mesh_t *in );
|
||||
void MakeMeshNormals( mesh_t in );
|
||||
void PutMeshOnCurve( mesh_t in );
|
||||
mesh_t SubdivideMesh2( const mesh_t in, int iterations );
|
||||
mesh_t RemoveLinearMeshColumnsRows( const mesh_t in );
|
||||
mesh_t TessellatedMesh( const mesh_t in, int iterations );
|
||||
void MakeMeshNormals( mesh_t& in );
|
||||
void PutMeshOnCurve( mesh_t& in );
|
||||
|
||||
|
||||
/* map.c */
|
||||
|
||||
@@ -773,7 +773,6 @@ mapDrawSurface_t *DrawSurfaceForSide( const entity_t& e, const brush_t& b, const
|
||||
mapDrawSurface_t *DrawSurfaceForMesh( const entity_t& e, parseMesh_t& p, mesh_t *mesh ){
|
||||
Plane3f plane;
|
||||
shaderInfo_t *si, *parent;
|
||||
mesh_t *copy;
|
||||
byte shaderIndexes[ MAX_EXPANDED_AXIS * MAX_EXPANDED_AXIS ];
|
||||
float offsets[ MAX_EXPANDED_AXIS * MAX_EXPANDED_AXIS ];
|
||||
|
||||
@@ -788,35 +787,35 @@ mapDrawSurface_t *DrawSurfaceForMesh( const entity_t& e, parseMesh_t& p, mesh_t
|
||||
}
|
||||
|
||||
/* get vertex count */
|
||||
const int numVerts = mesh->width * mesh->height;
|
||||
const int numVerts = mesh->numVerts();
|
||||
|
||||
/* to make valid normals for patches with degenerate edges,
|
||||
we need to make a copy of the mesh and put the aproximating
|
||||
points onto the curve */
|
||||
|
||||
/* create a copy of the mesh */
|
||||
copy = CopyMesh( mesh );
|
||||
mesh_t copy = CopyMesh( *mesh );
|
||||
|
||||
/* store off the original (potentially bad) normals */
|
||||
MakeMeshNormals( *copy );
|
||||
MakeMeshNormals( copy );
|
||||
for ( int i = 0; i < numVerts; ++i )
|
||||
mesh->verts[ i ].normal = copy->verts[ i ].normal;
|
||||
mesh->verts[ i ].normal = copy.verts[ i ].normal;
|
||||
|
||||
/* put the mesh on the curve */
|
||||
PutMeshOnCurve( *copy );
|
||||
PutMeshOnCurve( copy );
|
||||
|
||||
/* find new normals (to take into account degenerate/flipped edges */
|
||||
MakeMeshNormals( *copy );
|
||||
MakeMeshNormals( copy );
|
||||
for ( int i = 0; i < numVerts; ++i )
|
||||
{
|
||||
/* ydnar: only copy normals that are significantly different from the originals */
|
||||
if ( vector3_dot( copy->verts[ i ].normal, mesh->verts[ i ].normal ) < 0.75f ) {
|
||||
mesh->verts[ i ].normal = copy->verts[ i ].normal;
|
||||
if ( vector3_dot( copy.verts[ i ].normal, mesh->verts[ i ].normal ) < 0.75f ) {
|
||||
mesh->verts[ i ].normal = copy.verts[ i ].normal;
|
||||
}
|
||||
}
|
||||
|
||||
/* free the old mesh */
|
||||
FreeMesh( copy );
|
||||
copy.freeVerts();
|
||||
|
||||
/* ydnar: gs mods: check for indexed shader */
|
||||
const bool indexed = ( si->indexed && p.im != nullptr );
|
||||
@@ -2844,40 +2843,29 @@ static int AddSurfaceModels( mapDrawSurface_t& ds, entity_t& entity ){
|
||||
case ESurfaceType::Patch:
|
||||
{
|
||||
/* subdivide the surface */
|
||||
mesh_t src;
|
||||
src.width = ds.patchWidth;
|
||||
src.height = ds.patchHeight;
|
||||
src.verts = ds.verts.data();
|
||||
//% mesh_t *subdivided = SubdivideMesh( src, 8.0f, 512 );
|
||||
const int iterations = IterationsForCurve( ds.longestCurve, patchSubdivisions );
|
||||
mesh_t *subdivided = SubdivideMesh2( src, iterations );
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, ds.verts.data() ), IterationsForCurve( ds.longestCurve, patchSubdivisions ) );
|
||||
|
||||
/* subdivide each quad to place the models */
|
||||
for ( int y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ), /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ), /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* triangle 1 */
|
||||
const int n = AddSurfaceModelsToTriangle_r( ds, model, TriRef{
|
||||
&mesh->verts[ pw[ r + 0 ] ],
|
||||
&mesh->verts[ pw[ r + 1 ] ],
|
||||
&mesh->verts[ pw[ r + 2 ] ] }, entity );
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ] }, entity );
|
||||
if ( n < 0 ) {
|
||||
return n;
|
||||
}
|
||||
@@ -2885,9 +2873,9 @@ static int AddSurfaceModels( mapDrawSurface_t& ds, entity_t& entity ){
|
||||
|
||||
/* triangle 2 */
|
||||
const int n2 = AddSurfaceModelsToTriangle_r( ds, model, TriRef{
|
||||
&mesh->verts[ pw[ r + 0 ] ],
|
||||
&mesh->verts[ pw[ r + 2 ] ],
|
||||
&mesh->verts[ pw[ r + 3 ] ] }, entity );
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ] }, entity );
|
||||
if ( n2 < 0 ) {
|
||||
return n2;
|
||||
}
|
||||
@@ -2896,7 +2884,7 @@ static int AddSurfaceModels( mapDrawSurface_t& ds, entity_t& entity ){
|
||||
}
|
||||
|
||||
/* free the subdivided mesh */
|
||||
FreeMesh( mesh );
|
||||
mesh.freeVerts();
|
||||
break;
|
||||
}
|
||||
/* handle triangle surfaces */
|
||||
|
||||
@@ -186,53 +186,47 @@ void Foliage( mapDrawSurface_t& src, entity_t& entity ){
|
||||
case ESurfaceType::Patch:
|
||||
{
|
||||
/* make a mesh from the drawsurf */
|
||||
mesh_t srcMesh;
|
||||
srcMesh.width = src.patchWidth;
|
||||
srcMesh.height = src.patchHeight;
|
||||
srcMesh.verts = src.verts.data();
|
||||
mesh_t *subdivided = SubdivideMesh( srcMesh, 8, 512 );
|
||||
mesh_t srcMesh( src.patchWidth, src.patchHeight, src.verts.data() );
|
||||
mesh_t subdivided = SubdivideMesh( srcMesh, 8, 512 );
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
|
||||
/* get verts */
|
||||
const bspDrawVert_t *verts = mesh->verts;
|
||||
PutMeshOnCurve( subdivided );
|
||||
mesh_t mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
subdivided.freeVerts();
|
||||
|
||||
/* map the mesh quads */
|
||||
for ( int y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ) /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
|
||||
/* get drawverts and map first triangle */
|
||||
SubdivideFoliageTriangle_r( foliage, TriRef{
|
||||
&verts[ pw[ r + 0 ] ],
|
||||
&verts[ pw[ r + 1 ] ],
|
||||
&verts[ pw[ r + 2 ] ]
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 1 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ]
|
||||
} );
|
||||
/* get drawverts and map second triangle */
|
||||
SubdivideFoliageTriangle_r( foliage, TriRef{
|
||||
&verts[ pw[ r + 0 ] ],
|
||||
&verts[ pw[ r + 2 ] ],
|
||||
&verts[ pw[ r + 3 ] ]
|
||||
&mesh.verts[ pw[ r + 0 ] ],
|
||||
&mesh.verts[ pw[ r + 2 ] ],
|
||||
&mesh.verts[ pw[ r + 3 ] ]
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
||||
/* free the mesh */
|
||||
FreeMesh( mesh );
|
||||
mesh.freeVerts();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -361,12 +361,6 @@ static void TriangulatePatchSurface( const entity_t& e, mapDrawSurface_t& ds ){
|
||||
if ( ds.verts.empty() || ds.type != ESurfaceType::Patch || ( !patchMeta && !forcePatchMeta ) ) {
|
||||
return;
|
||||
}
|
||||
/* make a mesh from the drawsurf */
|
||||
mesh_t src;
|
||||
src.width = ds.patchWidth;
|
||||
src.height = ds.patchHeight;
|
||||
src.verts = ds.verts.data();
|
||||
//% mesh_t *subdivided = SubdivideMesh( src, 8, 999 );
|
||||
|
||||
int iterations;
|
||||
if ( int patchSubdivision; e.read_keyvalue( patchSubdivision, "_patchSubdivide", "patchSubdivide" ) ) {
|
||||
@@ -376,14 +370,8 @@ static void TriangulatePatchSurface( const entity_t& e, mapDrawSurface_t& ds ){
|
||||
const int patchQuality = e.intForKey( "_patchQuality", "patchQuality" );
|
||||
iterations = IterationsForCurve( ds.longestCurve, patchSubdivisions / ( patchQuality == 0? 1 : patchQuality ) );
|
||||
}
|
||||
|
||||
mesh_t *subdivided = SubdivideMesh2( src, iterations ); //% ds.maxIterations
|
||||
|
||||
/* fit it to the curve and remove colinear verts on rows/columns */
|
||||
PutMeshOnCurve( *subdivided );
|
||||
mesh_t *mesh = RemoveLinearMeshColumnsRows( subdivided );
|
||||
FreeMesh( subdivided );
|
||||
//% MakeMeshNormals( mesh );
|
||||
/* make a mesh from the drawsurf */
|
||||
mesh_t mesh = TessellatedMesh( mesh_t( ds.patchWidth, ds.patchHeight, ds.verts.data() ), iterations ); //% ds.maxIterations
|
||||
|
||||
/* make a copy of the drawsurface */
|
||||
mapDrawSurface_t& dsNew = AllocDrawSurface( ESurfaceType::Meta );
|
||||
@@ -397,23 +385,23 @@ static void TriangulatePatchSurface( const entity_t& e, mapDrawSurface_t& ds ){
|
||||
/* basic transmogrification */
|
||||
dsNew.type = ESurfaceType::Meta;
|
||||
dsNew.indexes.clear();
|
||||
dsNew.indexes.reserve( ( mesh->width - 1 ) * ( mesh->height - 1 ) * 6 );
|
||||
dsNew.indexes.reserve( ( mesh.width - 1 ) * ( mesh.height - 1 ) * 6 );
|
||||
|
||||
/* copy the verts in */
|
||||
dsNew.verts.assign( mesh->verts, mesh->verts + mesh->width * mesh->height );
|
||||
dsNew.verts.assign( mesh.verts, mesh.verts + mesh.numVerts() );
|
||||
|
||||
/* iterate through the mesh quads */
|
||||
for ( int y = 0; y < ( mesh->height - 1 ); ++y )
|
||||
for ( int y = 0; y < ( mesh.height - 1 ); ++y )
|
||||
{
|
||||
for ( int x = 0; x < ( mesh->width - 1 ); ++x )
|
||||
for ( int x = 0; x < ( mesh.width - 1 ); ++x )
|
||||
{
|
||||
/* set indexes */
|
||||
const int pw[ 5 ] = {
|
||||
x + ( y * mesh->width ),
|
||||
x + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh->width ),
|
||||
x + 1 + ( y * mesh->width ),
|
||||
x + ( y * mesh->width ) /* same as pw[ 0 ] */
|
||||
x + ( y * mesh.width ),
|
||||
x + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( ( y + 1 ) * mesh.width ),
|
||||
x + 1 + ( y * mesh.width ),
|
||||
x + ( y * mesh.width ) /* same as pw[ 0 ] */
|
||||
};
|
||||
/* set radix */
|
||||
const int r = ( x + y ) & 1;
|
||||
@@ -430,7 +418,7 @@ static void TriangulatePatchSurface( const entity_t& e, mapDrawSurface_t& ds ){
|
||||
}
|
||||
}
|
||||
|
||||
FreeMesh( mesh );
|
||||
mesh.freeVerts();
|
||||
|
||||
/* add to count */
|
||||
numPatchMetaSurfaces++;
|
||||
|
||||
@@ -495,7 +495,7 @@ void BeginModel( const entity_t& e ){
|
||||
/* bound patches */
|
||||
for ( const parseMesh_t& p : e.patches )
|
||||
{
|
||||
for ( const bspDrawVert_t& vert : Span( p.mesh.verts, p.mesh.width * p.mesh.height ) )
|
||||
for ( const bspDrawVert_t& vert : Span( p.mesh.verts, p.mesh.numVerts() ) )
|
||||
minmax.extend( vert.xyz );
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user