Skip to content

Commit

Permalink
- Added possibility to use Focal Length / FOV animation with GLTF Cam…
Browse files Browse the repository at this point in the history
…era animations.

- Added blenderPy script which shows howto set lenscurves as a custom prop float array containing all evaluated fov values
- minor cleanup to gltfparser and gltfExtras.
- gltfExtra key value pairs can now contain a bracket enclosed string as value

# Conflicts:
#	neo/idlib/gltfProperties.h
  • Loading branch information
HarrievG authored and RobertBeckebans committed Apr 29, 2023
1 parent edb62c1 commit ab7fefc
Show file tree
Hide file tree
Showing 9 changed files with 223 additions and 59 deletions.
33 changes: 31 additions & 2 deletions neo/d3xp/Camera.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ If you have questions concerning this license or the applicable additional terms

#include "Game_local.h"
#include "gltfParser.h"
#include "gltfExtras.h"


static const byte BCANIM_VERSION = 100;
Expand Down Expand Up @@ -771,7 +772,7 @@ void idCameraAnim::gltfLoadAnim( idStr gltfFileName, idStr animName )
{
gameLocal.Error( "Missing 'anim.%s' on '%s'", animName.c_str(), gltfFileName.c_str() );
}

//check for
cameraCuts.Clear();
cameraCuts.SetGranularity( 1 );
camera.Clear();
Expand Down Expand Up @@ -853,13 +854,41 @@ void idCameraAnim::gltfLoadAnim( idStr gltfFileName, idStr animName )
}
break;
case gltfAnimation_Channel_Target::scale:
{
idList<idVec3*>& values = data->GetAccessorView<idVec3>( output );
if( values.Num() > i )
{
gameLocal.Printf( "^5Frame: ^7%i ignored scale on /%s \n\n\n", i, anim->name.c_str() );
}
break;
}
break;
}
}
}

//check for extra anim data
if( anim->extras.json.Length() )
{
gltfItemArray animExtras;
GLTFARRAYITEM( animExtras, CameraLensFrames, gltfExtra_CameraLensFrames );
idLexer lexer( LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_NOSTRINGESCAPECHARS );
lexer.LoadMemory( anim->extras.json, anim->extras.json.Size(), "idCameraAnim_gltfExtra", 0 );
animExtras.Parse( &lexer , true );

if( CameraLensFrames->item )
{
auto* lensFrameValues = ( idList<double, TAG_IDLIB_LIST>* )CameraLensFrames->item;

if( lensFrameValues )
{
assert( lensFrameValues->Num() == camera.Num() );
for( int i = 0; i < lensFrameValues->Num(); i++ )
{
camera[i].fov = ( float )( *lensFrameValues )[i];
}
}
//Dont forget to free! normally a gltfPropertyArray destructor frees the itemdata
delete CameraLensFrames->item;
}
}
}
Expand Down
86 changes: 86 additions & 0 deletions neo/idlib/Lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1915,6 +1915,92 @@ const char* idLexer::ParseBracedSectionExact( idStr& out, int tabs )
return out.c_str();
}

/*
=================
idParser::ParseBracedSection
The next token should be an open brace.
Parses until a matching close brace is found.
Maintains exact characters between braces.
FIXME: this should use ReadToken and replace the token white space with correct indents and newlines
=================
*/
const char* idLexer::ParseBracketSectionExact( idStr& out, int tabs )
{
int depth;
bool doTabs;
bool skipWhite;

out.Empty();

if( !idLexer::ExpectTokenString( "[" ) )
{
return out.c_str();
}

out = "[";
depth = 1;
skipWhite = false;
doTabs = tabs >= 0;

while( depth && *idLexer::script_p )
{
char c = *( idLexer::script_p++ );

switch( c )
{
case '\t':
case ' ':
{
if( skipWhite )
{
continue;
}
break;
}
case '\n':
{
if( doTabs )
{
skipWhite = true;
out += c;
continue;
}
break;
}
case '[':
{
depth++;
tabs++;
break;
}
case ']':
{
depth--;
tabs--;
break;
}
}

if( skipWhite )
{
int i = tabs;
if( c == '[' )
{
i--;
}
skipWhite = false;
for( ; i > 0; i-- )
{
out += '\t';
}
}
out += c;
}
return out.c_str();
}

