Files
UnrealEngine/Engine/Source/Editor/UnrealEd/Private/ParamParser.cpp
2025-05-18 13:04:45 +08:00

311 lines
6.8 KiB
C++

// Copyright Epic Games, Inc. All Rights Reserved.
/*=============================================================================
ParamParser.cpp: Functions to help parse commands.
What's happening: When the Visual Basic level editor is being used,
this code exchanges messages with Visual Basic. This lets Visual Basic
affect the world, and it gives us a way of sending world information back
to Visual Basic.
=============================================================================*/
#include "CoreTypes.h"
#include "Logging/LogMacros.h"
#include "Math/Rotator.h"
#include "Math/UnrealMathSSE.h"
#include "Math/Vector.h"
#include "Misc/CString.h"
#include "Misc/Parse.h"
/*-----------------------------------------------------------------------------
Getters.
All of these functions return 1 if the appropriate item was
fetched, or 0 if not.
-----------------------------------------------------------------------------*/
DEFINE_LOG_CATEGORY_STATIC(LogParamParser, Log, All);
//
// Get a floating-point vector (X=, Y=, Z=).
//
bool GetFVECTOR( const TCHAR* Stream, FVector& Value )
{
int32 NumVects = 0;
Value = FVector::ZeroVector;
// Support for old format.
NumVects += FParse::Value( Stream, TEXT("X="), Value.X );
NumVects += FParse::Value( Stream, TEXT("Y="), Value.Y );
NumVects += FParse::Value( Stream, TEXT("Z="), Value.Z );
// New format.
if( NumVects == 0 )
{
Value.X = (FVector::FReal)FCString::Atof(Stream);
Stream = FCString::Strchr(Stream,',');
if( !Stream )
{
return 0;
}
Stream++;
Value.Y = (FVector::FReal)FCString::Atof(Stream);
Stream = FCString::Strchr(Stream,',');
if( !Stream )
{
return 0;
}
Stream++;
Value.Z = (FVector::FReal)FCString::Atof(Stream);
NumVects=3;
}
return NumVects==3;
}
/**
* Get a floating-point vector (X Y Z)
*
* @param The stream which has the vector in it
* @param this is an out param which will have the FVector
*
* @return this will return the current location in the stream after having processed the Vector out of it
**/
const TCHAR* GetFVECTORSpaceDelimited( const TCHAR* Stream, FVector& Value )
{
if( Stream == NULL )
{
return NULL;
}
Value = FVector::ZeroVector;
Value.X = FCString::Atof(Stream);
//UE_LOG(LogParamParser, Warning, TEXT("Value.X %f"), Value.X );
Stream = FCString::Strchr(Stream,' ');
if( !Stream )
{
return Stream;
}
Stream++;
Value.Y = FCString::Atof(Stream);
//UE_LOG(LogParamParser, Warning, TEXT("Value.Y %f"), Value.Y );
Stream = FCString::Strchr(Stream,' ');
if( !Stream )
{
return Stream;
}
Stream++;
Value.Z = FCString::Atof(Stream);
//UE_LOG(LogParamParser, Warning, TEXT("Value.Z %f"), Value.Z );
return Stream;
}
//
// Get a string enclosed in parenthesis.
//
bool GetSUBSTRING
(
const TCHAR* Stream,
const TCHAR* Match,
TCHAR* Value,
int32 MaxLen
)
{
const TCHAR* Found = FCString::Strifind(Stream,Match);
const TCHAR* Start;
if( Found == NULL ) return false; // didn't match.
Start = Found + FCString::Strlen(Match);
if( *Start != '(' )
return false;
FCString::Strncpy( Value, Start+1, MaxLen );
TCHAR* Temp=FCString::Strchr( Value, ')' );
if( Temp )
*Temp=0;
return true;
}
//
// Get a floating-point vector (X=, Y=, Z=).
//
bool GetFVECTOR
(
const TCHAR* Stream,
const TCHAR* Match,
FVector& Value
)
{
TCHAR Temp[80];
if (!GetSUBSTRING(Stream,Match,Temp,80)) return false;
return GetFVECTOR(Temp,Value);
}
//
// Get a set of rotations (PITCH=, YAW=, ROLL=), return whether anything got parsed.
//
bool GetFROTATOR
(
const TCHAR* Stream,
FRotator& Rotation,
int32 ScaleFactor
)
{
float Temp=0.0;
int32 N = 0;
Rotation = FRotator::ZeroRotator;
// Old format.
if( FParse::Value(Stream,TEXT("PITCH="),Temp) ) {Rotation.Pitch = Temp * ScaleFactor; N++;}
if( FParse::Value(Stream,TEXT("YAW="), Temp) ) {Rotation.Yaw = Temp * ScaleFactor; N++;}
if( FParse::Value(Stream,TEXT("ROLL="), Temp) ) {Rotation.Roll = Temp * ScaleFactor; N++;}
// New format.
if( N == 0 )
{
Rotation.Pitch = FCString::Atof(Stream) * ScaleFactor;
Stream = FCString::Strchr(Stream,',');
if( !Stream )
{
return false;
}
Rotation.Yaw = FCString::Atof(++Stream) * ScaleFactor;
Stream = FCString::Strchr(Stream,',');
if( !Stream )
{
return false;
}
Rotation.Roll = FCString::Atof(++Stream) * ScaleFactor;
return true;
}
return true;
}
/**
* Get an int based FRotator (X Y Z)
*
* @param The stream which has the rotator in it
* @param this is an out param which will have the FRotator
*
* @return this will return the current location in the stream after having processed the rotator out of it
**/
const TCHAR* GetFROTATORSpaceDelimited
(
const TCHAR* Stream,
FRotator& Rotation,
int32 ScaleFactor
)
{
if( Stream == NULL )
{
return NULL;
}
Rotation = FRotator::ZeroRotator;
Rotation.Pitch = FCString::Atof(Stream) * ScaleFactor;
//UE_LOG(LogParamParser, Warning, TEXT("Rotation.Pitch %d"), Rotation.Pitch );
Stream = FCString::Strchr(Stream,' ');
if( !Stream )
{
return Stream;
}
Rotation.Yaw = FCString::Atof(++Stream) * ScaleFactor;
//UE_LOG(LogParamParser, Warning, TEXT("Rotation.Yaw %d"), Rotation.Yaw );
Stream = FCString::Strchr(Stream,' ');
if( !Stream )
{
return Stream;
}
Rotation.Roll = FCString::Atof(++Stream) * ScaleFactor;
//UE_LOG(LogParamParser, Warning, TEXT("Rotation.Roll %d"), Rotation.Roll );
return Stream;
}
//
// Get a rotation value, return whether anything got parsed.
//
bool GetFROTATOR
(
const TCHAR* Stream,
const TCHAR* Match,
FRotator& Value,
int32 ScaleFactor
)
{
TCHAR Temp[80];
if (!GetSUBSTRING(Stream,Match,Temp,80)) return false;
return GetFROTATOR(Temp,Value,ScaleFactor);
}
//
// Gets a "BEGIN" string. Returns 1 if gotten, 0 if not.
// If not gotten, doesn't affect anything.
//
bool GetBEGIN( const TCHAR** Stream, const TCHAR* Match )
{
const TCHAR* Original = *Stream;
if( FParse::Command( Stream, TEXT("BEGIN") ) && FParse::Command( Stream, Match ) )
return true;
*Stream = Original;
return false;
}
//
// Gets an "END" string. Returns 1 if gotten, 0 if not.
// If not gotten, doesn't affect anything.
//
bool GetEND( const TCHAR** Stream, const TCHAR* Match )
{
const TCHAR* Original = *Stream;
if (FParse::Command (Stream,TEXT("END")) && FParse::Command (Stream,Match)) return 1; // Gotten.
*Stream = Original;
return false;
}
//
// Gets an "REMOVE" string. Returns true if gotten, false if not.
// If not gotten, doesn't affect anything.
//
bool GetREMOVE( const TCHAR** Stream, const TCHAR* Match )
{
const TCHAR* Original = *Stream;
if (FParse::Command (Stream,TEXT("REMOVE")) && FParse::Command (Stream,Match))
return true; // Gotten.
*Stream = Original;
return false;
}
//
// Output a vector.
//
TCHAR* SetFVECTOR( TCHAR* Dest, const FVector* FVector )
{
FCString::Sprintf( Dest, TEXT("%+013.6f,%+013.6f,%+013.6f"), FVector->X, FVector->Y, FVector->Z );
return Dest;
}