diff --git a/RELEASE-NOTES.md b/RELEASE-NOTES.md index 5b3a9e9f3..8774b147d 100644 --- a/RELEASE-NOTES.md +++ b/RELEASE-NOTES.md @@ -365,6 +365,8 @@ Using the models argument will also export all needed models by entity declarati * Allow _extra_ents.map files next to the original .map files so new entities can be added to existing maps or old entities can be tweaked with new values +* Fixed DPI Scaling problems for 4K screens + [ASSETS] * This release is the first time that contains changes to the base/ folder and is not a pure executable patch diff --git a/neo/d3xp/menus/MenuScreen.h b/neo/d3xp/menus/MenuScreen.h index a5ca9ea63..d24d40043 100644 --- a/neo/d3xp/menus/MenuScreen.h +++ b/neo/d3xp/menus/MenuScreen.h @@ -1367,6 +1367,8 @@ class idMenuScreen_Shell_SystemOptions : public idMenuScreen // RB begin SYSTEM_FIELD_POSTFX, SYSTEM_FIELD_SHADOWMAPPING, + SYSTEM_FIELD_SSAO, + SYSTEM_FIELD_AMBIENT_BRIGHTNESS, // RB end SYSTEM_FIELD_BRIGHTNESS, SYSTEM_FIELD_VOLUME, @@ -1395,12 +1397,14 @@ class idMenuScreen_Shell_SystemOptions : public idMenuScreen private: int originalFramerate; int originalAntialias; - int originalPostProcessing; int originalVsync; float originalBrightness; float originalVolume; // RB begin int originalShadowMapping; + int originalSSAO; + int originalPostProcessing; + float originalAmbientBrightness; // RB end idList modeList; diff --git a/neo/d3xp/menus/MenuScreen_Shell_SystemOptions.cpp b/neo/d3xp/menus/MenuScreen_Shell_SystemOptions.cpp index 219414aa8..b8326278c 100644 --- a/neo/d3xp/menus/MenuScreen_Shell_SystemOptions.cpp +++ b/neo/d3xp/menus/MenuScreen_Shell_SystemOptions.cpp @@ -55,7 +55,7 @@ void idMenuScreen_Shell_SystemOptions::Initialize( idMenuHandler* data ) SetSpritePath( "menuSystemOptions" ); - options = new( TAG_SWF ) idMenuWidget_DynamicList(); + options = new( TAG_SWF ) idMenuWidget_SystemOptionsList(); // RB: allow more options than defined in the SWF options->SetNumVisibleOptions( NUM_SYSTEM_OPTIONS_OPTIONS ); options->SetSpritePath( GetSpritePath(), "info", "options" ); options->SetWrappingAllowed( true ); @@ -104,6 +104,7 @@ void idMenuScreen_Shell_SystemOptions::Initialize( idMenuHandler* data ) control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_ANTIALIASING ); options->AddChild( control ); + // RB begin control = new( TAG_SWF ) idMenuWidget_ControlButton(); control->SetOptionType( OPTION_SLIDER_TEXT ); control->SetLabel( "Filmic VFX" ); @@ -112,7 +113,6 @@ void idMenuScreen_Shell_SystemOptions::Initialize( idMenuHandler* data ) control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_POSTFX ); options->AddChild( control ); - // RB begin control = new( TAG_SWF ) idMenuWidget_ControlButton(); control->SetOptionType( OPTION_SLIDER_TEXT ); control->SetLabel( "Soft Shadows" ); @@ -121,6 +121,14 @@ void idMenuScreen_Shell_SystemOptions::Initialize( idMenuHandler* data ) control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_SHADOWMAPPING ); options->AddChild( control ); + control = new( TAG_SWF ) idMenuWidget_ControlButton(); + control->SetOptionType( OPTION_SLIDER_TEXT ); + control->SetLabel( "SSAO" ); + control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_SSAO ); + control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() ); + control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_SSAO ); + options->AddChild( control ); + /*control = new( TAG_SWF ) idMenuWidget_ControlButton(); control->SetOptionType( OPTION_SLIDER_BAR ); control->SetLabel( "#str_swf_lodbias" ); @@ -128,6 +136,15 @@ void idMenuScreen_Shell_SystemOptions::Initialize( idMenuHandler* data ) control->SetupEvents( DEFAULT_REPEAT_TIME, options->GetChildren().Num() ); control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_LODBIAS ); options->AddChild( control );*/ + + control = new( TAG_SWF ) idMenuWidget_ControlButton(); + control->SetOptionType( OPTION_SLIDER_BAR ); + control->SetLabel( "Ambient Lighting" ); + control->SetDescription( "Sets the amount of indirect lighting. Needed for modern PBR reflections" ); + control->SetDataSource( &systemData, idMenuDataSource_SystemSettings::SYSTEM_FIELD_AMBIENT_BRIGHTNESS ); + control->SetupEvents( 2, options->GetChildren().Num() ); + control->AddEventAction( WIDGET_EVENT_PRESS ).Set( WIDGET_ACTION_COMMAND, idMenuDataSource_SystemSettings::SYSTEM_FIELD_SSAO ); + options->AddChild( control ); // RB end control = new( TAG_SWF ) idMenuWidget_ControlButton(); @@ -392,12 +409,14 @@ void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::LoadData { originalFramerate = com_engineHz.GetInteger(); originalAntialias = r_antiAliasing.GetInteger(); - originalPostProcessing = r_useFilmicPostProcessing.GetInteger(); originalVsync = r_swapInterval.GetInteger(); originalBrightness = r_exposure.GetFloat(); originalVolume = s_volume_dB.GetFloat(); // RB begin originalShadowMapping = r_useShadowMapping.GetInteger(); + originalSSAO = r_useSSAO.GetInteger(); + originalAmbientBrightness = r_forceAmbient.GetFloat(); + originalPostProcessing = r_useFilmicPostProcessing.GetInteger(); // RB end const int fullscreen = r_fullscreen.GetInteger(); @@ -522,15 +541,14 @@ void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustFi r_antiAliasing.SetInteger( AdjustOption( r_antiAliasing.GetInteger(), values, numValues, adjustAmount ) ); break; } + // RB begin case SYSTEM_FIELD_POSTFX: { static const int numValues = 2; static const int values[numValues] = { 0, 1 }; - //static const int values[numValues] = { 0, 2, 3, 4, 5 }; r_useFilmicPostProcessing.SetInteger( AdjustOption( r_useFilmicPostProcessing.GetInteger(), values, numValues, adjustAmount ) ); break; } - // RB begin case SYSTEM_FIELD_SHADOWMAPPING: { static const int numValues = 2; @@ -546,6 +564,22 @@ void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustFi r_lodBias.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, -1.0f, 1.0f ) ); break; }*/ + case SYSTEM_FIELD_SSAO: + { + static const int numValues = 2; + static const int values[numValues] = { 0, 1 }; + r_useSSAO.SetInteger( AdjustOption( r_useSSAO.GetInteger(), values, numValues, adjustAmount ) ); + break; + } + case SYSTEM_FIELD_AMBIENT_BRIGHTNESS: + { + const float percent = LinearAdjust( r_forceAmbient.GetFloat(), 0.0f, 1.0f, 0.0f, 100.0f ); + const float adjusted = percent + ( float )adjustAmount; + const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted ); + + r_forceAmbient.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, 0.0f, 1.0f ) ); + break; + } // RB end case SYSTEM_FIELD_BRIGHTNESS: { @@ -553,7 +587,7 @@ void idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::AdjustFi const float adjusted = percent + ( float )adjustAmount; const float clamped = idMath::ClampFloat( 0.0f, 100.0f, adjusted ); - r_exposure.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, 0.0f, 1.0f ) ); + r_exposure.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, 0.0f, 1.0f ) ); // RB r_lightScale.SetFloat( LinearAdjust( clamped, 0.0f, 100.0f, 2.0f, 4.0f ) ); break; } @@ -599,8 +633,10 @@ idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings return va( "%4i x %4i @ %dhz", modeList[vidmode].width, modeList[vidmode].height, modeList[vidmode].displayHz ); } } + case SYSTEM_FIELD_FRAMERATE: return va( "%d FPS", com_engineHz.GetInteger() ); + case SYSTEM_FIELD_VSYNC: if( r_swapInterval.GetInteger() == 1 ) { @@ -614,6 +650,7 @@ idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings { return "#str_swf_disabled"; } + case SYSTEM_FIELD_ANTIALIASING: { if( r_antiAliasing.GetInteger() == 0 ) @@ -646,6 +683,7 @@ idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings } //return va( "%dx", idMath::IPow( 2, r_motionBlur.GetInteger() ) ); // RB begin + case SYSTEM_FIELD_SHADOWMAPPING: if( r_useShadowMapping.GetInteger() == 1 ) { @@ -655,11 +693,27 @@ idSWFScriptVar idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings { return "#str_swf_disabled"; } + //case SYSTEM_FIELD_LODBIAS: // return LinearAdjust( r_lodBias.GetFloat(), -1.0f, 1.0f, 0.0f, 100.0f ); + + case SYSTEM_FIELD_SSAO: + if( r_useSSAO.GetInteger() == 1 ) + { + return "#str_swf_enabled"; + } + else + { + return "#str_swf_disabled"; + } + + case SYSTEM_FIELD_AMBIENT_BRIGHTNESS: + return LinearAdjust( r_forceAmbient.GetFloat(), 0.0f, 1.0f, 0.0f, 100.0f ); // RB end + case SYSTEM_FIELD_BRIGHTNESS: return LinearAdjust( r_exposure.GetFloat(), 0.0f, 1.0f, 0.0f, 100.0f ); + case SYSTEM_FIELD_VOLUME: { return 100.0f * Square( 1.0f - ( s_volume_dB.GetFloat() / DB_SILENCE ) ); @@ -679,31 +733,167 @@ bool idMenuScreen_Shell_SystemOptions::idMenuDataSource_SystemSettings::IsDataCh { return true; } + if( originalAntialias != r_antiAliasing.GetInteger() ) { return true; } + + if( originalVsync != r_swapInterval.GetInteger() ) + { + return true; + } + + if( originalShadowMapping != r_useShadowMapping.GetInteger() ) + { + return true; + } + + if( originalSSAO != r_useSSAO.GetInteger() ) + { + return true; + } + if( originalPostProcessing != r_useFilmicPostProcessing.GetInteger() ) { return true; } - if( originalVsync != r_swapInterval.GetInteger() ) + + if( originalAmbientBrightness != r_forceAmbient.GetFloat() ) { return true; } + if( originalBrightness != r_exposure.GetFloat() ) { return true; } + if( originalVolume != s_volume_dB.GetFloat() ) { return true; } - // RB begin - if( originalShadowMapping != r_useShadowMapping.GetInteger() ) + + return false; +} + +// RB begin +void idMenuWidget_SystemOptionsList::Update() +{ + if( GetSWFObject() == NULL ) { - return true; + return; } - // RB end - return false; + + idSWFScriptObject& root = GetSWFObject()->GetRootObject(); + + if( !BindSprite( root ) ) + { + return; + } + + //idLib::Printf( "SystemOptionsList::Update( offset = %i )\n", GetViewOffset() ); + + // clear old sprites and rebuild the options + for( int childIndex = 0; childIndex < GetTotalNumberOfOptions(); ++childIndex ) + { + idMenuWidget& child = GetChildByIndex( childIndex ); + + child.ClearSprite(); + } + + for( int optionIndex = 0; optionIndex < GetNumVisibleOptions(); ++optionIndex ) + { + if( optionIndex >= children.Num() ) + { + // not enough children + idSWFSpriteInstance* item = GetSprite()->GetScriptObject()->GetNestedSprite( va( "item%d", optionIndex ) ); + if( item != NULL ) + { + item->SetVisible( false ); + continue; + } + } + + // account view offset and total number of options + const int childIndex = ( GetViewOffset() + optionIndex ) % GetTotalNumberOfOptions(); + idMenuWidget& child = GetChildByIndex( childIndex ); + + child.SetSpritePath( GetSpritePath(), va( "item%d", optionIndex ) ); + if( child.BindSprite( root ) ) + { + if( optionIndex >= GetTotalNumberOfOptions() ) + { + child.ClearSprite(); + continue; + } + + child.Update(); + + if( optionIndex == focusIndex ) + { + child.SetState( WIDGET_STATE_SELECTING ); + } + else + { + child.SetState( WIDGET_STATE_NORMAL ); + } + } + } + + idSWFSpriteInstance* const upSprite = GetSprite()->GetScriptObject()->GetSprite( "upIndicator" ); + if( upSprite != NULL ) + { + upSprite->SetVisible( GetViewOffset() > 0 ); + } + + idSWFSpriteInstance* const downSprite = GetSprite()->GetScriptObject()->GetSprite( "downIndicator" ); + if( downSprite != NULL ) + { + downSprite->SetVisible( GetViewOffset() + GetNumVisibleOptions() < GetTotalNumberOfOptions() ); + } +} + +void idMenuWidget_SystemOptionsList::Scroll( const int scrollAmount, const bool wrapAround ) +{ + if( GetTotalNumberOfOptions() == 0 ) + { + return; + } + + int newIndex, newOffset; + + // RB: always wrap around + CalculatePositionFromIndexDelta( newIndex, newOffset, GetViewIndex(), GetViewOffset(), GetNumVisibleOptions(), GetTotalNumberOfOptions(), scrollAmount, IsWrappingAllowed(), true ); //wrapAround ); + + //int oldViewIndex = GetViewIndex(); + //int oldViewOffset = GetViewOffset(); + int oldFocusIndex = GetFocusIndex(); + + if( newOffset != GetViewOffset() ) + { + SetViewOffset( newOffset ); + if( menuData != NULL ) + { + menuData->PlaySound( GUI_SOUND_FOCUS ); + } + + // RB: HACK and I don't like it. + // focusIndex is used here for the visible state and not for event handling. + focusIndex = newIndex; + Update(); + focusIndex = oldFocusIndex; + } + + if( newIndex != GetViewIndex() ) + { + SetViewIndex( newIndex ); + + // trigger focus/unfocus sprite actions + SetFocusIndex( newIndex );// - newOffset ); + } + + //idLib::Printf( "scroll = %i, index = %i -> %i, offset = %i -> %i, focus = %i -> %i\n", scrollAmount, oldViewIndex, newIndex, oldViewOffset, newOffset, oldFocusIndex, GetFocusIndex() ); } +// RB end + diff --git a/neo/d3xp/menus/MenuWidget.h b/neo/d3xp/menus/MenuWidget.h index fb8c45764..ec6ada2b1 100644 --- a/neo/d3xp/menus/MenuWidget.h +++ b/neo/d3xp/menus/MenuWidget.h @@ -1271,8 +1271,18 @@ class idMenuWidget_ScoreboardList : public idMenuWidget_DynamicList { public: virtual void Update(); - virtual int GetTotalNumberOfOptions() const; + virtual int GetTotalNumberOfOptions() const; +}; + +// RB begin +class idMenuWidget_SystemOptionsList : public idMenuWidget_DynamicList +{ +public: + virtual void Update() override; + virtual void Scroll( const int scrollAmount, const bool wrapAround = false ) override; }; +// RB end + /* ================================================ diff --git a/neo/renderer/OpenGL/Image_GL.cpp b/neo/renderer/OpenGL/Image_GL.cpp index 8c7cf7d83..99338fe85 100644 --- a/neo/renderer/OpenGL/Image_GL.cpp +++ b/neo/renderer/OpenGL/Image_GL.cpp @@ -550,7 +550,7 @@ void idImage::SetTexParameters() } } - // RB: disabled use of unreliable extension that can make the game look worse + // RB: disabled use of unreliable extension that can make the game look worse but doesn't save any VRAM /* if( glConfig.textureLODBiasAvailable && ( usage != TD_FONT ) ) { diff --git a/neo/renderer/RenderSystem_init.cpp b/neo/renderer/RenderSystem_init.cpp index c1a17c7b7..f7590849a 100644 --- a/neo/renderer/RenderSystem_init.cpp +++ b/neo/renderer/RenderSystem_init.cpp @@ -99,8 +99,7 @@ idCVar r_useSeamlessCubeMap( "r_useSeamlessCubeMap", "1", CVAR_RENDERER | CVAR_B idCVar r_maxAnisotropicFiltering( "r_maxAnisotropicFiltering", "8", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_INTEGER, "limit aniso filtering" ); idCVar r_useTrilinearFiltering( "r_useTrilinearFiltering", "1", CVAR_RENDERER | CVAR_ARCHIVE | CVAR_BOOL, "Extra quality filtering" ); // RB: not used anymore -// SRS - Reenabled LODBIAS -idCVar r_lodBias( "r_lodBias", "0.5", CVAR_RENDERER | CVAR_ARCHIVE, /*"UNUSED: */"image lod bias" ); +idCVar r_lodBias( "r_lodBias", "0.5", CVAR_RENDERER | CVAR_ARCHIVE, "UNUSED: image lod bias" ); // RB end idCVar r_useStateCaching( "r_useStateCaching", "1", CVAR_RENDERER | CVAR_BOOL, "avoid redundant state changes in GL_*() calls" ); diff --git a/neo/swf/SWF_Main.cpp b/neo/swf/SWF_Main.cpp index 755de6ad5..0a8020911 100644 --- a/neo/swf/SWF_Main.cpp +++ b/neo/swf/SWF_Main.cpp @@ -179,7 +179,7 @@ idSWF::idSWF( const char* filename_, idSoundWorld* soundWorld_ ) } } - if( postLoadExportFlashToSWF.GetBool() ) + if( postLoadExportFlashToJSON.GetBool() ) { idStr jsonFileName = "exported/"; jsonFileName += filename; diff --git a/tools/blender/blender-2.93/scripts/addons/io_rbdoom_flash/__init__.py b/tools/blender/blender-2.93/scripts/addons/io_rbdoom_flash/__init__.py new file mode 100644 index 000000000..41683738e --- /dev/null +++ b/tools/blender/blender-2.93/scripts/addons/io_rbdoom_flash/__init__.py @@ -0,0 +1,430 @@ +# THIS SCRIPT IS EXPERIMENTAL, UNFINISHED AND UNSUPPORTED + +# RB: My intention of this script is to provide it as a backup before it gets lost. +# Feel free to experiment with it and to load the id Tech 4.x Flash guis into Blender without animation + +import json, sys, bpy +import mathutils +import time +import os +from decimal import * +from math import * + +jsonfilename = "C:\\Projects\\RBDOOM-3-BFG\\base\\exported\\swf\\shell.json" +basepath = "C:\\Projects\\RBDOOM-3-BFG\\base\\" + +start = time.time() +data = json.loads( open( jsonfilename ).read() ) +end = time.time() +print( "loading {0} took {1} seconds".format( jsonfilename, ( end - start ) ) ) + + +scene = bpy.context.scene + +#[ %f, %f, %f, %f, %f, %f ]", m.xx, m.yy, m.xy, m.yx, m.tx, m.ty +def transform_by_stylematrix( m, uv ): + return ( ( uv[0] * m[0] ) + ( uv[1] * m[2] ) + m[4], ( uv[1] * m[1] ) + ( uv[0] * m[3] ) + m[5] ) + +def inverse_stylematrix( m ): + inverse = [ 0, 0, 0, 0, 0, 0 ]; + + det = ( ( m[0] * m[1] ) - ( m[2] * m[3] ) ) + #if( idMath::Fabs( det ) < idMath::FLT_SMALLEST_NON_DENORMAL ) + #{ + # return *this; + #} + + invDet = 1.0 / det + + inverse[0] = invDet * m[1] + inverse[3] = invDet * -m[3] + inverse[2] = invDet * -m[2] + inverse[1] = invDet * m[0] + #inverse.tx = invDet * ( xy * ty ) - ( yy * tx ); + #inverse.ty = invDet * ( yx * tx ) - ( xx * ty ); + return inverse + + +def convert_flash_object( entry, buildDict ): + #print( entry["type"] ) + + origin = ( 0, 0, 0 ) + characterID = entry["characterID"] + characterIDStr = "characterID.{0}".format( entry["characterID"] ) + + #print( "processing characterID {0} = {1}".format( characterID, entry["type"] ) ) + + + if entry["type"] == "IMAGE" and buildDict == True: + + imgfile = entry["imageFile"] + imgfilename = os.path.normpath( basepath + imgfile ) + + width = entry["width"] + height = entry["height"] + + if os.path.exists( imgfilename ): + print( "found " + imgfilename ) + + # create material + mat = None + if characterIDStr in bpy.data.materials: + mat = bpy.data.materials[ characterIDStr ] + else: + mat = bpy.data.materials.new( characterIDStr ) + mat.preview_render_type = 'FLAT' + mat.use_nodes = True + + matNodes = mat.node_tree.nodes + matLinks = mat.node_tree.links + + matDisney = matNodes.get( "Principled BSDF" ) + + #bmattex.use_map_alpha = True + + # create image and assign to material + image = None + if characterIDStr in bpy.data.images: + image = bpy.data.images[ characterIDStr ] + else: + image = bpy.data.images.load( imgfilename ) + + #btex = None + #if characterIDStr in bpy.data.textures: + # btex = bpy.data.textures[ characterIDStr ] + #else: + # btex = bpy.data.textures.new( characterIDStr, type = 'IMAGE' ) + #btex.image = image + + # create image node + nodeTex = matNodes.new( "ShaderNodeTexImage" ) + nodeTex.image = image + + # create the texture coordinate + nodeUV = matNodes.new( "ShaderNodeTexCoord" ) + + matLinks.new( nodeTex.inputs["Vector"], nodeUV.outputs["UV"] ) + matLinks.new( matDisney.inputs["Base Color"], nodeTex.outputs["Color"] ) + matLinks.new( matDisney.inputs["Alpha"], nodeTex.outputs["Alpha"] ) + + mat.blend_method = 'BLEND' + + + if entry["type"] == "SHAPE" and buildDict == True: + + if "startBounds" in entry: + startBounds = entry["startBounds"] + origin = ( startBounds[0], startBounds[1], 0 ) + + meshName = "shape.{0}.mesh".format( characterID ) + + mesh = bpy.data.meshes.new( meshName ) + meshObj = bpy.data.objects.new( meshName, mesh ) + meshObj.location = origin + #ob.show_name = True + + # give object unique characterID so any sprite can reference it + meshObj["characterID"] = characterID + + # link object to scene and make active + #bpy.context.collection.objects.link( meshObj ) + #bpy.context.scene.objects.active = ob + #ob.select = True + + #shapeName = "shape.{0}".format( characterID ) + shapeCollection = bpy.data.collections.new( characterIDStr ) + shapeCollection.color_tag = 'COLOR_04' + bpy.context.scene.collection.children.link( shapeCollection ) + shapeCollection["characterID"] = characterID + + shapeCollection.objects.link( meshObj ) + bpy.data.collections[ "Dictionary" ].children.link( shapeCollection ) + + # add to SWF dictionary + #bpy.data.collections[ "Dictionary" ].objects.link( meshObj ) + + # remove from scene default collection + bpy.context.scene.collection.children.unlink( shapeCollection ) + #bpy.context.scene.collection.objects.unlink( meshObj ) + + #bpy.ops.collection.create( name = characterIDStr ) + #group = bpy.data.collections[ characterIDStr ] + + + #for i in range( len( entry["fillDraws"] ) ): + # fillDraw = entry["fillDraws"][i] + + #if len( entry["fillDraws"] ) > 1: + # error + + # build basic mesh from all fillDraws and assign different materials to the faces + verts = [] + faces = [] + numverts = 0 + + if "fillDraws" in entry: + for fillDraw in entry["fillDraws"]: + + if "startVerts" not in fillDraw: + continue + + # convert triangles to faces + indices = fillDraw["indices"] + for i in range( 0, len( indices ), 3 ): + faces.append( ( numverts + indices[i], numverts + indices[i+1], numverts + indices[i+2] ) ) + + fillDraw["firstVert"] = numverts + + for v in fillDraw["startVerts"]: + verts.append( ( v["v"][0], v["v"][1], 0.0 ) ) + numverts += 1 + + if "lineDraws" in entry: + + print( "characterID {0} = {1} has lineDraws".format( characterID, entry["type"] ) ) + + for lineDraw in entry["lineDraws"]: + + if "startVerts" not in lineDraw: + continue + + # convert triangles to faces + indices = lineDraw["indices"] + for i in range( 0, len( indices ), 3 ): + faces.append( ( numverts + indices[i], numverts + indices[i+1], numverts + indices[i+2] ) ) + + lineDraw["firstVert"] = numverts + + for v in lineDraw["startVerts"]: + verts.append( ( v["v"][0], v["v"][1], 0.0 ) ) + numverts += 1 + + mesh.from_pydata( verts, [], faces ) + + # set mesh object to active + bpy.context.view_layer.objects.active = meshObj + meshObj.select_set( True ) + + # convert tris to quads + bpy.ops.object.mode_set(mode = 'EDIT') + bpy.ops.mesh.tris_convert_to_quads() + bpy.ops.object.editmode_toggle() + + # create uv map + mesh.uv_layers.new( do_init = False, name="UVMap") + #mesh.update() + + if "fillDraws" in entry: + #for fillDraw in entry["fillDraws"]: + for i in range( len( entry["fillDraws"] ) ): + + fillDraw = entry["fillDraws"][i] + + if fillDraw["style"]["type"] == "bitmap": + + bitmapID = fillDraw["style"]["bitmapID"] + + if bitmapID == 65535: + continue + + stylematrix = inverse_stylematrix( fillDraw["style"]["startMatrix"] ) + + # build uv coords + #firstVert = fillDraw["firstVert"] + + # FIXME only calculate UVs vertices of this bitmap + for i in range( len( mesh.vertices ) ): + v = mesh.vertices[i] + + width = startBounds[2] - startBounds[0] + height = startBounds[3] - startBounds[1] + + uv = ( ( ( v.co[0] - startBounds[0] ) * ( 1.0 / width ) * 1.0 ) , ( v.co[1] - startBounds[1] ) * ( 1.0 / height ) * 1.0 ) + uv = ( 1.0 - uv[0], uv[1] ) + mesh.uv_layers[0].data[i].uv = uv + + #uv = ( v.co[0] * ( 1.0 / startBounds["width"] ) * 20.0 , v.co[1] * ( 1.0 / startBounds["height"] ) * 20.0 ) + #uv = ( 1.0 - uv[0], uv[1] ) + #me.uv_layers[0].data[i].uv = transform_by_stylematrix( stylematrix, uv ) + + if characterID == 135: + print( "v = ({0},{1}) uv = ({2},{3})".format( v.co[0], v.co[1], uv[0], uv[1] ) ) + + + # assign bitmap + + bitmap = "characterID.{0}".format( bitmapID ) + + if bitmap not in mesh.materials: + bitmapmat = bpy.data.materials[ "characterID.{0}".format( bitmapID ) ] + mesh.materials.append( bitmapmat ) + + #mesh.update() + + + if fillDraw["style"]["type"] == "solid": + + startColor = [ 1.0, 1.0, 1.0, 1.0 ] + + if "startColor" in fillDraw["style"]: + startColor = fillDraw["style"]["startColor"] + + solidmat = bpy.data.materials.new( "shape.{0}.fillDraw.{1}".format( characterID, i ) ) + solidmat.preview_render_type = 'FLAT' + #solidmat.use_shadeless = True + #solidmat.use_transparency = True + solidmat.diffuse_color = ( startColor[0], startColor[1], startColor[2], startColor[3] ) + mesh.materials.append( solidmat ) + + + + if entry["type"] == "SPRITE" and buildDict == False: + + #spriteObj = None + + bpy.ops.object.add( + type='EMPTY', + enter_editmode=False, + location=origin) + + spriteObj = bpy.context.object + + if "mainsprite" in entry: + + spriteObj.name = "mainsprite" + spriteObj.show_name = True + else: + spriteObj.name = "sprite.{0}".format( characterID ) + + spriteObj["characterID"] = characterID + + + spriteCollection = bpy.data.collections.new( characterIDStr ) + spriteCollection.color_tag = 'COLOR_03' + bpy.context.scene.collection.children.link( spriteCollection ) + + #spriteCollection = bpy.data.collections[ characterIDStr ] + spriteCollection["characterID"] = characterID + spriteCollection.objects.link( spriteObj ) + + # add to SWF Sprites + bpy.data.collections[ "Sprites" ].children.link( spriteCollection ) + + # remove from scene default collection + bpy.context.scene.collection.children.unlink( spriteCollection ) + #bpy.context.scene.collection.objects.unlink( placeObj ) + + for command in entry["commands"]: + + if command["type"] == "Tag_PlaceObject2" or command["type"] == "Tag_PlaceObject3": + + if "characterID" in command: + sourceID = command["characterID"] + + bpy.ops.object.select_all( action = 'DESELECT' ) + + #print( bpy.context.selected_objects ) + + #print( "searching sourceID ", sourceID ) + + sourceCollection = None + for source in bpy.data.collections: + if "characterID" in source and source["characterID"] == sourceID: + sourceCollection = source + break + + if sourceCollection == None: + print( "missed clone source ", sourceID ) + + else: + + #print( "duplicating target = ", target.name ) + #print( bpy.context.selected_objects ) + + # place instance at startMatrix + m = [1.0, 1.0, 0.0, 0.0, 0.0, 0.0 ] + + if "startMatrix" in command: + m = command["startMatrix"] + + #targetLocation = ( m[4], m[5], command["depth"] ) + #targetLocation = spriteObj.location + mathutils.Vector( ( m[4], m[5], -1.0 ) ) + + #targetScale = ( m[0], m[1], 1.0 ) + + # https://blender.stackexchange.com/questions/156473/how-to-avoid-operator-collection-instance-add + + #bpy.ops.object.duplicate() + placeObj = bpy.data.objects.new( name = sourceCollection.name, object_data = None ) + placeObj.instance_collection = sourceCollection + placeObj.instance_type = 'COLLECTION' + + parentCollection = spriteCollection + parentCollection.objects.link( placeObj ) + + #parentCollection = bpy.context.view_layer.active_layer_collection + #parentCollection.collection.objects.link( placeObj ) + + + + #if "mainsprite" in entry: + # placeObj.name = "mainsprite" + #else: + # placeObj.name = "sprite.{0}".format( characterID ) + + if "name" in command: + placeObj.name = "{0}.{1}.{2}".format( spriteObj.name, command["name"], sourceID ) + placeObj.show_name = True + else: + placeObj.name = "{0}.characterID.{1}".format( spriteObj.name, sourceID ) + + placeObj.parent = spriteObj + #targetClone["characterID"] = -1 + + placeObj.location = ( m[4], m[5], command["depth"] ) + placeObj.scale = ( m[0], m[1], 1.0 ) + + bpy.ops.object.select_all( action = 'DESELECT' ) + + + +def create_default_collections(): + + # remove all groups + for group in bpy.data.collections: + bpy.data.collections.remove( group ) + + #bpy.ops.collection.create( name = "Dictionary" ) + #bpy.ops.collection.create( name = "Sprites" ) + collection = bpy.data.collections.new( "Dictionary" ) + bpy.context.scene.collection.children.link( collection ) + + collection = bpy.data.collections.new( "Sprites" ) + bpy.context.scene.collection.children.link( collection ) + + print( bpy.data.collections ) + + +# clear old materials +for mat in bpy.data.materials: + mat.user_clear() + bpy.data.materials.remove( mat ) + +create_default_collections() + +start = time.time() + +for entry in data["dict"]: + convert_flash_object( entry, True ) + +i = 0 +for entry in data["dict"]: + convert_flash_object( entry, False ) + + i += 1 + + #if i == 4: + # break + +end = time.time() +print( "importing {0} took {1} seconds".format( jsonfilename, ( end - start ) ) ) \ No newline at end of file diff --git a/zip-RBDOOM-3-BFG-bakedlightdata.bat b/zip-RBDOOM-3-BFG-bakedlightdata.bat deleted file mode 100644 index 0a0b3362a..000000000 --- a/zip-RBDOOM-3-BFG-bakedlightdata.bat +++ /dev/null @@ -1,3 +0,0 @@ -7z a RBDOOM-3-BFG-1.3.0.39-baseSP_bakedlightdata.7z -r base/env/ base/maps/*.lightgrid base/maps/*_extra_ents.map -x!generated -REM sha256sum RBDOOM-3-BFG-1.3.0.39-base_bakedlightdata.7z >> SHA256SUMS.txt -pause diff --git a/zip-RBDOOM-3-BFG-bakedlightdata.sh b/zip-RBDOOM-3-BFG-bakedlightdata.sh deleted file mode 100755 index 44f73a52c..000000000 --- a/zip-RBDOOM-3-BFG-bakedlightdata.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/sh - -7z a RBDOOM-3-BFG-1.3.0.31-baseSP_bakedlightdata.7z -r base/env/ base/maps/*.lightgrid -mx9 -x!generated - -for i in `ls *7z*`; do sha256sum $i >> SHA256SUMS.txt; done