Code: Select all
//
// Fixed and extended version of TraceTexture() which also returns
// the Texture hit (Hint: There are Sound properties on Texture).
//
native(3250) final iterator function TraceTextures
(
Class<Actor> BaseClass,
out Actor HitActor,
out Texture Texture,
out Name TextureName,
out Name TextureGroup,
out int TextureFlags,
out Vector HitLocation,
out Vector HitNormal,
Vector TraceEnd,
optional Vector TraceStart,
optional Vector TraceExtent
);
//
// First Hit variant of TraceTextures.
// (The same as Trace is to TraceActors)
//
native(3251) final function Actor TraceSingleTexture
(
Class<Actor> BaseClass,
out Texture Texture,
out Name TextureName,
out Name TextureGroup,
out int TextureFlags,
out Vector HitLocation,
out Vector HitNormal,
Vector TraceEnd,
optional Vector TraceStart,
optional bool bTraceActors,
optional Vector TraceExtent
);
void AHXActor::execTraceTextures( FFrame& Stack, RESULT_DECL )
{
guard(AHXActor::execTraceTextures);
P_GET_CLASS(BaseClass);
P_GET_OBJECT_REF(AActor,Actor);
P_GET_OBJECT_REF(UTexture,Texture);
P_GET_NAME_REF(TextureName);
P_GET_NAME_REF(TextureGroup);
P_GET_DWORD_REF(TextureFlags);
P_GET_VECTOR_REF(HitLocation);
P_GET_VECTOR_REF(HitNormal);
P_GET_VECTOR(TraceEnd);
P_GET_VECTOR_OPTX(TraceStart,Location);
P_GET_VECTOR_OPTX(TraceExtent,FVector(0,0,0));
P_FINISH;
FMemMark MemMark( GMem );
if ( !BaseClass )
BaseClass = AActor::StaticClass();
FCheckResult* Res = GetLevel()->MultiLineCheck( GMem, TraceEnd, TraceStart, TraceExtent, 1, Level, 0 );
PRE_ITERATOR
{
if ( Res )
{
*Actor = Res->Actor;
*HitLocation = Res->Location;
*HitNormal = Res->Normal;
((UHXLevel*)GetLevel())->FindTexture( Res->Actor, Res->Location, Res->Item, *Texture, *TextureName, *TextureGroup, *TextureFlags );
Res = Res->GetNext();
}
else
{
Stack.Code = &Stack.Node->Script( wEndOffset + 1 );
*Actor = NULL;
*Texture = NULL;
*TextureName = NAME_None;
*TextureGroup = NAME_None;
*TextureFlags = 0;
break;
}
}
POST_ITERATOR
MemMark.Pop();
unguardexec;
}
void AHXActor::execTraceSingleTexture( FFrame& Stack, RESULT_DECL )
{
guard(AHXActor::execTraceSingleTexture);
P_GET_CLASS(BaseClass);
P_GET_OBJECT_REF(UTexture,Texture);
P_GET_NAME_REF(TextureName);
P_GET_NAME_REF(TextureGroup);
P_GET_DWORD_REF(TextureFlags);
P_GET_VECTOR_REF(HitLocation);
P_GET_VECTOR_REF(HitNormal);
P_GET_VECTOR(TraceEnd);
P_GET_VECTOR_OPTX(TraceStart,Location);
P_GET_UBOOL_OPTX(bTraceActors,bCollideActors);
P_GET_VECTOR_OPTX(TraceExtent,FVector(0,0,0));
P_FINISH;
FCheckResult Res( 1.0 );
GetLevel()->SingleLineCheck( Res, this, TraceEnd, TraceStart, bTraceActors ? TRACE_ProjTargets : TRACE_VisBlocking, TraceExtent, 0 );
*(AActor**)Result = Res.Actor;
*HitLocation = Res.Location;
*HitNormal = Res.Normal;
((UHXLevel*)GetLevel())->FindTexture( Res.Actor, Res.Location, Res.Item, *Texture, *TextureName, *TextureGroup, *TextureFlags );
unguardexec;
}
// Find the FBspNode for Point.
INT UHXModel::FindNode( INT iPlane, FVector Point )
{
guard(UHXModel::FindNode);
INT Index = iPlane;
while ( Index!=INDEX_NONE )
{
FBspNode& Node = Nodes(Index);
if ( Node.iSurf!=INDEX_NONE )
{
UBOOL Valid = 1;
FLOAT OldPlaneDot = 0.0f;
// Check for NumVertices == 0
if ( Node.NumVertices )
{
for ( INT i = 0; i < Node.NumVertices && Valid; i++ )
{
// Get Points.
FVector& A = Points(Verts(Node.iVertPool + i).pVertex);
FVector& B = Points(Verts(Node.iVertPool + ((i+1) % Node.NumVertices)).pVertex);
// Now build a plane.
FPlane Plane( A, (B-A)^FVector( Node.Plane.X, Node.Plane.Y, Node.Plane.Z ) );
// Now check Point against this plane.
FLOAT PlaneDot = Plane.PlaneDot( Point );
// Sign changed, check next FBspNode.
if ( OldPlaneDot * PlaneDot < 0.0f )
Valid = 0;
// Sign stayed the same, everything is fine.
else
OldPlaneDot = PlaneDot;
}
if ( Valid ) // Passed check.
return Index;
}
}
Index = Node.iPlane;
}
return INDEX_NONE;
unguard;
}
void UHXLevel::FindTexture( AActor* Actor, FVector Location, INT Item, UTexture*& Texture, FName& TextureName, FName& TextureGroup, DWORD& TextureFlags )
{
guard(UHXLevel::FindTexture);
// Reset.
Texture = NULL;
TextureName = NAME_None;
TextureGroup = NAME_None;
TextureFlags = 0;
// LevelInfo hit.
if ( Actor && Actor->Level && Actor->Level==Actor )
{
Item = ((UHXModel*)Model)->FindNode( Item, Location );
if ( Item!=INDEX_NONE )
{
FBspNode& Node = Model->Nodes(Item);
if ( Node.iSurf!=INDEX_NONE )
{
FBspSurf& Surf = Model->Surfs(Node.iSurf);
if ( Surf.Texture )
{
Texture = Surf.Texture;
TextureName = Surf.Texture->GetFName();
if ( Surf.Texture->GetOuter() && Surf.Texture->GetOuter()->GetOuter() )
TextureGroup = Surf.Texture->GetOuter()->GetFName();
}
TextureFlags = Surf.PolyFlags;
}
}
}
else if ( Actor && Actor->Brush )
{
FBspNode& Node = Actor->Brush->Nodes(Item);
FBspSurf& Surf = Actor->Brush->Surfs(Node.iSurf);
if ( Surf.Texture )
{
Texture = Surf.Texture;
TextureName = Surf.Texture->GetFName();
if ( Surf.Texture->GetOuter() && Surf.Texture->GetOuter()->GetOuter() )
TextureGroup = Surf.Texture->GetOuter()->GetFName();
}
TextureFlags = Surf.PolyFlags;
}
unguard;
}