/**
 * Creates a model from the triangles in a static mesh.
 */
void CreateModelFromStaticMesh(UModel* Model,AStaticMeshActor* StaticMeshActor)
{
#if TODO_STATICMESH
    UStaticMesh*	StaticMesh = StaticMeshActor->StaticMeshComponent->StaticMesh;
    FMatrix			ActorToWorld = StaticMeshActor->ActorToWorld().ToMatrixWithScale();

    Model->Polys->Element.Empty();

    const FStaticMeshTriangle* RawTriangleData = (FStaticMeshTriangle*) StaticMesh->LODModels[0].RawTriangles.Lock(LOCK_READ_ONLY);
    if(StaticMesh->LODModels[0].RawTriangles.GetElementCount())
    {
        for(int32 TriangleIndex = 0; TriangleIndex < StaticMesh->LODModels[0].RawTriangles.GetElementCount(); TriangleIndex++)
        {
            const FStaticMeshTriangle&	Triangle	= RawTriangleData[TriangleIndex];
            FPoly*						Polygon		= new(Model->Polys->Element) FPoly;

            Polygon->Init();
            Polygon->iLink = Polygon - Model->Polys->Element.GetData();
            Polygon->Material = StaticMesh->LODModels[0].Elements[Triangle.MaterialIndex].Material;
            Polygon->PolyFlags = PF_DefaultFlags;
            Polygon->SmoothingMask = Triangle.SmoothingMask;

            new(Polygon->Vertices) FVector(ActorToWorld.TransformPosition(Triangle.Vertices[2]));
            new(Polygon->Vertices) FVector(ActorToWorld.TransformPosition(Triangle.Vertices[1]));
            new(Polygon->Vertices) FVector(ActorToWorld.TransformPosition(Triangle.Vertices[0]));

            Polygon->CalcNormal(1);
            Polygon->Finalize(NULL,0);
            FTexCoordsToVectors(Polygon->Vertices[2],FVector(Triangle.UVs[0][0].X * UModel::GetGlobalBSPTexelScale(),Triangle.UVs[0][0].Y * UModel::GetGlobalBSPTexelScale(),1),
                                Polygon->Vertices[1],FVector(Triangle.UVs[1][0].X * UModel::GetGlobalBSPTexelScale(),Triangle.UVs[1][0].Y * UModel::GetGlobalBSPTexelScale(),1),
                                Polygon->Vertices[0],FVector(Triangle.UVs[2][0].X * UModel::GetGlobalBSPTexelScale(),Triangle.UVs[2][0].Y * UModel::GetGlobalBSPTexelScale(),1),
                                &Polygon->Base,&Polygon->TextureU,&Polygon->TextureV);
        }
    }
    StaticMesh->LODModels[0].RawTriangles.Unlock();

    Model->Linked = 1;
    FBSPOps::bspValidateBrush(Model,0,1);
    Model->BuildBound();
#endif // #if TODO_STATICMESH
}
Exemple #2
0
/**
 * Rotates the specified brush's vertices.
 */
