private static void GenerateConvexPolygonTriIndices( LevelGeometryTesselator.Polygon poly, int[] indexMap, GroupListBuilder builder, GroupMaterial material ) { GroupBuilder group = builder.GetGroup( material ); ICollection< int > indices = group.Indices; int baseIndex = indexMap[ poly.Edges[0].StartIndex ]; for ( int index = 1; index < poly.Edges.Length - 1; ++index ) { indices.Add( baseIndex ); indices.Add( indexMap[ poly.Edges[ index ].StartIndex ] ); indices.Add( indexMap[ poly.Edges[ index ].EndIndex ] ); } }
/// <summary> /// Builds runtime environment graphics from level geometry /// </summary> /// <param name="envGraphics">Environment graphics to build</param> /// <param name="geometry">Level geometry</param> /// <returns>Returns a new <see cref="IEnvironmentGraphics"/> object</returns> public IEnvironmentGraphics Build( IEnvironmentGraphics envGraphics, LevelGeometry geometry ) { // Create environment graphics Csg2.Node root = Csg2.Build( geometry.ObstaclePolygons ); List< LevelGeometryTesselator.Polygon > floorPolys = new List< LevelGeometryTesselator.Polygon >( ); List< LevelGeometryTesselator.Polygon > obstaclePolys = new List< LevelGeometryTesselator.Polygon >( ); LevelGeometryTesselator tess = new LevelGeometryTesselator( ); LevelGeometryTesselator.Polygon poly = tess.CreateBoundingPolygon( -100, -100, 100, 100 ); LevelGeometryTesselator.AddPolygonDelegate addFloorPoly = delegate( LevelGeometryTesselator.Polygon floorPoly, Csg2.Node node ) { floorPolys.Add( floorPoly ); }; LevelGeometryTesselator.AddPolygonDelegate addObstaclePoly = delegate( LevelGeometryTesselator.Polygon obstaclePoly, Csg2.Node node ) { obstaclePolys.Add( obstaclePoly ); }; tess.BuildConvexRegions( root, poly, addFloorPoly, addObstaclePoly, true ); GroupListBuilder groupsBuilder = new GroupListBuilder( ); Point2[] flatPoints = tess.Points.ToArray( ); // // Get the texture source for the wall // ITexture2d textureSource = node.Edge.WallData.Texture; // ITechnique techniqueSource = node.Edge.WallData.Technique; // GroupMaterial material = new GroupMaterial( techniqueSource, new ITexture2d[] { textureSource } ); // GroupBuilder group = builder.GetGroup( material ); StaticGeometryData defaultFloor = StaticGeometryData.CreateDefaultFloorData( ); StaticGeometryData defaultWall = StaticGeometryData.CreateDefaultWallData( ); GroupMaterial defaultFloorMaterial = new GroupMaterial ( defaultFloor.Technique, new ITexture2d[] { defaultFloor.Texture } ); GroupMaterial defaultWallMaterial = new GroupMaterial ( defaultWall.Technique, new ITexture2d[] { defaultWall.Texture } ); GroupMaterial defaultObstacleMaterial = new GroupMaterial ( defaultFloor.Technique, new ITexture2d[] { defaultFloor.Texture } ); int[] floorIndexMap = new int[ flatPoints.Length ]; int[] roofIndexMap = new int[ flatPoints.Length ]; for ( int index = 0; index < flatPoints.Length; ++index ) { floorIndexMap[ index ] = -1; roofIndexMap[ index ] = -1; } List< Vertex > vertices = new List< Vertex >( flatPoints.Length * 2 ); foreach ( LevelGeometryTesselator.Polygon floorPoly in floorPolys ) { for ( int edgeIndex = 0; edgeIndex < floorPoly.Edges.Length; ++edgeIndex ) { int pIndex = floorPoly.Edges[ edgeIndex ].StartIndex; if ( floorIndexMap[ pIndex ] == -1 ) { Point2 srcPt = flatPoints[ pIndex ]; floorIndexMap[ pIndex ] = AddVertex( vertices, FloorVertex( srcPt.X, 0, srcPt.Y ) ); } } GenerateConvexPolygonTriIndices( floorPoly, floorIndexMap, groupsBuilder, defaultFloorMaterial ); } foreach ( LevelGeometryTesselator.Polygon obstaclePoly in obstaclePolys ) { // Duplicate floor points at obstacle height, add wall polys for ( int edgeIndex = 0; edgeIndex < obstaclePoly.Edges.Length; ++edgeIndex ) { int pIndex = obstaclePoly.Edges[ edgeIndex ].StartIndex; if ( roofIndexMap[ pIndex ] == -1 ) { Point2 srcPt = flatPoints[ pIndex ]; roofIndexMap[ pIndex ] = AddVertex( vertices, FloorVertex( srcPt.X, 6, srcPt.Y ) ); } } // Generate wall polys for ( int edgeIndex = 0; edgeIndex < obstaclePoly.Edges.Length; ++edgeIndex ) { int pIndex = obstaclePoly.Edges[ edgeIndex ].StartIndex; int nextPIndex = obstaclePoly.Edges[ edgeIndex ].EndIndex; if ( ( floorIndexMap[ pIndex ] == -1 ) || ( floorIndexMap[ nextPIndex ] == -1 ) ) { // No equivalent floor vertices - ignore continue; } //if ( floorIndexMap[ pIndex ] == -1 ) //{ // floorIndexMap[ pIndex ] = AddVertex( vertices, FloorVertex( flatPoints[ pIndex ].X, 0, flatPoints[ pIndex ].Y ) ); //} //if ( floorIndexMap[ nextPIndex ] == -1 ) //{ // floorIndexMap[ nextPIndex ] = AddVertex( vertices, FloorVertex( flatPoints[ nextPIndex ].X, 0, flatPoints[ nextPIndex ].Y ) ); //} Point3 floor0Pt = vertices[ floorIndexMap[ pIndex ] ].m_Point; Point3 floor1Pt = vertices[ floorIndexMap[ nextPIndex ] ].m_Point; Point3 roof0Pt = vertices[ roofIndexMap[ pIndex ] ].m_Point; Point3 roof1Pt = vertices[ roofIndexMap[ nextPIndex ] ].m_Point; Vector3 dir = Vector3.Cross( floor1Pt - floor0Pt, floor0Pt - roof0Pt ).MakeNormal( ); // TODO: AP: Better texture coordinate generation float texWidth = floor0Pt.DistanceTo( floor1Pt ) / 5.0f; float texHeight = floor0Pt.DistanceTo( roof0Pt ) / 5.0f; int floorP0 = AddVertex( vertices, new Vertex( floor0Pt, dir, new Point2( 0, 0 ) ) ); int floorP1 = AddVertex( vertices, new Vertex( floor1Pt, dir, new Point2( texWidth, 0 ) ) ); int roofP0 = AddVertex( vertices, new Vertex( roof0Pt, dir, new Point2( 0, texHeight ) ) ); int roofP1 = AddVertex( vertices, new Vertex( roof1Pt, dir, new Point2( texWidth, texHeight ) ) ); GroupBuilder group = groupsBuilder.GetGroup( defaultWallMaterial ); group.Indices.Add( floorP0 ); group.Indices.Add( floorP1 ); group.Indices.Add( roofP0 ); group.Indices.Add( floorP1 ); group.Indices.Add( roofP1 ); group.Indices.Add( roofP0 ); } GenerateConvexPolygonTriIndices( obstaclePoly, roofIndexMap, groupsBuilder, defaultObstacleMaterial ); } VertexBufferData buffer = VertexBufferData.FromVertexCollection( vertices ); EnvironmentGraphicsData.GridCell cell = new EnvironmentGraphicsData.GridCell( buffer ); foreach ( GroupBuilder group in groupsBuilder.Groups ) { cell.Groups.Add( group.Create( ) ); } EnvironmentGraphicsData data = new EnvironmentGraphicsData( 1, 1 ); data[ 0, 0 ] = cell; envGraphics.Build( data ); return envGraphics; /* EnvironmentGraphicsData envGraphicsData = new EnvironmentGraphicsData( 1, 1 ); EnvironmentGraphicsData.GridCell levelCell = new EnvironmentGraphicsData.GridCell( ); EnvironmentGraphicsData.CellGeometryGroup[] groups = CreateGroups( geometry.Csg.Root ); levelCell.Groups.AddRange( groups ); envGraphicsData[ 0, 0 ] = levelCell; envGraphics.Build( envGraphicsData ); return envGraphics; /* // Determine x/z bounds of the geometry Rectangle levelBounds = GetLevelBounds( geometry.Csg.Root ); int xDivisions = ( int )( levelBounds.Width / m_ChopSize ) + 1; int yDivisions = ( int )( levelBounds.Height / m_ChopSize ) + 1; float y = levelBounds.Y; TriBuilder builder = new TriBuilder( ); for ( int yDiv = 0; yDiv < yDivisions; ++yDiv, y += m_ChopSize ) { float x = levelBounds.X; for ( int xDiv = 0; xDiv < xDivisions; ++xDiv, x += m_ChopSize ) { ClippetyClip( geometry.Csg.Root, x, y, x + m_ChopSize, y + m_ChopSize, builder ); } } return null; */ }