/*
=================
idLexer::ParseBracedSection
Expand Down
1 change: 1 addition & 0 deletions neo/idlib/Lexer.h
Original file line number Diff line number Diff line change
Expand Up @@ -218,6 +218,7 @@ class idLexer
const char* ParseBracedSection( idStr& out );
// parse a braced section into a string, maintaining indents and newlines
const char* ParseBracedSectionExact( idStr& out, int tabs = -1 );
const char* ParseBracketSectionExact( idStr& out, int tabs = -1 );
// parse the rest of the line
const char* ParseRestOfLine( idStr& out );
// pulls the entire line, including the \n at the end
Expand Down
23 changes: 5 additions & 18 deletions neo/idlib/gltfExtras.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,10 @@ void gltfExtra_Scatter::parse( idToken& token, idLexer* parser )
scatterInfo.Parse( parser, true );
}

void gltfExtra_cvar::parse( idToken& token, idLexer* parser )
void gltfExtra_CameraLensFrames::parse( idToken& token, idLexer* parser )
{
parser->UnreadToken( &token );
gltfItemArray cvarInfo;
idStr n, t, v, d;
GLTFARRAYITEMREF( cvarInfo, name, gltfItem , n );
GLTFARRAYITEMREF( cvarInfo, type, gltfItem , t );
GLTFARRAYITEMREF( cvarInfo, value, gltfItem, v );
GLTFARRAYITEMREF( cvarInfo, desc, gltfItem , d );
int total = cvarInfo.Parse( parser );
assert( total == 3 );
idCVar* gltExtra_cvar = new idCVar(
n.c_str(),
v.c_str(),
CVAR_SYSTEM | CVAR_BOOL,
d.c_str()
);

cvarSystem->Register( gltExtra_cvar );
item = new idList<double>();
auto* numbers = new gltfItem_number_array( "" );
numbers->Set( item, parser );
numbers->parse( token );
}
34 changes: 16 additions & 18 deletions neo/idlib/gltfExtras.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
===========================================================================
Doom 3 BFG Edition GPL Source Code
Copyright (C) 2022 Harrie van Ginneken
Copyright (C) 2022 - 2023 Harrie van Ginneken
This file is part of the Doom 3 BFG Edition GPL Source Code ("Doom 3 BFG Edition Source Code").
Expand All @@ -29,36 +29,34 @@ If you have questions concerning this license or the applicable additional terms
#include "gltfParser.h"

#ifndef gltfExtraParser
#define gltfExtraParser(className,ptype) \
class gltfExtra_##className : public parsable, public parseType<ptype> \
{public: \
gltfExtra_##className( idStr Name ) : name( Name ){ item = nullptr; } \
virtual void parse( idToken &token ){parse(token,nullptr);} \
virtual void parse( idToken &token , idLexer * parser ); \
virtual idStr &Name() { return name; } \
private: \
#define gltfExtraParser(className,ptype) \
class gltfExtra_##className : public parsable, public parseType<ptype> \
{public: \
gltfExtra_##className( idStr Name ) : name( Name ){ item = nullptr; } \
virtual void parse( idToken &token ) {parse(token,nullptr); } \
virtual void parse( idToken &token , idLexer * parser ); \
virtual idStr &Name() { return name; } \
private: \
idStr name;}
#pragma endregion

#endif

//Helper macros for gltf data deserialize
#define GLTFARRAYITEM(target,name,type) auto * name = new type (#name); target.AddItemDef((parsable*)name)
#define GLTFARRAYITEMREF(target,name,type,ref) auto * name = new type (#name); target.AddItemDef((parsable*)name); name->Set(&ref)

#ifndef GLTF_EXTRAS_H
#define GLTF_EXTRAS_H

class test
class gltfExtraStub
{
public:
test() { }
gltfExtraStub() { }
};

gltfExtraParser( Scatter, gltfExtraStub );

gltfExtraParser( Scatter, test );
gltfExtraParser( CameraLensFrames, idList<double> );

gltfExtraParser( cvar, idCVar );
#endif // GLTF_EXTRAS_H

#ifndef gltfExternalParser
#undef gltfExtraParser
#endif
#undef gltfExtraParser
31 changes: 17 additions & 14 deletions neo/idlib/gltfParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,6 @@ gltf_accessor_component::Type GetComponentTypeEnum( int id , uint* sizeInBytes

idList<gltfData*> gltfData::dataList;
idHashIndex gltfData::fileDataHash;
gltfItemArray* gltfItem_Extra::items = new gltfItemArray();

//Helper macros for gltf data deserialize
//NOTE: gltfItems that deviate from the default SET(T*) function cannot be handled with itemref macro.
Expand Down Expand Up @@ -300,14 +299,20 @@ int gltfItemArray::Fill( idLexer* lexer, idDict* strPairs )
idToken token;
bool parsing = true;
int parseCount = 0;
lexer->ExpectTokenString( "{" );
lexer->ReadToken( &token );
while( parsing && !lexer->PeekTokenString( "}" ) && lexer->ExpectAnyToken( &token ) )
{
lexer->ExpectTokenString( ":" );
idStr key = token;
idStr value;
key.StripTrailingWhitespace();
if( lexer->PeekTokenString( "{" ) )
if( lexer->PeekTokenString( "[" ) )
{
lexer->ParseBracketSectionExact( value );
value.StripTrailingWhitespace();
strPairs->Set( key, value );
}
else if( lexer->PeekTokenString( "{" ) )
{
lexer->ParseBracedSectionExact( value );
value.StripTrailingWhitespace();
Expand Down Expand Up @@ -338,6 +343,7 @@ int gltfItemArray::Parse( idLexer* lexer, bool forwardLexer/* = false*/ )
idToken token;
bool parsing = true;
int parseCount = 0;