void FBSPOps::RotateBrushVerts(ABrush* Brush, const FRotator& Rotation, bool bClearComponents)
{
	if(Brush->BrushComponent->Brush && Brush->BrushComponent->Brush->Polys)
	{
		for( int32 poly = 0 ; poly < Brush->BrushComponent->Brush->Polys->Element.Num() ; poly++ )
		{
			FPoly* Poly = &(Brush->BrushComponent->Brush->Polys->Element[poly]);

			// Rotate the vertices.
			for( int32 vertex = 0 ; vertex < Poly->Vertices.Num() ; vertex++ )
			{
				Poly->Vertices[vertex] = Brush->GetPrePivot() + FRotationMatrix( Rotation ).TransformVector( Poly->Vertices[vertex] - Brush->GetPrePivot() );
			}
			Poly->Base = Brush->GetPrePivot() + FRotationMatrix( Rotation ).TransformVector( Poly->Base - Brush->GetPrePivot() );

			// Rotate the texture vectors.
			Poly->TextureU = FRotationMatrix( Rotation ).TransformVector( Poly->TextureU );
			Poly->TextureV = FRotationMatrix( Rotation ).TransformVector( Poly->TextureV );

			// Recalc the normal for the poly.
			Poly->Normal = FVector::ZeroVector;
			Poly->Finalize(Brush,0);
		}

		Brush->BrushComponent->Brush->BuildBound();

		if( !Brush->IsStaticBrush() )
		{
			csgPrepMovingBrush( Brush );
		}

		if ( bClearComponents )
		{
			Brush->ReregisterAllComponents();
		}
	}
}
Exemple #3
0
FPoly FPoly::BuildAndCutInfiniteFPoly(const FPlane& InPlane, const TArray<FPlane>& InCutPlanes, ABrush* InOwnerBrush)
{
    FPoly PolyMerged = BuildInfiniteFPoly( InPlane );
    PolyMerged.Finalize( InOwnerBrush, 1 );

    FPoly Front, Back;
    int32 result;

    for( int32 p = 0 ; p < InCutPlanes.Num() ; ++p )
    {
        const FPlane* Plane = &InCutPlanes[p];

        result = PolyMerged.SplitWithPlane( Plane->GetSafeNormal() * Plane->W, Plane->GetSafeNormal(), &Front, &Back, 1 );

        if( result == SP_Split )
        {
            PolyMerged = Back;
        }
    }

    PolyMerged.Reverse();

    return PolyMerged;
}
bool FGeomObject::FinalizeSourceData()
{
	if( !GEditorModeTools().IsModeActive(FBuiltinEditorModes::EM_Geometry) )
	{
		return 0;
	}

	ABrush* brush = GetActualBrush();
	bool Ret = false;
	double StartTime = FPlatformTime::Seconds();
	const double TimeLimit = 10.0;

	// Remove invalid polygons from the brush

	for( int32 x = 0 ; x < brush->Brush->Polys->Element.Num() ; ++x )
	{
		FPoly* Poly = &brush->Brush->Polys->Element[x];

		if( Poly->Vertices.Num() < 3 )
		{
			brush->Brush->Polys->Element.RemoveAt( x );
			x = -1;
		}
	}

	for( int32 p = 0 ; p < brush->Brush->Polys->Element.Num() ; ++p )
	{
		FPoly* Poly = &(brush->Brush->Polys->Element[p]);
		Poly->iLink = p;
		int32 SaveNumVertices = Poly->Vertices.Num();

		const bool bTimeLimitExpired = TimeLimit < FPlatformTime::Seconds() - StartTime;

		if( !Poly->IsCoplanar() || !Poly->IsConvex() )
		{
			// If the polygon is no longer coplanar and/or convex, break it up into separate triangles.

			FPoly WkPoly = *Poly;
			brush->Brush->Polys->Element.RemoveAt( p );

			TArray<FPoly> Polygons;
			if( !bTimeLimitExpired && WkPoly.Triangulate( brush, Polygons ) > 0 )
			{
				FPoly::OptimizeIntoConvexPolys( brush, Polygons );

				for( int32 t = 0 ; t < Polygons.Num() ; ++t )
				{
					brush->Brush->Polys->Element.Add( Polygons[t] );
				}
			}

			p = -1;
			Ret = true;
		}
		else
		{
			int32 FixResult = Poly->Fix();
			if( FixResult != SaveNumVertices )
			{
				// If the polygon collapses after running "Fix" against it, it needs to be
				// removed from the brushes polygon list.

				if( bTimeLimitExpired || FixResult == 0 )
				{
					brush->Brush->Polys->Element.RemoveAt( p );
				}

				p = -1;
				Ret = true;
			}
			else
			{
				// If we get here, the polygon is valid and needs to be kept.  Finalize its internals.

				Poly->Finalize(brush,1);
			}
		}
	}

	if (TimeLimit < FPlatformTime::Seconds() - StartTime)
	{
		UE_LOG(LogEditorGeometry, Error, TEXT("FGeomObject::FinalizeSourceData() failed because it took too long"));
	}

	brush->ReregisterAllComponents();

	return Ret;
}
Exemple #5
0
int32 FPoly::Triangulate( ABrush* InOwnerBrush, TArray<FPoly>& OutTriangles )
{
#if WITH_EDITOR

    if( Vertices.Num() < 3 )
    {
        return 0;
    }

    FClipSMPolygon Polygon(0);

    for( int32 v = 0 ; v < Vertices.Num() ; ++v )
    {
        FClipSMVertex vtx;
        vtx.Pos = Vertices[v];

        // Init other data so that VertsAreEqual won't compare garbage
        vtx.TangentX = FVector::ZeroVector;
        vtx.TangentY = FVector::ZeroVector;
        vtx.TangentZ = FVector::ZeroVector;
        vtx.Color = FColor(0, 0, 0);
        for( int32 uvIndex=0; uvIndex<ARRAY_COUNT(vtx.UVs); ++uvIndex )
        {
            vtx.UVs[uvIndex] = FVector2D(0.f, 0.f);
        }


        Polygon.Vertices.Add( vtx );
    }

    Polygon.FaceNormal = Normal;

    // Attempt to triangulate this polygon
    TArray<FClipSMTriangle> Triangles;
    if( TriangulatePoly( Triangles, Polygon ) )
    {
        // Create a set of FPolys from the triangles

        OutTriangles.Empty();
        FPoly TrianglePoly;

        for( int32 p = 0 ; p < Triangles.Num() ; ++p )
        {
            FClipSMTriangle* tri = &(Triangles[p]);

            TrianglePoly.Init();
            TrianglePoly.Base = tri->Vertices[0].Pos;

            TrianglePoly.Vertices.Add( tri->Vertices[0].Pos );
            TrianglePoly.Vertices.Add( tri->Vertices[1].Pos );
            TrianglePoly.Vertices.Add( tri->Vertices[2].Pos );

            if( TrianglePoly.Finalize( InOwnerBrush, 0 ) == 0 )
            {
                OutTriangles.Add( TrianglePoly );
            }
        }
    }

#endif

    return OutTriangles.Num();
}