IndexVertexBufferCollector GetAllGeometriesForNavigationMesh() { var collector = new IndexVertexBufferCollector(); var scene = FindParent<Component_Scene>(); if( scene != null ) { foreach( var geometry in scene.GetComponents<Component_Pathfinding_Geometry>( false, true, true ) ) { var type = geometry.Type.Value; if( type == Component_Pathfinding_Geometry.TypeEnum.WalkableArea || type == Component_Pathfinding_Geometry.TypeEnum.BakedObstacle ) AddGeometryToCollector( collector, geometry ); } foreach( var geometryTag in scene.GetComponents<Component_Pathfinding_GeometryTag>( false, true, true ) ) { var type = geometryTag.Type.Value; if( type == Component_Pathfinding_GeometryTag.TypeEnum.WalkableArea || type == Component_Pathfinding_GeometryTag.TypeEnum.BakedObstacle ) AddGeometryTagToCollector( collector, geometryTag ); } } return collector; }
IndexVertexBufferCollector GetAllGeometriesForNavigationMesh() { IndexVertexBufferCollector collector = new IndexVertexBufferCollector(); foreach( Entity geometry in geometries ) { if( !geometry.Editor_IsExcludedFromWorld() ) AddEntityToCollector( collector, geometry ); } return collector; }
//IndexVertexBufferCollector GetGeometriesForNavigationMesh( Bounds bounds ) //{ // IndexVertexBufferCollector collector = new IndexVertexBufferCollector(); // странный способ // Map.Instance.GetObjects( new Box( bounds ), delegate( MapObject obj ) // { // if( geometries.Contains( obj ) ) // AddEntityToCollector( collector, obj ); // } ); // //heightmapterrain is not added in volume selections, this is actually good thing because now we can only add the required part // { // //raycast does not hit terrain?!? // /* // Vec3 top = bounds.GetCenter(); // top.Z = boundsMax.Z; // Vec3 bottom = bounds.GetCenter(); // bottom.Z = boundsMin.Z; // RayCastResult[] results = PhysicsWorld.Instance.RayCastPiercing(new Ray(top, bottom), (int)ContactGroup.CastOnlyCollision); // foreach (RayCastResult result in results) // { // HeightmapTerrain terrain = HeightmapTerrain.GetTerrainByBody( result.Shape.Body ); // if( terrain != null) // if( geometries.Contains(terrain) ) // AddHeightmapTerrainPartToCollector(collector, terrain, bounds); // } // */ // //SodanKerjuu: Lo-Tek style, better hope you don't have more than one terrain // foreach( HeightmapTerrain terrain in HeightmapTerrain.Instances ) // if( geometries.Contains( terrain ) ) // AddHeightmapTerrainPartToCollector( collector, terrain, bounds ); // } // return collector; //} //void AddHeightmapTerrainPartToCollector( IndexVertexBufferCollector collector, HeightmapTerrain terrain, Bounds bounds ) //{ // int size = terrain.GetHeightmapSizeAsInteger(); // Vec3[] vertices = new Vec3[ ( size + 1 ) * ( size + 1 ) ]; // int[] indices = new int[ size * size * 6 ]; // int vertexPosition = 0; // int indexPosition = 0; // for( int y = 0; y < size + 1; y++ ) // { // for( int x = 0; x < size + 1; x++ ) // { // если очень большое число дыр, то будет излишне? // //SodanKerjuu: no need, you will have unused vertices, but they won't matter for Recast if they are not indexed // //if( !terrain.GetHoleFlag( new Vec2i( x, y ) ) ) // //{ // Vec2 pos2 = terrain.GetPositionXY( new Vec2i( x, y ) ); // Vec3 pos = new Vec3( pos2.X, pos2.Y, terrain.GetHeight( new Vec2i( x, y ) ) ); // vertices[ vertexPosition ] = pos; // vertexPosition++; // //} // } // } // for( int y = 0; y < size; y++ ) // { // for( int x = 0; x < size; x++ ) // { // if( !terrain.GetHoleFlag( new Vec2i( x, y ) ) ) // { // indices[ indexPosition + 0 ] = ( size + 1 ) * y + x; // indices[ indexPosition + 1 ] = ( size + 1 ) * y + x + 1; // indices[ indexPosition + 2 ] = ( size + 1 ) * ( y + 1 ) + x + 1; // indices[ indexPosition + 3 ] = ( size + 1 ) * ( y + 1 ) + x + 1; // indices[ indexPosition + 4 ] = ( size + 1 ) * ( y + 1 ) + x; // indices[ indexPosition + 5 ] = ( size + 1 ) * y + x; // indexPosition += 6; // } // } // } // collector.Add( vertices, vertexPosition, indices, indexPosition ); //} bool AddEntityToCollector( IndexVertexBufferCollector collector, Entity entity ) { //Static meshes StaticMesh staticMesh = entity as StaticMesh; if( staticMesh != null ) { if( staticMesh.Collision == false ) return false; Mesh mesh; if( !string.IsNullOrEmpty( staticMesh.CollisionSpecialMeshName ) ) mesh = MeshManager.Instance.Load( staticMesh.CollisionSpecialMeshName ); else mesh = MeshManager.Instance.Load( staticMesh.MeshName ); if( mesh == null ) return false; Mat4 transform = staticMesh.GetTransform(); foreach( SubMesh subMesh in mesh.SubMeshes ) { if( subMesh.AllowCollision ) { Vec3[] vertices; int[] indices; subMesh.GetSomeGeometry( out vertices, out indices ); if( vertices != null ) { for( int n = 0; n < vertices.Length; n++ ) vertices[ n ] = transform * vertices[ n ]; collector.Add( vertices, vertices.Length, indices, indices.Length ); } } } return true; } //MapObjectAttachedMesh MapObject mapObject = entity as MapObject; if( mapObject != null && !( entity is StaticMesh ) ) //SodanKerjuu: static meshes qualify as both { bool added = false; foreach( MapObjectAttachedObject attachedObject in mapObject.AttachedObjects ) { MapObjectAttachedMesh attachedMesh = attachedObject as MapObjectAttachedMesh; if( attachedMesh != null && attachedMesh.Collision ) { Mesh mesh; if( !string.IsNullOrEmpty( attachedMesh.CollisionSpecialMeshName ) ) mesh = MeshManager.Instance.Load( attachedMesh.CollisionSpecialMeshName ); else mesh = MeshManager.Instance.Load( attachedMesh.MeshName ); if( mesh != null ) { Vec3 pos; Quat rot; Vec3 scl; attachedMesh.GetGlobalTransform( out pos, out rot, out scl ); Mat4 transform = new Mat4( rot.ToMat3() * Mat3.FromScale( scl ), pos ); foreach( SubMesh subMesh in mesh.SubMeshes ) { if( subMesh.AllowCollision ) { Vec3[] vertices; int[] indices; subMesh.GetSomeGeometry( out vertices, out indices ); if( vertices != null ) { for( int n = 0; n < vertices.Length; n++ ) vertices[ n ] = transform * vertices[ n ]; collector.Add( vertices, vertices.Length, indices, indices.Length ); added = true; } } } } } } return added; } //HeightmapTerrain HeightmapTerrain terrain = entity as HeightmapTerrain; if( terrain != null ) { int size = terrain.GetHeightmapSizeAsInteger(); Vec3[] vertices = new Vec3[ ( size + 1 ) * ( size + 1 ) ]; int[] indices = new int[ size * size * 6 ]; int vertexPosition = 0; int indexPosition = 0; for( int y = 0; y < size + 1; y++ ) { for( int x = 0; x < size + 1; x++ ) { //SodanKerjuu: no need, you will have unused vertices, but they won't matter for Recast if they are not indexed //if( !terrain.GetHoleFlag( new Vec2i( x, y ) ) ) //{ Vec2 pos2 = terrain.GetPositionXY( new Vec2I( x, y ) ); Vec3 pos = new Vec3( pos2.X, pos2.Y, terrain.GetHeight( new Vec2I( x, y ) ) ); vertices[ vertexPosition ] = pos; vertexPosition++; //} } } for( int y = 0; y < size; y++ ) { for( int x = 0; x < size; x++ ) { if( !terrain.GetHoleFlag( new Vec2I( x, y ) ) ) { indices[ indexPosition + 0 ] = ( size + 1 ) * y + x; indices[ indexPosition + 1 ] = ( size + 1 ) * y + x + 1; indices[ indexPosition + 2 ] = ( size + 1 ) * ( y + 1 ) + x + 1; indices[ indexPosition + 3 ] = ( size + 1 ) * ( y + 1 ) + x + 1; indices[ indexPosition + 4 ] = ( size + 1 ) * ( y + 1 ) + x; indices[ indexPosition + 5 ] = ( size + 1 ) * y + x; indexPosition += 6; } } } collector.Add( vertices, vertexPosition, indices, indexPosition ); return true; } return false; }
void AddGeometryTagToCollector( IndexVertexBufferCollector collector, Component_Pathfinding_GeometryTag geometryTag ) { //!!!! //_MeshInSpace var meshInSpace = geometryTag.Parent as Component_MeshInSpace; if( meshInSpace != null ) { var mesh = meshInSpace.Mesh.Value; if( mesh != null && mesh.Result != null ) { var transform = meshInSpace.Transform.Value.ToMatrix4(); var vertices = new Vector3[ mesh.Result.ExtractedVerticesPositions.Length ]; for( int n = 0; n < vertices.Length; n++ ) vertices[ n ] = transform * mesh.Result.ExtractedVerticesPositions[ n ].ToVector3(); collector.Add( vertices, mesh.Result.ExtractedIndices ); } } ////HeightmapTerrain //HeightmapTerrain terrain = entity as HeightmapTerrain; //if( terrain != null && terrain.Enabled ) //{ // int size = terrain.GetHeightmapSizeAsInteger(); // Vec3[] vertices = new Vec3[ ( size + 1 ) * ( size + 1 ) ]; // int[] indices = new int[ size * size * 6 ]; // int vertexPosition = 0; // int indexPosition = 0; // for( int y = 0; y < size + 1; y++ ) // { // for( int x = 0; x < size + 1; x++ ) // { // //if( !terrain.GetHoleFlag( new Vec2i( x, y ) ) ) // //{ // Vec2 pos2 = terrain.GetPositionXY( new Vec2I( x, y ) ); // Vec3 pos = new Vec3( pos2.X, pos2.Y, terrain.GetHeight( new Vec2I( x, y ) ) ); // vertices[ vertexPosition ] = pos; // vertexPosition++; // //} // } // } // for( int y = 0; y < size; y++ ) // { // for( int x = 0; x < size; x++ ) // { // if( !terrain.GetHoleFlag( new Vec2I( x, y ) ) ) // { // indices[ indexPosition + 0 ] = ( size + 1 ) * y + x; // indices[ indexPosition + 1 ] = ( size + 1 ) * y + x + 1; // indices[ indexPosition + 2 ] = ( size + 1 ) * ( y + 1 ) + x + 1; // indices[ indexPosition + 3 ] = ( size + 1 ) * ( y + 1 ) + x + 1; // indices[ indexPosition + 4 ] = ( size + 1 ) * ( y + 1 ) + x; // indices[ indexPosition + 5 ] = ( size + 1 ) * y + x; // indexPosition += 6; // } // } // } // collector.Add( vertices, vertexPosition, indices, indexPosition ); //} }
void AddGeometryToCollector( IndexVertexBufferCollector collector, Component_Pathfinding_Geometry geometry ) { geometry.GetGeometry( out var vertices, out var indices ); if( vertices != null ) collector.Add( vertices, indices ); }