mirror of
https://github.com/id-Software/DOOM-3-BFG.git
synced 2025-03-13 14:12:37 +00:00
- Added possibility to use Focal Length / FOV animation with GLTF Camera 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
This commit is contained in:
parent
edb62c15d9
commit
ab7fefcadc
9 changed files with 223 additions and 59 deletions
|
@ -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;
|
||||
|
@ -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();
|
||||
|
@ -853,15 +854,43 @@ 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -218,6 +218,7 @@ public:
|
|||
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
|
||||
|
|
|
@ -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 );
|
||||
}
|
|
@ -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").
|
||||
|
||||
|
@ -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
|
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -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 ) )
|
||||
{
|
||||
|
@ -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
|
||||
{
|
||||
|
@ -452,12 +458,11 @@ 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() )
|
||||
{
|
||||
|
@ -465,12 +470,6 @@ void gltfItem_Extra::parse( idToken& token )
|
|||
}
|
||||
}
|
||||
|
||||
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;
|
||||
|
@ -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 );
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
@ -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 )
|
||||
|
|
|
@ -52,9 +52,6 @@ public:
|
|||
{
|
||||
item = type;
|
||||
}
|
||||
virtual ~parseType()
|
||||
{
|
||||
}
|
||||
T* item;
|
||||
};
|
||||
|
||||
|
@ -97,7 +94,6 @@ private:
|
|||
idStr object;
|
||||
};
|
||||
|
||||
class gltfItemArray;
|
||||
class gltfItem_Extra : public parsable, public parseType<gltfExtra>
|
||||
{
|
||||
public:
|
||||
|
@ -120,7 +116,6 @@ private:
|
|||
idStr name;
|
||||
gltfData* data;
|
||||
idLexer* parser;
|
||||
static gltfItemArray* items;
|
||||
};
|
||||
|
||||
class gltfItem_uri : public parsable, public parseType<idStr>
|
||||
|
|
|
@ -92,8 +92,6 @@ public:
|
|||
idStr json;
|
||||
//str:str pairs of each item
|
||||
idDict strPairs;
|
||||
//specialized parsers
|
||||
idList<gltfExtra*> extras;
|
||||
};
|
||||
|
||||
class gltfExt_KHR_lights_punctual;
|
||||
|
|
|
@ -0,0 +1,67 @@
|
|||
import bpy
|
||||
import numpy as np
|
||||
import functools
|
||||
import bpy
|
||||
from pathlib import Path
|
||||
from mathutils import Matrix
|
||||
import math
|
||||
|
||||
C = bpy.context
|
||||
data = bpy.data
|
||||
|
||||
########################################
|
||||
# arguments #
|
||||
########################################
|
||||
gltfExtraIdentifier = 'CameraLensFrames'
|
||||
LensFcurveTarget = 'CameraAction'
|
||||
actionTarget = 'intro_anim'
|
||||
cameraTarget = 'Camera'
|
||||
########################################
|
||||
|
||||
print("///////////////////////////////////////////////////////////////////////////////")
|
||||
print("sample Camera Lens fcurve and set as extra float array prop on target animation")
|
||||
|
||||
lensFcurveAction = None
|
||||
lensFcurve = None
|
||||
action = None
|
||||
camera = None
|
||||
|
||||
#find camera object
|
||||
for obj in data.cameras:
|
||||
if (obj.name == cameraTarget):
|
||||
camera = obj
|
||||
break
|
||||
|
||||
# iterate over all actions and find target camera with focal length fcurve and target action to add it to
|
||||
for obj in data.actions:
|
||||
if (not lensFcurve and obj.fcurves and obj.id_root == 'CAMERA' and obj.name == LensFcurveTarget):
|
||||
for fc in obj.fcurves:
|
||||
if "lens" in fc.data_path:
|
||||
lensFcurve = fc
|
||||
lensFcurveAction = obj
|
||||
|
||||
if (not action and obj.name == actionTarget):
|
||||
action = obj
|
||||
|
||||
if (action and lensFcurve):
|
||||
break
|
||||
|
||||
print ("LensCurve: {0} in action {1}".format(lensFcurve,lensFcurveAction))
|
||||
print ('action: %s' % action)
|
||||
print ('camera: %s' % camera)
|
||||
|
||||
if action and lensFcurve and camera:
|
||||
if gltfExtraIdentifier in action:
|
||||
print("Property reset")
|
||||
del action[gltfExtraIdentifier]
|
||||
|
||||
action[gltfExtraIdentifier] = np.array([], dtype = np.float32)
|
||||
|
||||
print ("setting {0} values from action {1} ".format(action.frame_range[1],lensFcurveAction.name) )
|
||||
for val in range(0,int(action.frame_range[1] + 1)):
|
||||
hFov = math.degrees(2 * math.atan(camera.sensor_width /(2 * lensFcurve.evaluate(val))))
|
||||
action[gltfExtraIdentifier] = np.append(action[gltfExtraIdentifier], hFov)
|
||||
else:
|
||||
print("Failed! Property NOT SET")
|
||||
|
||||
print ("Done!")
|
Loading…
Reference in a new issue