//============================================================================= // TerrainBuilder: Builds a 3D cube brush, with a tessellated bottom. //============================================================================= class TerrainBuilder extends BrushBuilder; var() float Height, Width, Breadth; var() int WidthSegments, DepthSegments; // How many breaks to have in each direction var() name GroupName; function BuildTerrain( int Direction, float dx, float dy, float dz, int WidthSeg, int DepthSeg ) { local int n,nbottom,ntop,i,j,k,x,y; local float WidthStep, DepthStep; // // TOP // n = GetVertexCount(); // Create vertices for( i=-1; i<2; i+=2 ) for( j=-1; j<2; j+=2 ) for( k=-1; k<2; k+=2 ) Vertex3f( i*dx/2, j*dy/2, k*dz/2 ); // Create the top Poly4i(Direction,n+3,n+1,n+5,n+7, 'sky'); // // BOTTOM // nbottom = GetVertexCount(); // Create vertices WidthStep = dx / WidthSeg; DepthStep = dy / DepthSeg; for( x = 0 ; x < WidthSeg + 1 ; x++ ) for( y = 0 ; y < DepthSeg + 1 ; y++ ) Vertex3f( (WidthStep * x) - dx/2, (DepthStep * y) - dy/2, -(dz/2) ); ntop = GetVertexCount(); for( x = 0 ; x < WidthSeg + 1 ; x++ ) for( y = 0 ; y < DepthSeg + 1 ; y++ ) Vertex3f( (WidthStep * x) - dx/2, (DepthStep * y) - dy/2, dz/2 ); // Create the bottom as a mesh of triangles for( x = 0 ; x < WidthSeg ; x++ ) for( y = 0 ; y < DepthSeg ; y++ ) { Poly3i(-Direction, (nbottom+y) + ((DepthSeg+1) * x), (nbottom+y) + ((DepthSeg+1) * (x+1)), ((nbottom+1)+y) + ((DepthSeg+1) * (x+1)), 'ground'); Poly3i(-Direction, (nbottom+y) + ((DepthSeg+1) * x), ((nbottom+1)+y) + ((DepthSeg+1) * (x+1)), ((nbottom+1)+y) + ((DepthSeg+1) * x), 'ground'); } // // SIDES // // The bottom poly of each side is basically a triangle fan. // for( x = 0 ; x < WidthSeg ; x++ ) { Poly4i(-Direction, nbottom + DepthSeg + ((DepthSeg+1) * x), nbottom + DepthSeg + ((DepthSeg+1) * (x + 1)), ntop + DepthSeg + ((DepthSeg+1) * (x + 1)), ntop + DepthSeg + ((DepthSeg+1) * x), 'sky' ); Poly4i(-Direction, nbottom + ((DepthSeg+1) * (x + 1)), nbottom + ((DepthSeg+1) * x), ntop + ((DepthSeg+1) * x), ntop + ((DepthSeg+1) * (x + 1)), 'sky' ); } for( y = 0 ; y < DepthSeg ; y++ ) { Poly4i(-Direction, nbottom + y, nbottom + (y + 1), ntop + (y + 1), ntop + y, 'sky' ); Poly4i(-Direction, nbottom + ((DepthSeg+1) * WidthSeg) + (y + 1), nbottom + ((DepthSeg+1) * WidthSeg) + y, ntop + ((DepthSeg+1) * WidthSeg) + y, ntop + ((DepthSeg+1) * WidthSeg) + (y + 1), 'sky' ); } } event bool Build() { if( Height<=0 || Width<=0 || Breadth<=0 || WidthSegments<=0 || DepthSegments<=0 ) return BadParameters(); BeginBrush( false, GroupName ); BuildTerrain( +1, Breadth, Width, Height, WidthSegments, DepthSegments ); return EndBrush(); } defaultproperties { Height=256 Width=256 Breadth=512 WidthSegments=4 DepthSegments=2 GroupName=Terrain BitmapFilename="BBTerrain" ToolTip="BSP Based Terrain" }