Exemple #1
0
/*
==================
CM_SurfaceCollideFromTriangleSoup
==================
*/
static void CM_SurfaceCollideFromTriangleSoup(cTriangleSoup_t* triSoup,
                                              cSurfaceCollide_t* sc) {
    int i;
    float* p1, *p2, *p3;
    //	int             i1, i2, i3;

    cFacet_t* facet;

    CM_ResetPlaneCounts();

    // find the planes for each triangle of the grid
    for (i = 0; i < triSoup->numTriangles; i++) {
        p1 = triSoup->points[i][0];
        p2 = triSoup->points[i][1];
        p3 = triSoup->points[i][2];

        triSoup->trianglePlanes[i] = CM_FindPlane(p1, p2, p3);

        // Log::Notive( "trianglePlane[%i] = %i", i, trianglePlanes[i]);
    }

    // create the borders for each triangle
    for (i = 0; i < triSoup->numTriangles; i++) {
        facet = &facets[numFacets];
        Com_Memset(facet, 0, sizeof(*facet));

        p1 = triSoup->points[i][0];
        p2 = triSoup->points[i][1];
        p3 = triSoup->points[i][2];

        facet->surfacePlane =
                triSoup->trianglePlanes[i]; // CM_FindPlane(p1, p2, p3);

// try and make a quad out of two triangles
#if 0
		i1 = triSoup->indexes[ i * 3 + 0 ];
		i2 = triSoup->indexes[ i * 3 + 1 ];
		i3 = triSoup->indexes[ i * 3 + 2 ];

		if ( i != triSoup->numTriangles - 1 )
		{
			i4 = triSoup->indexes[ i * 3 + 3 ];
			i5 = triSoup->indexes[ i * 3 + 4 ];
			i6 = triSoup->indexes[ i * 3 + 5 ];

			if ( i4 == i3 && i5 == i2 )
			{
				p4 = triSoup->points[ i ][ 5 ]; // vertex at i6

				if ( CM_GenerateFacetFor4Points( facet, p1, p2, p4, p3 ) )  //test->facets[count], v1, v2, v4, v3))
				{
					CM_SetBorderInward( facet, triSoup, i, 0 );

					if ( CM_ValidateFacet( facet ) )
					{
						CM_AddFacetBevels( facet );
						numFacets++;

						i++; // skip next tri
						continue;
					}
				}
			}
		}

#endif

        if (CM_GenerateFacetFor3Points(facet, p1, p2, p3)) {
            CM_SetBorderInward(facet, triSoup, i, 0);

            if (CM_ValidateFacet(facet)) {
                CM_AddFacetBevels(facet);
                numFacets++;
            }
        }
    }

    // copy the results out
    sc->numPlanes = numPlanes;
    sc->planes = (cPlane_t*) CM_Alloc(numPlanes * sizeof(*sc->planes));
    Com_Memcpy(sc->planes, planes, numPlanes * sizeof(*sc->planes));

    sc->numFacets = numFacets;
    sc->facets = (cFacet_t*) CM_Alloc(numFacets * sizeof(*sc->facets));
    Com_Memcpy(sc->facets, facets, numFacets * sizeof(*sc->facets));
}
/*
==================
CM_PatchCollideFromGrid
==================
*/
static void CM_PatchCollideFromGrid( cGrid_t *grid, patchCollide_t *pf ) {
	int i, j;
	float           *p1, *p2, *p3;
	int gridPlanes[MAX_GRID_SIZE][MAX_GRID_SIZE][2];
	facet_t         *facet;
	int borders[4];
	int noAdjust[4];

	numPlanes = 0;
	numFacets = 0;

	// find the planes for each triangle of the grid
	for ( i = 0 ; i < grid->width - 1 ; i++ ) {
		for ( j = 0 ; j < grid->height - 1 ; j++ ) {
			p1 = grid->points[i][j];
			p2 = grid->points[i + 1][j];
			p3 = grid->points[i + 1][j + 1];
			gridPlanes[i][j][0] = CM_FindPlane( p1, p2, p3 );

			p1 = grid->points[i + 1][j + 1];
			p2 = grid->points[i][j + 1];
			p3 = grid->points[i][j];
			gridPlanes[i][j][1] = CM_FindPlane( p1, p2, p3 );
		}
	}

	// create the borders for each facet
	for ( i = 0 ; i < grid->width - 1 ; i++ ) {
		for ( j = 0 ; j < grid->height - 1 ; j++ ) {

			borders[EN_TOP] = -1;
			if ( j > 0 ) {
				borders[EN_TOP] = gridPlanes[i][j - 1][1];
			} else if ( grid->wrapHeight ) {
				borders[EN_TOP] = gridPlanes[i][grid->height - 2][1];
			}
			noAdjust[EN_TOP] = ( borders[EN_TOP] == gridPlanes[i][j][0] );
			if ( borders[EN_TOP] == -1 || noAdjust[EN_TOP] ) {
				borders[EN_TOP] = CM_EdgePlaneNum( grid, gridPlanes, i, j, 0 );
			}

			borders[EN_BOTTOM] = -1;
			if ( j < grid->height - 2 ) {
				borders[EN_BOTTOM] = gridPlanes[i][j + 1][0];
			} else if ( grid->wrapHeight ) {
				borders[EN_BOTTOM] = gridPlanes[i][0][0];
			}
			noAdjust[EN_BOTTOM] = ( borders[EN_BOTTOM] == gridPlanes[i][j][1] );
			if ( borders[EN_BOTTOM] == -1 || noAdjust[EN_BOTTOM] ) {
				borders[EN_BOTTOM] = CM_EdgePlaneNum( grid, gridPlanes, i, j, 2 );
			}

			borders[EN_LEFT] = -1;
			if ( i > 0 ) {
				borders[EN_LEFT] = gridPlanes[i - 1][j][0];
			} else if ( grid->wrapWidth ) {
				borders[EN_LEFT] = gridPlanes[grid->width - 2][j][0];
			}
			noAdjust[EN_LEFT] = ( borders[EN_LEFT] == gridPlanes[i][j][1] );
			if ( borders[EN_LEFT] == -1 || noAdjust[EN_LEFT] ) {
				borders[EN_LEFT] = CM_EdgePlaneNum( grid, gridPlanes, i, j, 3 );
			}

			borders[EN_RIGHT] = -1;
			if ( i < grid->width - 2 ) {
				borders[EN_RIGHT] = gridPlanes[i + 1][j][1];
			} else if ( grid->wrapWidth ) {
				borders[EN_RIGHT] = gridPlanes[0][j][1];
			}
			noAdjust[EN_RIGHT] = ( borders[EN_RIGHT] == gridPlanes[i][j][0] );
			if ( borders[EN_RIGHT] == -1 || noAdjust[EN_RIGHT] ) {
				borders[EN_RIGHT] = CM_EdgePlaneNum( grid, gridPlanes, i, j, 1 );
			}

			if ( numFacets == MAX_FACETS ) {
				Com_Error( ERR_DROP, "MAX_FACETS" );
			}
			facet = &facets[numFacets];
			memset( facet, 0, sizeof( *facet ) );

			if ( gridPlanes[i][j][0] == gridPlanes[i][j][1] ) {
				if ( gridPlanes[i][j][0] == -1 ) {
					continue;       // degenrate
				}
				facet->surfacePlane = gridPlanes[i][j][0];
				facet->numBorders = 4;
				facet->borderPlanes[0] = borders[EN_TOP];
				facet->borderNoAdjust[0] = noAdjust[EN_TOP];
				facet->borderPlanes[1] = borders[EN_RIGHT];
				facet->borderNoAdjust[1] = noAdjust[EN_RIGHT];
				facet->borderPlanes[2] = borders[EN_BOTTOM];
				facet->borderNoAdjust[2] = noAdjust[EN_BOTTOM];
				facet->borderPlanes[3] = borders[EN_LEFT];
				facet->borderNoAdjust[3] = noAdjust[EN_LEFT];
				CM_SetBorderInward( facet, grid, gridPlanes, i, j, -1 );
				if ( CM_ValidateFacet( facet ) ) {
					CM_AddFacetBevels( facet );
					numFacets++;
				}
			} else {
				// two seperate triangles
				facet->surfacePlane = gridPlanes[i][j][0];
				facet->numBorders = 3;
				facet->borderPlanes[0] = borders[EN_TOP];
				facet->borderNoAdjust[0] = noAdjust[EN_TOP];
				facet->borderPlanes[1] = borders[EN_RIGHT];
				facet->borderNoAdjust[1] = noAdjust[EN_RIGHT];
				facet->borderPlanes[2] = gridPlanes[i][j][1];
				if ( facet->borderPlanes[2] == -1 ) {
					facet->borderPlanes[2] = borders[EN_BOTTOM];
					if ( facet->borderPlanes[2] == -1 ) {
						facet->borderPlanes[2] = CM_EdgePlaneNum( grid, gridPlanes, i, j, 4 );
					}
				}
				CM_SetBorderInward( facet, grid, gridPlanes, i, j, 0 );
				if ( CM_ValidateFacet( facet ) ) {
					CM_AddFacetBevels( facet );
					numFacets++;
				}

				if ( numFacets == MAX_FACETS ) {
					Com_Error( ERR_DROP, "MAX_FACETS" );
				}
				facet = &facets[numFacets];
				memset( facet, 0, sizeof( *facet ) );

				facet->surfacePlane = gridPlanes[i][j][1];
				facet->numBorders = 3;
				facet->borderPlanes[0] = borders[EN_BOTTOM];
				facet->borderNoAdjust[0] = noAdjust[EN_BOTTOM];
				facet->borderPlanes[1] = borders[EN_LEFT];
				facet->borderNoAdjust[1] = noAdjust[EN_LEFT];
				facet->borderPlanes[2] = gridPlanes[i][j][0];
				if ( facet->borderPlanes[2] == -1 ) {
					facet->borderPlanes[2] = borders[EN_TOP];
					if ( facet->borderPlanes[2] == -1 ) {
						facet->borderPlanes[2] = CM_EdgePlaneNum( grid, gridPlanes, i, j, 5 );
					}
				}
				CM_SetBorderInward( facet, grid, gridPlanes, i, j, 1 );
				if ( CM_ValidateFacet( facet ) ) {
					CM_AddFacetBevels( facet );
					numFacets++;
				}
			}
		}
	}

	// copy the results out
	pf->numPlanes = numPlanes;
	pf->numFacets = numFacets;
	pf->facets = Hunk_Alloc( numFacets * sizeof( *pf->facets ), h_high );
	memcpy( pf->facets, facets, numFacets * sizeof( *pf->facets ) );
	pf->planes = Hunk_Alloc( numPlanes * sizeof( *pf->planes ), h_high );
	memcpy( pf->planes, planes, numPlanes * sizeof( *pf->planes ) );
}
/*
==================
CM_SurfaceCollideFromTriangleSoup
==================
*/
static void CM_SurfaceCollideFromTriangleSoup( cTriangleSoup_t *triSoup, cSurfaceCollide_t *sc )
{
	float	*p1, *p2, *p3;
	int	i, i1, i2, i3;
	cfacet_t	*facet;

	numPlanes = 0;
	numFacets = 0;

#ifdef USE_HASHING
	// initialize hash table
	Mem_Set( planeHashTable, 0, sizeof( planeHashTable ));
#endif

	// find the planes for each triangle of the grid
	for( i = 0; i < triSoup->numTriangles; i++ )
	{
		p1 = triSoup->points[i][0];
		p2 = triSoup->points[i][1];
		p3 = triSoup->points[i][2];

		triSoup->trianglePlanes[i] = CM_FindPlane( p1, p2, p3 );
	}

	// create the borders for each triangle
	for( i = 0; i < triSoup->numTriangles; i++ )
	{
		facet = &facets[numFacets];
		Mem_Set( facet, 0, sizeof( *facet ));

		i1 = triSoup->indexes[i*3+0];
		i2 = triSoup->indexes[i*3+1];
		i3 = triSoup->indexes[i*3+2];

		p1 = triSoup->points[i][0];
		p2 = triSoup->points[i][1];
		p3 = triSoup->points[i][2];

		facet->surfacePlane = triSoup->trianglePlanes[i];

		// try and make a quad out of two triangles
#if 0
		if( i != triSoup->numTriangles - 1 )
		{
			int	i4, i5, i6;
			float	*p4;

			i4 = triSoup->indexes[i*3+3];
			i5 = triSoup->indexes[i*3+4];
			i6 = triSoup->indexes[i*3+5];

			if( i4 == i3 && i5 == i2 )
			{
				p4 = triSoup->points[i][5]; // vertex at i6

				if(CM_GenerateFacetFor4Points( facet, p1, p2, p4, p3 ))
				{
					CM_SetBorderInward( facet, triSoup, i, 0 );

					if( CM_ValidateFacet( facet ))
					{
						CM_AddFacetBevels( facet );
						numFacets++;

						i++; // skip next tri
						continue;
					}
				}
			}
		}
#endif

		if( CM_GenerateFacetFor3Points( facet, p1, p2, p3 ))
		{
			CM_SetBorderInward( facet, triSoup, i, 0 );

			if( CM_ValidateFacet( facet ))
			{
				CM_AddFacetBevels( facet );
				numFacets++;
			}
		}
	}

	// copy the results out
	sc->numPlanes = numPlanes;
	sc->planes = Mem_Alloc( cms.mempool, numPlanes * sizeof( *sc->planes ));
	Mem_Copy( sc->planes, planes, numPlanes * sizeof( *sc->planes ));

	sc->numFacets = numFacets;
	sc->facets = Mem_Alloc( cms.mempool, numFacets * sizeof( *sc->facets ));
	Mem_Copy( sc->facets, facets, numFacets * sizeof( *sc->facets ));
}