lexer->ExpectTokenString( "{" );
while( parsing && !lexer->PeekTokenString( "}" ) && lexer->ExpectAnyToken( &token ) )
{
Expand All @@ -362,7 +368,7 @@ int gltfItemArray::Parse( idLexer* lexer, bool forwardLexer/* = false*/ )
}
if( !parsed )
{
lexer->SkipBracedSection();
lexer->SkipBracedSection( true, lexer->PeekTokenString( "{" ) ? BRSKIP_BRACES : BRSKIP_BRACKET );
}
else
{
Expand Down Expand Up @@ -452,25 +458,18 @@ void gltfItem_Extra::parse( idToken& token )
{
parser->UnreadToken( &token );
parser->ParseBracedSectionExact( item->json );

gltfItemArray items;
idLexer lexer( LEXFL_ALLOWPATHNAMES | LEXFL_ALLOWMULTICHARLITERALS | LEXFL_NOSTRINGESCAPECHARS );
lexer.LoadMemory( item->json, item->json.Size(), "gltfItem_Extra", 0 );
items->Fill( &lexer, &item->strPairs );
items.Fill( &lexer, &item->strPairs );
lexer.Reset();
items->Parse( &lexer , true );

if( gltf_parseVerbose.GetBool() )
{
common->Printf( "%s", item->json.c_str() );
}
}

void gltfItem_Extra::Register( parsable* extra )
{
common->DPrintf( "...Registering gltf Extra \"%s\" total(%i)\n", extra->Name().c_str(), items->Num() );
items->AddItemDef( extra );
}

void gltfItem_animation_sampler::parse( idToken& token )
{
gltfItemArray animSampler;
Expand Down Expand Up @@ -692,7 +691,6 @@ void gltfItem_number_array::parse( idToken& token )

void gltfItem_vec4::parse( idToken& token )
{

auto* numbers = new gltfItem_number_array( "" );
idList<double> numberarray;
numbers->Set( &numberarray, parser );
Expand All @@ -704,6 +702,7 @@ void gltfItem_vec4::parse( idToken& token )

double* val = numbers->item->Ptr();
*item = idVec4( val[0], val[1], val[2], val[3] );
delete numbers;
}

void gltfItem_vec3::parse( idToken& token )
Expand All @@ -719,6 +718,7 @@ void gltfItem_vec3::parse( idToken& token )

double* val = numbers->item->Ptr();
*item = idVec3( val[0], val[1], val[2] );
delete numbers;
}

void gltfItem_vec2::parse( idToken& token )
Expand All @@ -734,6 +734,7 @@ void gltfItem_vec2::parse( idToken& token )

double* val = numbers->item->Ptr();
*item = idVec2( val[0], val[1] );
delete numbers;
}

void gltfItem_quat::parse( idToken& token )
Expand All @@ -749,6 +750,7 @@ void gltfItem_quat::parse( idToken& token )

double* val = numbers->item->Ptr();
*item = idQuat( val[0] , val[1] , val[2] , val[3] );
delete numbers;
}

void gltfItem_mat4::parse( idToken& token )
Expand All @@ -769,6 +771,7 @@ void gltfItem_mat4::parse( idToken& token )
val[8], val[9], val[10], val[11],
val[12], val[13], val[14], val[15]
);
delete numbers;
}

void gltfItem_accessor_sparse::parse( idToken& token )
Expand Down
Loading

0 comments on commit ab7fefc

Please sign in to comment.