本文整理汇总了C++中FPoly类的典型用法代码示例。如果您正苦于以下问题:C++ FPoly类的具体用法?C++ FPoly怎么用?C++ FPoly使用的例子?那么, 这里精选的类代码示例或许可以为您提供帮助。
在下文中一共展示了FPoly类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。
示例1: DecomposeUCXMesh
void DecomposeUCXMesh( const TArray<FVector>& CollisionVertices, const TArray<int32>& CollisionFaceIdx, UBodySetup* BodySetup )
{
// We keep no ref to this Model, so it will be GC'd at some point after the import.
auto TempModel = NewObject<UModel>();
TempModel->Initialize(nullptr, 1);
FMeshConnectivityBuilder ConnectivityBuilder;
// Send triangles to connectivity builder
for(int32 x = 0; x < CollisionFaceIdx.Num(); x += 3)
{
const FVector &VertexA = CollisionVertices[ CollisionFaceIdx[x + 2] ];
const FVector &VertexB = CollisionVertices[ CollisionFaceIdx[x + 1] ];
const FVector &VertexC = CollisionVertices[ CollisionFaceIdx[x + 0] ];
ConnectivityBuilder.AddTriangle( VertexA, VertexB, VertexC );
}
ConnectivityBuilder.CreateConnectivityGroups();
// For each valid group build BSP and extract convex hulls
for ( int32 i=0; i<ConnectivityBuilder.Groups.Num(); i++ )
{
const FMeshConnectivityGroup &Group = ConnectivityBuilder.Groups[ i ];
// TODO: add some BSP friendly checks here
// e.g. if group triangles form a closed mesh
// Generate polygons from group triangles
TempModel->Polys->Element.Empty();
for ( int32 j=0; j<Group.Triangles.Num(); j++ )
{
const FMeshConnectivityTriangle &Triangle = ConnectivityBuilder.Triangles[ Group.Triangles[j] ];
FPoly* Poly = new( TempModel->Polys->Element ) FPoly();
Poly->Init();
Poly->iLink = j / 3;
// Add vertices
new( Poly->Vertices ) FVector( ConnectivityBuilder.Vertices[ Triangle.Vertices[0] ].Position );
new( Poly->Vertices ) FVector( ConnectivityBuilder.Vertices[ Triangle.Vertices[1] ].Position );
new( Poly->Vertices ) FVector( ConnectivityBuilder.Vertices[ Triangle.Vertices[2] ].Position );
// Update polygon normal
Poly->CalcNormal(1);
}
// Build bounding box.
TempModel->BuildBound();
// Build BSP for the brush.
FBSPOps::bspBuild( TempModel,FBSPOps::BSP_Good,15,70,1,0 );
FBSPOps::bspRefresh( TempModel, 1 );
FBSPOps::bspBuildBounds( TempModel );
// Convert collision model into a collection of convex hulls.
// Generated convex hulls will be added to existing ones
BodySetup->CreateFromModel( TempModel, false );
}
}
示例2: FEdge
void UEditorEngine::polySplitOverlappingEdges( TArray<FPoly>* InPolyList, TArray<FPoly>* InResult )
{
InResult->Empty();
for( int32 poly = 0 ; poly < InPolyList->Num() ; poly++ )
{
FPoly* SrcPoly = &(*InPolyList)[poly];
FPoly NewPoly = *SrcPoly;
for( int32 edge = 0 ; edge < SrcPoly->Vertices.Num() ; edge++ )
{
FEdge SrcEdge = FEdge( SrcPoly->Vertices[edge], SrcPoly->Vertices[ edge+1 < SrcPoly->Vertices.Num() ? edge+1 : 0 ] );
FPlane SrcEdgePlane( SrcEdge.Vertex[0], SrcEdge.Vertex[1], SrcEdge.Vertex[0] + (SrcPoly->Normal * 16) );
for( int32 poly2 = 0 ; poly2 < InPolyList->Num() ; poly2++ )
{
FPoly* CmpPoly = &(*InPolyList)[poly2];
// We can't compare to ourselves.
if( CmpPoly == SrcPoly )
continue;
for( int32 edge2 = 0 ; edge2 < CmpPoly->Vertices.Num() ; edge2++ )
{
FEdge CmpEdge = FEdge( CmpPoly->Vertices[edge2], CmpPoly->Vertices[ edge2+1 < CmpPoly->Vertices.Num() ? edge2+1 : 0 ] );
// If both vertices on this edge lie on the same plane as the original edge, create
// a sphere around the original 2 vertices. If either of this edges vertices are inside of
// that sphere, we need to split the original edge by adding a vertex to it's poly.
if( FMath::Abs( FVector::PointPlaneDist( CmpEdge.Vertex[0], SrcEdge.Vertex[0], SrcEdgePlane ) ) < THRESH_POINT_ON_PLANE
&& FMath::Abs( FVector::PointPlaneDist( CmpEdge.Vertex[1], SrcEdge.Vertex[0], SrcEdgePlane ) ) < THRESH_POINT_ON_PLANE )
{
//
// Check THIS edge against the SOURCE edge
//
FVector Dir = SrcEdge.Vertex[1] - SrcEdge.Vertex[0];
Dir.Normalize();
float Dist = FVector::Dist( SrcEdge.Vertex[1], SrcEdge.Vertex[0] );
FVector Origin = SrcEdge.Vertex[0] + (Dir * (Dist / 2.0f));
float Radius = Dist / 2.0f;
for( int32 vtx = 0 ; vtx < 2 ; vtx++ )
if( FVector::Dist( Origin, CmpEdge.Vertex[vtx] ) && FVector::Dist( Origin, CmpEdge.Vertex[vtx] ) < Radius )
NewPoly.InsertVertex( edge2+1, CmpEdge.Vertex[vtx] );
}
}
}
}
new(*InResult)FPoly( NewPoly );
}
}
示例3: while
//
// Cut a partitioning poly by a list of polys, and add the resulting inside pieces to the
// front list and back list.
//
static void SplitPartitioner
(
UModel* Model,
FPoly** PolyList,
FPoly** FrontList,
FPoly** BackList,
int32 n,
int32 nPolys,
int32& nFront,
int32& nBack,
FPoly InfiniteEdPoly,
TArray<FPoly*>& AllocatedFPolys
)
{
FPoly FrontPoly,BackPoly;
while( n < nPolys )
{
FPoly* Poly = PolyList[n];
switch( InfiniteEdPoly.SplitWithPlane(Poly->Vertices[0],Poly->Normal,&FrontPoly,&BackPoly,0) )
{
case SP_Coplanar:
// May occasionally happen.
// UE_LOG(LogBSPOps, Log, TEXT("FilterBound: Got inficoplanar") );
break;
case SP_Front:
// Shouldn't happen if hull is correct.
// UE_LOG(LogBSPOps, Log, TEXT("FilterBound: Got infifront") );
return;
case SP_Split:
InfiniteEdPoly = BackPoly;
break;
case SP_Back:
break;
}
n++;
}
FPoly* New = new FPoly;
*New = InfiniteEdPoly;
New->Reverse();
New->iBrushPoly |= 0x40000000;
FrontList[nFront++] = New;
AllocatedFPolys.Add( New );
New = new FPoly;
*New = InfiniteEdPoly;
BackList[nBack++] = New;
AllocatedFPolys.Add( New );
}
示例4: GetWidgetLocation
FVector FEdModeTexture::GetWidgetLocation() const
{
for ( TSelectedSurfaceIterator<> It(GetWorld()) ; It ; ++It )
{
FBspSurf* Surf = *It;
ABrush* BrushActor = ( ABrush* )Surf->Actor;
if( BrushActor )
{
FPoly* poly = &BrushActor->Brush->Polys->Element[ Surf->iBrushPoly ];
return BrushActor->ActorToWorld().TransformPosition( poly->GetMidPoint() );
}
}
return FEdMode::GetWidgetLocation();
}
示例5: ClipPolygon
bool FConvexVolume::ClipPolygon(FPoly& Polygon) const
{
for(int32 PlaneIndex = 0;PlaneIndex < Planes.Num();PlaneIndex++)
{
const FPlane& Plane = Planes[PlaneIndex];
if(!Polygon.Split(-FVector(Plane),Plane * Plane.W))
return 0;
}
return 1;
}
示例6: CreateModelFromStaticMesh
/**
* 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
}
示例7: BuildInfiniteFPoly
FPoly FPoly::BuildInfiniteFPoly(const FPlane& InPlane)
{
FVector Axis1, Axis2;
// Find two non-problematic axis vectors.
InPlane.FindBestAxisVectors( Axis1, Axis2 );
// Set up the FPoly.
FPoly EdPoly;
EdPoly.Init();
EdPoly.Normal.X = InPlane.X;
EdPoly.Normal.Y = InPlane.Y;
EdPoly.Normal.Z = InPlane.Z;
EdPoly.Base = EdPoly.Normal * InPlane.W;
EdPoly.Vertices.Add( EdPoly.Base + Axis1*HALF_WORLD_MAX + Axis2*HALF_WORLD_MAX );
EdPoly.Vertices.Add( EdPoly.Base - Axis1*HALF_WORLD_MAX + Axis2*HALF_WORLD_MAX );
EdPoly.Vertices.Add( EdPoly.Base - Axis1*HALF_WORLD_MAX - Axis2*HALF_WORLD_MAX );
EdPoly.Vertices.Add( EdPoly.Base + Axis1*HALF_WORLD_MAX - Axis2*HALF_WORLD_MAX );
return EdPoly;
}
示例8: BuildInfiniteFPoly
//
// Build an FPoly representing an "infinite" plane (which exceeds the maximum
// dimensions of the world in all directions) for a particular Bsp node.
//
FPoly FBSPOps::BuildInfiniteFPoly( UModel* Model, int32 iNode )
{
FBspNode &Node = Model->Nodes [iNode ];
FBspSurf &Poly = Model->Surfs [Node.iSurf ];
FVector Base = Poly.Plane * Poly.Plane.W;
FVector Normal = Poly.Plane;
FVector Axis1,Axis2;
// Find two non-problematic axis vectors.
Normal.FindBestAxisVectors( Axis1, Axis2 );
// Set up the FPoly.
FPoly EdPoly;
EdPoly.Init();
EdPoly.Normal = Normal;
EdPoly.Base = Base;
new(EdPoly.Vertices) FVector(Base + Axis1*WORLD_MAX + Axis2*WORLD_MAX);
new(EdPoly.Vertices) FVector(Base - Axis1*WORLD_MAX + Axis2*WORLD_MAX);
new(EdPoly.Vertices) FVector(Base - Axis1*WORLD_MAX - Axis2*WORLD_MAX);
new(EdPoly.Vertices) FVector(Base + Axis1*WORLD_MAX - Axis2*WORLD_MAX);
return EdPoly;
}
示例9: RotateBrushVerts
/**
* 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();
}
}
}
示例10: while
FPoly operator*(const FPoly& a,const FPoly& b)
{
FPoly prod;
fterm *iptr,*pos;
fterm *ptr=b.start;
if (&a==&b)
{ // squaring
pos=NULL;
while (ptr!=NULL)
{ // diagonal terms
pos=prod.addterm(ptr->an*ptr->an,ptr->n+ptr->n,pos);
ptr=ptr->next;
}
ptr=b.start;
while (ptr!=NULL)
{ // above the diagonal
iptr=ptr->next;
pos=NULL;
while (iptr!=NULL)
{
pos=prod.addterm(2*ptr->an*iptr->an,ptr->n+iptr->n,pos);
iptr=iptr->next;
}
ptr=ptr->next;
}
}
else while (ptr!=NULL)
{
FPoly t=a;
t.multerm(ptr->an,ptr->n);
ptr=ptr->next;
prod+=t;
}
return prod;
}
示例11: Faces
int32 FPoly::Faces( const FPoly &Test ) const
{
// Coplanar implies not facing.
if( IsCoplanar( Test ) )
return 0;
// If this poly is frontfaced relative to all of Test's points, they're not facing.
for( int32 i=0; i<Test.Vertices.Num(); i++ )
{
if( !IsBackfaced( Test.Vertices[i] ) )
{
// If Test is frontfaced relative to on or more of this poly's points, they're facing.
for( i=0; i<Vertices.Num(); i++ )
if( Test.IsBackfaced( Vertices[i] ) )
return 1;
return 0;
}
}
return 0;
}
示例12: GenerateKDopAsSimpleCollision
int32 GenerateKDopAsSimpleCollision(UStaticMesh* StaticMesh, const TArray<FVector> &Dirs)
{
// Make sure rendering is done - so we are not changing data being used by collision drawing.
FlushRenderingCommands();
if (!PromptToRemoveExistingCollision(StaticMesh))
{
return INDEX_NONE;
}
UBodySetup* bs = StaticMesh->BodySetup;
// Do k- specific stuff.
int32 kCount = Dirs.Num();
TArray<float> maxDist;
for(int32 i=0; i<kCount; i++)
maxDist.Add(-MY_FLTMAX);
// Construct temporary UModel for kdop creation. We keep no refs to it, so it can be GC'd.
auto TempModel = NewObject<UModel>();
TempModel->Initialize(nullptr, 1);
// For each vertex, project along each kdop direction, to find the max in that direction.
const FStaticMeshLODResources& RenderData = StaticMesh->RenderData->LODResources[0];
for(int32 i=0; i<RenderData.GetNumVertices(); i++)
{
for(int32 j=0; j<kCount; j++)
{
float dist = RenderData.PositionVertexBuffer.VertexPosition(i) | Dirs[j];
maxDist[j] = FMath::Max(dist, maxDist[j]);
}
}
// Inflate kdop to ensure it is no degenerate
const float MinSize = 0.1f;
for(int32 i=0; i<kCount; i++)
{
maxDist[i] += MinSize;
}
// Now we have the planes of the kdop, we work out the face polygons.
TArray<FPlane> planes;
for(int32 i=0; i<kCount; i++)
planes.Add( FPlane(Dirs[i], maxDist[i]) );
for(int32 i=0; i<planes.Num(); i++)
{
FPoly* Polygon = new(TempModel->Polys->Element) FPoly();
FVector Base, AxisX, AxisY;
Polygon->Init();
Polygon->Normal = planes[i];
Polygon->Normal.FindBestAxisVectors(AxisX,AxisY);
Base = planes[i] * planes[i].W;
new(Polygon->Vertices) FVector(Base + AxisX * HALF_WORLD_MAX + AxisY * HALF_WORLD_MAX);
new(Polygon->Vertices) FVector(Base + AxisX * HALF_WORLD_MAX - AxisY * HALF_WORLD_MAX);
new(Polygon->Vertices) FVector(Base - AxisX * HALF_WORLD_MAX - AxisY * HALF_WORLD_MAX);
new(Polygon->Vertices) FVector(Base - AxisX * HALF_WORLD_MAX + AxisY * HALF_WORLD_MAX);
for(int32 j=0; j<planes.Num(); j++)
{
if(i != j)
{
if(!Polygon->Split(-FVector(planes[j]), planes[j] * planes[j].W))
{
Polygon->Vertices.Empty();
break;
}
}
}
if(Polygon->Vertices.Num() < 3)
{
// If poly resulted in no verts, remove from array
TempModel->Polys->Element.RemoveAt(TempModel->Polys->Element.Num()-1);
}
else
{
// Other stuff...
Polygon->iLink = i;
Polygon->CalcNormal(1);
}
}
if(TempModel->Polys->Element.Num() < 4)
{
TempModel = NULL;
return INDEX_NONE;
}
// Build bounding box.
TempModel->BuildBound();
// Build BSP for the brush.
FBSPOps::bspBuild(TempModel,FBSPOps::BSP_Good,15,70,1,0);
FBSPOps::bspRefresh(TempModel,1);
FBSPOps::bspBuildBounds(TempModel);
//.........这里部分代码省略.........
示例13: Mark
//
// Pick a splitter poly then split a pool of polygons into front and back polygons and
// recurse.
//
// iParent = Parent Bsp node, or INDEX_NONE if this is the root node.
// IsFront = 1 if this is the front node of iParent, 0 of back (undefined if iParent==INDEX_NONE)
//
void FBSPOps::SplitPolyList
(
UModel *Model,
int32 iParent,
ENodePlace NodePlace,
int32 NumPolys,
FPoly **PolyList,
EBspOptimization Opt,
int32 Balance,
int32 PortalBias,
int32 RebuildSimplePolys
)
{
FMemMark Mark(FMemStack::Get());
// Keeping track of allocated FPoly structures to delete later on.
TArray<FPoly*> AllocatedFPolys;
// To account for big EdPolys split up.
int32 NumPolysToAlloc = NumPolys + 8 + NumPolys/4;
int32 NumFront=0; FPoly **FrontList = new(FMemStack::Get(),NumPolysToAlloc)FPoly*;
int32 NumBack =0; FPoly **BackList = new(FMemStack::Get(),NumPolysToAlloc)FPoly*;
FPoly *SplitPoly = FindBestSplit( NumPolys, PolyList, Opt, Balance, PortalBias );
// Add the splitter poly to the Bsp with either a new BspSurf or an existing one.
if( RebuildSimplePolys )
{
SplitPoly->iLink = Model->Surfs.Num();
}
int32 iOurNode = bspAddNode(Model,iParent,NodePlace,0,SplitPoly);
int32 iPlaneNode = iOurNode;
// Now divide all polygons in the pool into (A) polygons that are
// in front of Poly, and (B) polygons that are in back of Poly.
// Coplanar polys are inserted immediately, before recursing.
// If any polygons are split by Poly, we ignrore the original poly,
// split it into two polys, and add two new polys to the pool.
FPoly *FrontEdPoly = new FPoly;
FPoly *BackEdPoly = new FPoly;
// Keep track of allocations.
AllocatedFPolys.Add( FrontEdPoly );
AllocatedFPolys.Add( BackEdPoly );
for( int32 i=0; i<NumPolys; i++ )
{
FPoly *EdPoly = PolyList[i];
if( EdPoly == SplitPoly )
{
continue;
}
switch( EdPoly->SplitWithPlane( SplitPoly->Vertices[0], SplitPoly->Normal, FrontEdPoly, BackEdPoly, 0 ) )
{
case SP_Coplanar:
if( RebuildSimplePolys )
{
EdPoly->iLink = Model->Surfs.Num()-1;
}
iPlaneNode = bspAddNode( Model, iPlaneNode, NODE_Plane, 0, EdPoly );
break;
case SP_Front:
FrontList[NumFront++] = PolyList[i];
break;
case SP_Back:
BackList[NumBack++] = PolyList[i];
break;
case SP_Split:
// Create front & back nodes.
FrontList[NumFront++] = FrontEdPoly;
BackList [NumBack ++] = BackEdPoly;
FrontEdPoly = new FPoly;
BackEdPoly = new FPoly;
// Keep track of allocations.
AllocatedFPolys.Add( FrontEdPoly );
AllocatedFPolys.Add( BackEdPoly );
break;
}
}
// Recursively split the front and back pools.
if( NumFront > 0 ) SplitPolyList( Model, iOurNode, NODE_Front, NumFront, FrontList, Opt, Balance, PortalBias, RebuildSimplePolys );
if( NumBack > 0 ) SplitPolyList( Model, iOurNode, NODE_Back, NumBack, BackList, Opt, Balance, PortalBias, RebuildSimplePolys );
// Delete FPolys allocated above. We cannot use FMemStack::Get() for FPoly as the array data FPoly contains will be allocated in regular memory.
//.........这里部分代码省略.........
示例14: check
//
// Find the best splitting polygon within a pool of polygons, and return its
// index (into the PolyList array).
//
static FPoly *FindBestSplit
(
int32 NumPolys,
FPoly** PolyList,
FBSPOps::EBspOptimization Opt,
int32 Balance,
int32 InPortalBias
)
{
check(NumPolys>0);
// No need to test if only one poly.
if( NumPolys==1 )
return PolyList[0];
FPoly *Poly, *Best=NULL;
float Score, BestScore;
int32 i, Index, j, Inc;
int32 Splits, Front, Back, Coplanar, AllSemiSolids;
//PortalBias -- added by Legend on 4/12/2000
float PortalBias = InPortalBias / 100.0f;
Balance &= 0xFF; // keep only the low byte to recover "Balance"
//UE_LOG(LogBSPOps, Log, TEXT("Balance=%d PortalBias=%f"), Balance, PortalBias );
if (Opt==FBSPOps::BSP_Optimal) Inc = 1; // Test lots of nodes.
else if (Opt==FBSPOps::BSP_Good) Inc = FMath::Max(1,NumPolys/20); // Test 20 nodes.
else /* BSP_Lame */ Inc = FMath::Max(1,NumPolys/4); // Test 4 nodes.
// See if there are any non-semisolid polygons here.
for( i=0; i<NumPolys; i++ )
if( !(PolyList[i]->PolyFlags & PF_AddLast) )
break;
AllSemiSolids = (i>=NumPolys);
// Search through all polygons in the pool and find:
// A. The number of splits each poly would make.
// B. The number of front and back nodes the polygon would create.
// C. Number of coplanars.
BestScore = 0;
for( i=0; i<NumPolys; i+=Inc )
{
Splits = Front = Back = Coplanar = 0;
Index = i-1;
do
{
Index++;
Poly = PolyList[Index];
} while( Index<(i+Inc) && Index<NumPolys
&& ( (Poly->PolyFlags & PF_AddLast) && !(Poly->PolyFlags & PF_Portal) )
&& !AllSemiSolids );
if( Index>=i+Inc || Index>=NumPolys )
continue;
for( j=0; j<NumPolys; j+=Inc ) if( j != Index )
{
FPoly *OtherPoly = PolyList[j];
switch( OtherPoly->SplitWithPlaneFast( FPlane( Poly->Vertices[0], Poly->Normal), NULL, NULL ) )
{
case SP_Coplanar:
Coplanar++;
break;
case SP_Front:
Front++;
break;
case SP_Back:
Back++;
break;
case SP_Split:
// Disfavor splitting polys that are zone portals.
if( !(OtherPoly->PolyFlags & PF_Portal) )
Splits++;
else
Splits += 16;
break;
}
}
// added by Legend 1/31/1999
// Score optimization: minimize cuts vs. balance tree (as specified in BSP Rebuilder dialog)
Score = ( 100.0 - float(Balance) ) * Splits + float(Balance) * FMath::Abs( Front - Back );
if( Poly->PolyFlags & PF_Portal )
{
// PortalBias -- added by Legend on 4/12/2000
//
// PortalBias enables level designers to control the effect of Portals on the BSP.
// This effect can range from 0.0 (ignore portals), to 1.0 (portals cut everything).
//
// In builds prior to this (since the 221 build dating back to 1/31/1999) the bias
// has been 1.0 causing the portals to cut the BSP in ways that will potentially
// degrade level performance, and increase the BSP complexity.
//
// By setting the bias to a value between 0.3 and 0.7 the positive effects of
// the portals are preserved without giving them unreasonable priority in the BSP.
//.........这里部分代码省略.........
示例15: class_poly
//.........这里部分代码省略.........
break;
default: break;
}
e=(k*B*l)%48;
if (e<0) e+=48;
cinv=pow(lam,e);
cinv*=(n*Fi2[i]);
cinv=pow(cinv*pow(F(j,A,B,C,D,0),k),g);
}
else
{
int N=getN(D);
// adjust A and B
if (N==2)
{
j=3;
if (A%3!=0)
{
if (B%3!=0)
{
if ((B+A+A)%3!=0) B+=(4*A);
else B+=(A+A);
}
}
else
{
if (B%3!=0)
{
if (C%3!=0)
{
if ((C+B)%3!=0) B+=(4*A);
else B+=(A+A);
}
}
}
A*=3;
}
else
{
j=4;
if ((A%N)==0)
{
A=C;
B=-B;
}
while (B%N!=0) B+=(A+A);
A*=N;
}
cinv=F(j,A,B,C,D,N);
}
// multiply polynomial by new term(s)
FPoly F;
if (conj)
{ // conjugate pair
// t^2-2a+(a^2+b^2) , where cinv=a+ib
F.addterm((Float)1,2);
F.addterm(-2*real(cinv),1);
F.addterm(real(cinv)*real(cinv)+imaginary(cinv)*imaginary(cinv),0);
}
else
{ // t-cinv
F.addterm((Float)1,1);
F.addterm(-real(cinv),0);
// store as a linear polynomial, or combine 2 to make a quadratic
if (T[0].iszero())
{
T[0]=F;
return;
}
else
{
F=T[0]*F; // got a quadratic
T[0].clear();
}
}
// accumulate Polynomial as 2^m degree components
// This allows the use of karatsuba via the "special" function
// This is the time critical bit....
for (i=1;;i++)
{
if (T[i].iszero())
{
T[i]=F; // store this 2^i degree polynomial
break;
}
else
{
F=special(T[i],F); // e.g. if i=1 two quadratics make a quartic..
T[i].clear();
}
}
}