From 9fed37bae007bd5e53963ec67e925381609a2980 Mon Sep 17 00:00:00 2001 From: Garux Date: Tue, 1 Aug 2017 13:26:50 +0300 Subject: [PATCH] Q3map2: * native surfaceparm noob support (no -custinfoparms needed) * -noob in bsp phase: assign surfaceparm noob to all map surfaces * surfaceparm ob: skip assigning surfaceparm noob with -noob on that * farplane modes: radius+radius, origin2origin, exact (add r/o/e to the number to enable), < 0 works too * samples+filter - enabled again, makes sense * -vertexscale * fixed -novertex, (0..1) sets * quick q3map_novertexlight (?) * fixed _clone _ins _instance (_clonename) * -nolm - no lightmaps * ent keys aliases:_sa - shadeangle;_ss - samplesize * -shift N -shift X Y Z: shift whole map to some coords * more fogs (256) (ingame appearence lots of ones might be bugged due to engine arrangement, needs testing) * q3map_remapshader remaps anything fine, on all stages (effect is: postrenaming shader when things are have been done) * fixed 'unknown argument 1' at -lightanglehl * -nocmdline writting to worldspawn Radiant: binds... * wasd camera binds, c - deSelect, z - delete * ExpandSelectionToEntities - shift+e * make detail - alt+d * arbitrary rotation - shifr+r * arbitrary scale - ctrl+shift+s misc... * fit width, fit height butts in surf inspector (for trims) (saves scales ratio) add old TODO with ideas --- TODO | 149 ++++++++++++++ radiant/brush.h | 20 ++ radiant/brush_primit.cpp | 82 ++++++++ radiant/brush_primit.h | 2 + radiant/brushmanip.cpp | 44 +++- radiant/brushmanip.h | 4 + radiant/camwindow.cpp | 28 +-- radiant/mainframe.cpp | 12 +- radiant/select.cpp | 18 ++ radiant/select.h | 2 + radiant/surfacedialog.cpp | 44 +++- tools/quake3/q3map2/bsp.c | 6 +- tools/quake3/q3map2/bspfile_abstract.c | 11 +- tools/quake3/q3map2/game_quake3.h | 4 + tools/quake3/q3map2/light.c | 25 ++- tools/quake3/q3map2/light_ydnar.c | 22 +- tools/quake3/q3map2/lightmaps_ydnar.c | 3 +- tools/quake3/q3map2/main.c | 275 ++++++++++++++++++++++++- tools/quake3/q3map2/map.c | 6 + tools/quake3/q3map2/model.c | 16 +- tools/quake3/q3map2/q3map2.h | 13 +- tools/quake3/q3map2/shaders.c | 9 +- tools/quake3/q3map2/surface.c | 6 +- tools/quake3/q3map2/vis.c | 15 +- tools/quake3/q3map2/visflow.c | 22 +- 25 files changed, 786 insertions(+), 52 deletions(-) create mode 100644 TODO diff --git a/TODO b/TODO new file mode 100644 index 00000000..60573df1 --- /dev/null +++ b/TODO @@ -0,0 +1,149 @@ +[-z-]: make rotate dialog non-modal + + + +BUGS + +MSI: installer bug with new folders? : create custom dir, click New Folder icon, type "FOLDER\" - gets stuck +GTK2: gtk2 crashes when trying to use bitmap fonts such as MS Sans Serif http://bugzilla.gnome.org/show_bug.cgi?id=142579 +GTK2: alt+tab while mouse button is held down: see http://bugzilla.gnome.org/show_bug.cgi?id=145156 +UI: changing resolution in floating-windows mode can screw up window positions. +HalfLife: half-life maps saved in q1 map format are not supported - currently have to convert them to hammer map format using hammer editor. And vice versa. +Entity: creating a new entity with all the brushes of another entity selected results in the latter entity having no brushes. +SConscript: build fails if SETUP=1 +SConscript: svn.py fails if not using C locale - set LC_ALL? +GUI: can't use arrow keys to navigate in camera view when capslock is enabled +GUI: screensaver causes: gdkgc-win32.c: line 905 (gdk_win32_hdc_get): assertion failed: (win32_gc->hdc == NULL) + + +FEATURES + +- paint-select or equivalent (e.g. area-selection with occlusion) +- select-complete-tall or equivalent (e.g. subtract-from-selection modifier key) +- texture pane names are often illegible, becuase 1. they are long and overlap each other and 2. they overlap the outline rectangles around the images themselves. + + +Build: document build-menu xml format. +The build menu in GtkRadiant 1.5 is entirely customisable - you can make it run qbsp3/qvis3/arghrad or any tool you want. Use 'Build > Customize...' to edit the menu. + +Menu commands are the shell commands that Radiant will execute when you choose the menu item. You can add as many commands as you want to a single menu item, and they will be executed in sequence. The commands contain variables, specified using []. The values of variables will be substituted when the command is executed. + +For example: +
[q2map] -bsp "[MapFile]"
+becomes: +
"C:\Program Files\GtkRadiant 1.5.0\q2map" -fs_basepath "c:\quake2" -bsp "c:\quake2\baseq2\maps\blah.map"
+This uses the predefined variable 'MapFile' and the custom variable 'q2map'. 'q2map' is defined in the XML file, and 'MapFile' is the full path to your map. +The 'MapFile' variable is enclosed in quotes, because the path to your map may contain spaces. +At the moment you can only create custom variables by editing the XML file. A custom variable for arghrad would look something like this: +
"[RadiantPath]arghrad"
+This variable could then be used in a command like this: +
[arghrad] "[MapFile]"
+ +Entity: option to filter non-world entities (e.g. not func_group or func_static) +Rotate Tool: if more than one object is selected, with different local orientations, use parent-space rotation pivot instead of local-space +Brush: MMB+ctrl to paint texture on whole brush/patch. +Camera: add alternative highlighting styles (used to be J). +Doom3: filter func_splinemovers +Entity: draw arrowheads to show direction of connection-lines. +? MMB to select a texture should also apply that texture to all selected faces. +Mouse: support 2-button mouse. +Grid: background colour should be different when the smallest grid is invisible due to being zoomed out. +Brush: option to disable dots on selected faces when not in face mode. +Entity: draw direction arrow for func_door and func_button angle. +Build Menu: support for editing variables. +Shaders: handle doom3 materials with multiple bumpmaps stage - use first stage, ignore later stages. +Brush: warn when a brush is dragged into a configuration with <0 volume +Textures: add option to give new brushes a specific texture instead of the last selected. +? QE-tool: click anywhere on xy view to drag entity instead of requiring clicking directly on entity. +UserDocs: how to use multi-vertex selection - replaces vertex-edit-splits-faces option: +UserDocs: how to use parent-selection: + Parent-selection works like Maya: it allows you to 'reparent' brushes + onto other entities than the one they're currently part of. To use it, + select some brushes, select an entity, Edit -> Parent. +Textures: add anisotropic filtering. +Preferences: allow preference settings to be shared across games. +Preferences: add colour 'theme' files using prefs format. +Preferences: sensible default size for prefs window. +Doom3: add model browser. +Doom3: s_diversity light key. +HalfLife: enable HL-mode on linux/osx. +Renderer: doom3 'parallel' and 'spot' light support. +Entity: add mouse-editing for doom3 light_center key +Shaders: add support for texture transforms. +Shaders: add support for 'addnormals' keyword - e.g. models/mapobjects/healthgui/healthguidirty +TGA Loader: check that true-colour images with palettes are properly handled. +Module System: reinstate 'refresh' feature. +Surface Inspector: add button for 'axial' projection for doom3. +Build: fix hardcoded engine-launch commands - use similar system to build-menu command description. +Filters: use q2/heretic2 content flags to filter brushes. +? Surface Inspector: allow material names not relative to 'textures/' for doom3 +Module System: add versioning for module-system api. +svn: remove install/ dir, create it during build process on win32 +Editing: add option to choose the default startup tool mode. +Renderer: lighting for doom3 materials without bumpmaps (e.g. mcity/mchangar2) +Renderer: realtime doom3 materials preview +Renderer: realtime doom3 shadows preview +Linux: Provide .tar.gz of example-map data for et/wolf. +Textures Window: add inner dark outline to distinguish 'is-shader' outline from white textures. +HalfLife2: add HL2 map load/save. +Selection: add move-pivot mode to allow rotation/scale around a custom pivot-point. +Selection: add rotate increment for rotate manipulator. +Selection: visibly distinguish between entity and brush selections +Selection: need 'add to selection' and 'subtract from selection' modifiers +Selection: Finish scale manipulator. +FaceCopy/PasteTexture: Make face-copy/paste-texture shortcuts customisable. +Manual: add documentation about search paths for .ent/.def/.fgd, shaders etc for each game. +Halflife: add support for cstrike fgd. +HalfLife: disable patches +HalfLife: add HL .mdl model loader. +HalfLife: add HL .spr support. +HalfLife: support fgd 'flags' attributes. +Model: add support for doom3 md5anim format +Model: support doom3 ragdolls +VFS: add ability to browse VFS from file-open dialogs. +Installer: enable q3 brush-primitives map support. +Installer: add editor manual to linux installer +Map: add conversion between map formats +Map: add conversion between entity definition formats +Build: add build-menu dmap support (doom3) +Entity: optionally draw target connection lines thicker than one pixel. +Entity: add specialised attribute-entry in entity-inspector for integer/real/color attribute types. +Patch: add cap-texture, fit-texture and natural-texture toolbar buttons +Patch: draw patches in wireframe from the back, make patches selectable from the back +Patch: add option for convert-selection-to-new-brush/patch +Patch: fix bobtoolz merge-patches feature +Patch: fix insert/remove rows/cols indicated by current selected patch vertices. +Autosave/Snapshots: Add support for multi-file maps. +Quake2: Q2 hint transparency support +Shortcuts: make shortcut list editable within radiant. +Shortcuts: convert shortcuts.ini to xml. +Shortcuts: warn when duplicate shortcuts are registered +Shortcuts: rename commands in order to group shortcuts list better. +upgrade to new API for SymGetModuleInfo - required for compiling with Visual Studio 8.0 +Doom3: lights should stay in place while resizing + + +LOW priority features + +Selection: Add shear manipulator? +Textures Window: Improve texture-manipulation and texture-browsing tools. +Undo: make selections undoable? +Win32 Installer: Automatically upgrade existing installation. +General: refactor game-specific hacks to be parameterised by .game file +Patch: Overlays, Bend Mode, Thicken. +Brush: Add brush-specific plugin API. +Entity: Draw light style numbers. +... Entity: Show models with model2 key. +Entity: Interpret _remap* key (_MindLink_). +Entity: Support _origin _angles _scale on groups. +Selection: Add Primitive-mode shortcut key/button. +Selection: Customisable manipulator size - +/- to change the size of the translate/rotate tool. +Selection: Add optional screen-relative control for constrained rotations. +Clipper: Change selection/manipulation to be consistent with other component editing. +Filtering: Either deselect filtered nodes, or render filtered nodes that are selected. +Filtering: Add customisable filter presets to set/unset multiple filters at once. +Texdef: Make texdef formats abstract, add conversion between texdef formats (use generic affine-texture-matrix format for conversions). +Textures Window: Precise display of texture size when selecting. (tooltip, possibly) +Status: 'Size of brush' display on status bar. +Colours: maya scheme default? +Quake: add support for adjusting gamma on quake palette? diff --git a/radiant/brush.h b/radiant/brush.h index 0fb6ffe2..5504f954 100644 --- a/radiant/brush.h +++ b/radiant/brush.h @@ -598,6 +598,14 @@ void fit( const Vector3& normal, const Winding& winding, float s_repeat, float t Texdef_FitTexture( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat ); } +void fitW( const Vector3& normal, const Winding& winding, float s_repeat, float t_repeat ){ + Texdef_FitTextureW( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat ); +} + +void fitH( const Vector3& normal, const Winding& winding, float s_repeat, float t_repeat ){ + Texdef_FitTextureH( m_projection, m_shader.width(), m_shader.height(), normal, winding, s_repeat, t_repeat ); +} + void emitTextureCoordinates( Winding& winding, const Vector3& normal, const Matrix4& localToWorld ){ Texdef_EmitTextureCoordinates( m_projection, m_shader.width(), m_shader.height(), winding, normal, localToWorld ); } @@ -1199,6 +1207,18 @@ void FitTexture( float s_repeat, float t_repeat ){ texdefChanged(); } +void FitTextureW( float s_repeat, float t_repeat ){ + undoSave(); + m_texdef.fitW( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat ); + texdefChanged(); +} + +void FitTextureH( float s_repeat, float t_repeat ){ + undoSave(); + m_texdef.fitH( m_plane.plane3().normal(), m_winding, s_repeat, t_repeat ); + texdefChanged(); +} + void EmitTextureCoordinates(){ Texdef_EmitTextureCoordinates( m_texdefTransformed, m_shader.width(), m_shader.height(), m_winding, plane3().normal(), g_matrix4_identity ); } diff --git a/radiant/brush_primit.cpp b/radiant/brush_primit.cpp index 4ea73c03..85ee1e46 100644 --- a/radiant/brush_primit.cpp +++ b/radiant/brush_primit.cpp @@ -1122,6 +1122,88 @@ void Texdef_FitTexture( TextureProjection& projection, std::size_t width, std::s Texdef_normalise( projection, (float)width, (float)height ); } +void Texdef_FitTextureW( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat ){ + if ( w.numpoints < 3 ) { + return; + } + + Matrix4 st2tex; + Texdef_toTransform( projection, (float)width, (float)height, st2tex ); + + // the current texture transform + Matrix4 local2tex = st2tex; + { + Matrix4 xyz2st; + Texdef_basisForNormal( projection, normal, xyz2st ); + matrix4_multiply_by_matrix4( local2tex, xyz2st ); + } + + // the bounds of the current texture transform + AABB bounds; + for ( Winding::const_iterator i = w.begin(); i != w.end(); ++i ) + { + Vector3 texcoord = matrix4_transformed_point( local2tex, ( *i ).vertex ); + aabb_extend_by_point_safe( bounds, texcoord ); + } + bounds.origin.z() = 0; + bounds.extents.z() = 1; + + // the bounds of a perfectly fitted texture transform + AABB perfect( Vector3( s_repeat * 0.5, s_repeat * 0.5 * bounds.extents.y() / bounds.extents.x(), 0 ), Vector3( s_repeat * 0.5, s_repeat * 0.5 * bounds.extents.y() / bounds.extents.x(), 1 ) ); + + // the difference between the current texture transform and the perfectly fitted transform + Matrix4 matrix( matrix4_translation_for_vec3( bounds.origin - perfect.origin ) ); + matrix4_pivoted_scale_by_vec3( matrix, bounds.extents / perfect.extents, perfect.origin ); + matrix4_affine_invert( matrix ); + + // apply the difference to the current texture transform + matrix4_premultiply_by_matrix4( st2tex, matrix ); + + Texdef_fromTransform( projection, (float)width, (float)height, st2tex ); + Texdef_normalise( projection, (float)width, (float)height ); +} + +void Texdef_FitTextureH( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat ){ + if ( w.numpoints < 3 ) { + return; + } + + Matrix4 st2tex; + Texdef_toTransform( projection, (float)width, (float)height, st2tex ); + + // the current texture transform + Matrix4 local2tex = st2tex; + { + Matrix4 xyz2st; + Texdef_basisForNormal( projection, normal, xyz2st ); + matrix4_multiply_by_matrix4( local2tex, xyz2st ); + } + + // the bounds of the current texture transform + AABB bounds; + for ( Winding::const_iterator i = w.begin(); i != w.end(); ++i ) + { + Vector3 texcoord = matrix4_transformed_point( local2tex, ( *i ).vertex ); + aabb_extend_by_point_safe( bounds, texcoord ); + } + bounds.origin.z() = 0; + bounds.extents.z() = 1; + + // the bounds of a perfectly fitted texture transform + AABB perfect( Vector3( t_repeat * 0.5 * bounds.extents.x() / bounds.extents.y(), t_repeat * 0.5, 0 ), Vector3( t_repeat * 0.5 * bounds.extents.x() / bounds.extents.y(), t_repeat * 0.5, 1 ) ); + + // the difference between the current texture transform and the perfectly fitted transform + Matrix4 matrix( matrix4_translation_for_vec3( bounds.origin - perfect.origin ) ); + matrix4_pivoted_scale_by_vec3( matrix, bounds.extents / perfect.extents, perfect.origin ); + matrix4_affine_invert( matrix ); + + // apply the difference to the current texture transform + matrix4_premultiply_by_matrix4( st2tex, matrix ); + + Texdef_fromTransform( projection, (float)width, (float)height, st2tex ); + Texdef_normalise( projection, (float)width, (float)height ); +} + float Texdef_getDefaultTextureScale(){ return g_texdef_default_scale; } diff --git a/radiant/brush_primit.h b/radiant/brush_primit.h index 79d27f3e..5e68c146 100644 --- a/radiant/brush_primit.h +++ b/radiant/brush_primit.h @@ -106,6 +106,8 @@ void Texdef_Shift( TextureProjection& projection, float s, float t ); void Texdef_Scale( TextureProjection& projection, float s, float t ); void Texdef_Rotate( TextureProjection& projection, float angle ); void Texdef_FitTexture( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat ); +void Texdef_FitTextureW( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat ); +void Texdef_FitTextureH( TextureProjection& projection, std::size_t width, std::size_t height, const Vector3& normal, const Winding& w, float s_repeat, float t_repeat ); void Texdef_EmitTextureCoordinates( const TextureProjection& projection, std::size_t width, std::size_t height, Winding& w, const Vector3& normal, const Matrix4& localToWorld ); void ShiftScaleRotate_fromFace( texdef_t& shiftScaleRotate, const TextureProjection& projection ); diff --git a/radiant/brushmanip.cpp b/radiant/brushmanip.cpp index c49464be..79b84657 100644 --- a/radiant/brushmanip.cpp +++ b/radiant/brushmanip.cpp @@ -631,6 +631,28 @@ void operator()( Face& face ) const { } }; +class FaceFitTextureW +{ +float m_s_repeat, m_t_repeat; +public: +FaceFitTextureW( float s_repeat, float t_repeat ) : m_s_repeat( s_repeat ), m_t_repeat( t_repeat ){ +} +void operator()( Face& face ) const { + face.FitTextureW( m_s_repeat, m_t_repeat ); +} +}; + +class FaceFitTextureH +{ +float m_s_repeat, m_t_repeat; +public: +FaceFitTextureH( float s_repeat, float t_repeat ) : m_s_repeat( s_repeat ), m_t_repeat( t_repeat ){ +} +void operator()( Face& face ) const { + face.FitTextureH( m_s_repeat, m_t_repeat ); +} +}; + void Scene_BrushFitTexture_Selected( scene::Graph& graph, float s_repeat, float t_repeat ){ Scene_ForEachSelectedBrush_ForEachFace( graph, FaceFitTexture( s_repeat, t_repeat ) ); SceneChangeNotify(); @@ -641,6 +663,26 @@ void Scene_BrushFitTexture_Component_Selected( scene::Graph& graph, float s_repe SceneChangeNotify(); } +void Scene_BrushFitTexture_SelectedW( scene::Graph& graph, float s_repeat, float t_repeat ){ + Scene_ForEachSelectedBrush_ForEachFace( graph, FaceFitTextureW( s_repeat, t_repeat ) ); + SceneChangeNotify(); +} + +void Scene_BrushFitTexture_Component_SelectedW( scene::Graph& graph, float s_repeat, float t_repeat ){ + Scene_ForEachSelectedBrushFace( graph, FaceFitTextureW( s_repeat, t_repeat ) ); + SceneChangeNotify(); +} + +void Scene_BrushFitTexture_SelectedH( scene::Graph& graph, float s_repeat, float t_repeat ){ + Scene_ForEachSelectedBrush_ForEachFace( graph, FaceFitTextureH( s_repeat, t_repeat ) ); + SceneChangeNotify(); +} + +void Scene_BrushFitTexture_Component_SelectedH( scene::Graph& graph, float s_repeat, float t_repeat ){ + Scene_ForEachSelectedBrushFace( graph, FaceFitTextureH( s_repeat, t_repeat ) ); + SceneChangeNotify(); +} + TextureProjection g_defaultTextureProjection; const TextureProjection& TextureTransform_getDefault(){ TexDef_Construct_Default( g_defaultTextureProjection ); @@ -1371,7 +1413,7 @@ void Brush_registerCommands(){ GlobalCommands_insert( "SplitSelected", FreeCaller(), Accelerator( GDK_Return, (GdkModifierType)GDK_SHIFT_MASK ) ); GlobalCommands_insert( "FlipClip", FreeCaller(), Accelerator( GDK_Return, (GdkModifierType)GDK_CONTROL_MASK ) ); - GlobalCommands_insert( "MakeDetail", FreeCaller(), Accelerator( 'M', (GdkModifierType)GDK_CONTROL_MASK ) ); + GlobalCommands_insert( "MakeDetail", FreeCaller(), Accelerator( 'D', (GdkModifierType)GDK_MOD1_MASK ) ); GlobalCommands_insert( "MakeStructural", FreeCaller(), Accelerator( 'S', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); } diff --git a/radiant/brushmanip.h b/radiant/brushmanip.h index 06f67271..f26e68ab 100644 --- a/radiant/brushmanip.h +++ b/radiant/brushmanip.h @@ -70,6 +70,10 @@ void Scene_BrushSelectByShader( scene::Graph& graph, const char* name ); void Scene_BrushSelectByShader_Component( scene::Graph& graph, const char* name ); void Scene_BrushFitTexture_Selected( scene::Graph& graph, float s_repeat, float t_repeat ); void Scene_BrushFitTexture_Component_Selected( scene::Graph& graph, float s_repeat, float t_repeat ); +void Scene_BrushFitTexture_SelectedW( scene::Graph& graph, float s_repeat, float t_repeat ); +void Scene_BrushFitTexture_Component_SelectedW( scene::Graph& graph, float s_repeat, float t_repeat ); +void Scene_BrushFitTexture_SelectedH( scene::Graph& graph, float s_repeat, float t_repeat ); +void Scene_BrushFitTexture_Component_SelectedH( scene::Graph& graph, float s_repeat, float t_repeat ); typedef struct _GtkMenu GtkMenu; void Brush_constructMenu( GtkMenu* menu ); diff --git a/radiant/camwindow.cpp b/radiant/camwindow.cpp index de2e03e0..3d0c6a51 100644 --- a/radiant/camwindow.cpp +++ b/radiant/camwindow.cpp @@ -954,27 +954,27 @@ void CamWnd_registerCommands( CamWnd& camwnd ){ ReferenceCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveForward", Accelerator( GDK_Up ), + GlobalKeyEvents_insert( "CameraFreeMoveForward", Accelerator( 'W' ), FreeMoveCameraMoveForwardKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveForwardKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveBack", Accelerator( GDK_Down ), + GlobalKeyEvents_insert( "CameraFreeMoveBack", Accelerator( 'S' ), FreeMoveCameraMoveBackKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveBackKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveLeft", Accelerator( GDK_Left ), + GlobalKeyEvents_insert( "CameraFreeMoveLeft", Accelerator( 'A' ), FreeMoveCameraMoveLeftKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveLeftKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveRight", Accelerator( GDK_Right ), + GlobalKeyEvents_insert( "CameraFreeMoveRight", Accelerator( 'D' ), FreeMoveCameraMoveRightKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveRightKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveUp", Accelerator( 'D' ), + GlobalKeyEvents_insert( "CameraFreeMoveUp", Accelerator( GDK_period ), FreeMoveCameraMoveUpKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveUpKeyUpCaller( camwnd.getCamera() ) ); - GlobalKeyEvents_insert( "CameraFreeMoveDown", Accelerator( 'C' ), + GlobalKeyEvents_insert( "CameraFreeMoveDown", Accelerator( GDK_comma ), FreeMoveCameraMoveDownKeyDownCaller( camwnd.getCamera() ), FreeMoveCameraMoveDownKeyUpCaller( camwnd.getCamera() ) ); @@ -1900,15 +1900,15 @@ void CamWnd_Construct(){ GlobalShortcuts_insert( "CameraStrafeRight", Accelerator( GDK_period ) ); GlobalShortcuts_insert( "CameraStrafeLeft", Accelerator( GDK_comma ) ); - GlobalShortcuts_insert( "CameraUp", Accelerator( 'D' ) ); - GlobalShortcuts_insert( "CameraDown", Accelerator( 'C' ) ); - GlobalShortcuts_insert( "CameraAngleUp", Accelerator( 'A' ) ); - GlobalShortcuts_insert( "CameraAngleDown", Accelerator( 'Z' ) ); + GlobalShortcuts_insert( "CameraUp", accelerator_null() ); + GlobalShortcuts_insert( "CameraDown", accelerator_null() ); + GlobalShortcuts_insert( "CameraAngleUp", accelerator_null() ); + GlobalShortcuts_insert( "CameraAngleDown", accelerator_null() ); - GlobalShortcuts_insert( "CameraFreeMoveForward", Accelerator( GDK_Up ) ); - GlobalShortcuts_insert( "CameraFreeMoveBack", Accelerator( GDK_Down ) ); - GlobalShortcuts_insert( "CameraFreeMoveLeft", Accelerator( GDK_Left ) ); - GlobalShortcuts_insert( "CameraFreeMoveRight", Accelerator( GDK_Right ) ); + GlobalShortcuts_insert( "CameraFreeMoveForward", Accelerator( 'W' ) ); + GlobalShortcuts_insert( "CameraFreeMoveBack", Accelerator( 'S' ) ); + GlobalShortcuts_insert( "CameraFreeMoveLeft", Accelerator( 'A' ) ); + GlobalShortcuts_insert( "CameraFreeMoveRight", Accelerator( 'D' ) ); GlobalToggles_insert( "ShowStats", ShowStatsToggleCaller(), ToggleItem::AddCallbackCaller( g_show_stats ) ); diff --git a/radiant/mainframe.cpp b/radiant/mainframe.cpp index abb12ef6..8fb38e32 100644 --- a/radiant/mainframe.cpp +++ b/radiant/mainframe.cpp @@ -3201,13 +3201,15 @@ void MainFrame_Construct(){ GlobalCommands_insert( "PasteToCamera", FreeCaller(), Accelerator( 'V', (GdkModifierType)GDK_MOD1_MASK ) ); GlobalCommands_insert( "CloneSelection", FreeCaller(), Accelerator( GDK_space ) ); GlobalCommands_insert( "CloneSelectionAndMakeUnique", FreeCaller(), Accelerator( GDK_space, (GdkModifierType)GDK_SHIFT_MASK ) ); - GlobalCommands_insert( "DeleteSelection", FreeCaller(), Accelerator( GDK_BackSpace ) ); +// GlobalCommands_insert( "DeleteSelection", FreeCaller(), Accelerator( GDK_BackSpace ) ); + GlobalCommands_insert( "DeleteSelection", FreeCaller(), Accelerator( 'Z' ) ); GlobalCommands_insert( "ParentSelection", FreeCaller() ); - GlobalCommands_insert( "UnSelectSelection", FreeCaller(), Accelerator( GDK_Escape ) ); +// GlobalCommands_insert( "UnSelectSelection", FreeCaller(), Accelerator( GDK_Escape ) ); + GlobalCommands_insert( "UnSelectSelection", FreeCaller(), Accelerator( 'C' ) ); GlobalCommands_insert( "InvertSelection", FreeCaller(), Accelerator( 'I' ) ); GlobalCommands_insert( "SelectInside", FreeCaller() ); GlobalCommands_insert( "SelectTouching", FreeCaller() ); - GlobalCommands_insert( "ExpandSelectionToEntities", FreeCaller(), Accelerator( 'E', (GdkModifierType)( GDK_MOD1_MASK | GDK_CONTROL_MASK ) ) ); + GlobalCommands_insert( "ExpandSelectionToEntities", FreeCaller(), Accelerator( 'E', (GdkModifierType)GDK_SHIFT_MASK ) ); GlobalCommands_insert( "Preferences", FreeCaller(), Accelerator( 'P' ) ); GlobalCommands_insert( "ToggleConsole", FreeCaller(), Accelerator( 'O' ) ); @@ -3228,8 +3230,8 @@ void MainFrame_Construct(){ GlobalCommands_insert( "MirrorSelectionZ", FreeCaller() ); GlobalCommands_insert( "RotateSelectionZ", FreeCaller() ); - GlobalCommands_insert( "ArbitraryRotation", FreeCaller() ); - GlobalCommands_insert( "ArbitraryScale", FreeCaller() ); + GlobalCommands_insert( "ArbitraryRotation", FreeCaller(), Accelerator( 'R', (GdkModifierType)GDK_SHIFT_MASK ) ); + GlobalCommands_insert( "ArbitraryScale", FreeCaller(), Accelerator( 'S', (GdkModifierType)( GDK_SHIFT_MASK | GDK_CONTROL_MASK ) ) ); GlobalCommands_insert( "BuildMenuCustomize", FreeCaller() ); diff --git a/radiant/select.cpp b/radiant/select.cpp index 4246ab42..0728692e 100644 --- a/radiant/select.cpp +++ b/radiant/select.cpp @@ -692,6 +692,24 @@ void Select_FitTexture( float horizontal, float vertical ){ SceneChangeNotify(); } +void Select_FitTextureW( float horizontal, float vertical ){ + if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) { + Scene_BrushFitTexture_SelectedW( GlobalSceneGraph(), horizontal, vertical ); + } + Scene_BrushFitTexture_Component_SelectedW( GlobalSceneGraph(), horizontal, vertical ); + + SceneChangeNotify(); +} + +void Select_FitTextureH( float horizontal, float vertical ){ + if ( GlobalSelectionSystem().Mode() != SelectionSystem::eComponent ) { + Scene_BrushFitTexture_SelectedH( GlobalSceneGraph(), horizontal, vertical ); + } + Scene_BrushFitTexture_Component_SelectedH( GlobalSceneGraph(), horizontal, vertical ); + + SceneChangeNotify(); +} + inline void hide_node( scene::Node& node, bool hide ){ hide ? node.enable( scene::Node::eHidden ) diff --git a/radiant/select.h b/radiant/select.h index 4a158fd4..cc5660e7 100644 --- a/radiant/select.h +++ b/radiant/select.h @@ -62,6 +62,8 @@ void Select_RotateTexture( float amt ); void Select_ScaleTexture( float x, float y ); void Select_ShiftTexture( float x, float y ); void Select_FitTexture( float horizontal = 1, float vertical = 1 ); +void Select_FitTextureW( float horizontal = 1, float vertical = 1 ); +void Select_FitTextureH( float horizontal = 1, float vertical = 1 ); void FindReplaceTextures( const char* pFind, const char* pReplace, bool bSelected ); void HideSelected(); diff --git a/radiant/surfacedialog.cpp b/radiant/surfacedialog.cpp index ac02d7fd..3d64f411 100644 --- a/radiant/surfacedialog.cpp +++ b/radiant/surfacedialog.cpp @@ -441,6 +441,16 @@ void SurfaceInspector_FitTexture(){ Select_FitTexture( getSurfaceInspector().m_fitHorizontal, getSurfaceInspector().m_fitVertical ); } +void SurfaceInspector_FitTextureW(){ + UndoableCommand undo( "textureAutoFitW" ); + Select_FitTextureW( getSurfaceInspector().m_fitHorizontal, getSurfaceInspector().m_fitVertical ); +} + +void SurfaceInspector_FitTextureH(){ + UndoableCommand undo( "textureAutoFitH" ); + Select_FitTextureH( getSurfaceInspector().m_fitHorizontal, getSurfaceInspector().m_fitVertical ); +} + static void OnBtnPatchdetails( GtkWidget *widget, gpointer data ){ Scene_PatchCapTexture_Selected( GlobalSceneGraph() ); } @@ -495,6 +505,18 @@ static void OnBtnFaceFit( GtkWidget *widget, gpointer data ){ SurfaceInspector_FitTexture(); } +static void OnBtnFaceFitW( GtkWidget *widget, gpointer data ){ + getSurfaceInspector().exportData(); + SurfaceInspector_FitTextureW(); +} + +static void OnBtnFaceFitH( GtkWidget *widget, gpointer data ){ + getSurfaceInspector().exportData(); + SurfaceInspector_FitTextureH(); +} + + + typedef const char* FlagName; const FlagName surfaceflagNamesDefault[32] = { @@ -853,18 +875,24 @@ GtkWindow* SurfaceInspector::BuildDialog(){ (GtkAttachOptions) ( 0 ), 0, 0 ); } { - GtkWidget* label = gtk_label_new( "Width" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 2, 3, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), + GtkWidget* button = gtk_button_new_with_label( "Width" ); + gtk_widget_show( button ); + gtk_table_attach( GTK_TABLE( table ), button, 2, 3, 0, 1, + (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); + g_signal_connect( G_OBJECT( button ), "clicked", + G_CALLBACK( OnBtnFaceFitW ), 0 ); + gtk_widget_set_usize( button, 60, -2 ); } { - GtkWidget* label = gtk_label_new( "Height" ); - gtk_widget_show( label ); - gtk_table_attach( GTK_TABLE( table ), label, 3, 4, 0, 1, - (GtkAttachOptions) ( GTK_FILL ), + GtkWidget* button = gtk_button_new_with_label( "Height" ); + gtk_widget_show( button ); + gtk_table_attach( GTK_TABLE( table ), button, 3, 4, 0, 1, + (GtkAttachOptions) ( GTK_EXPAND | GTK_FILL ), (GtkAttachOptions) ( 0 ), 0, 0 ); + g_signal_connect( G_OBJECT( button ), "clicked", + G_CALLBACK( OnBtnFaceFitH ), 0 ); + gtk_widget_set_usize( button, 60, -2 ); } { GtkWidget* button = gtk_button_new_with_label( "Axial" ); diff --git a/tools/quake3/q3map2/bsp.c b/tools/quake3/q3map2/bsp.c index da737460..a65b27f5 100644 --- a/tools/quake3/q3map2/bsp.c +++ b/tools/quake3/q3map2/bsp.c @@ -196,7 +196,7 @@ static void SetCloneModelNumbers( void ){ Sys_Printf( "WARNING: Cloned entity %s referenced entity without model\n", value2 ); continue; } - models = atoi( &value2[ 1 ] ); + models = atoi( &value3[ 1 ] ); /* add the model key */ sprintf( modelValue, "*%d", models ); @@ -981,6 +981,10 @@ int BSPMain( int argc, char **argv ){ else if ( !strcmp( argv[ i ], "-bsp" ) ) { Sys_Printf( "-bsp argument unnecessary\n" ); } + else if ( !strcmp( argv[ i ], "-noob" ) ) { + Sys_Printf( "No oBs!\n" ); + noob = qtrue; + } else { Sys_Printf( "WARNING: Unknown option \"%s\"\n", argv[ i ] ); diff --git a/tools/quake3/q3map2/bspfile_abstract.c b/tools/quake3/q3map2/bspfile_abstract.c index 1dab66db..c5df215e 100644 --- a/tools/quake3/q3map2/bspfile_abstract.c +++ b/tools/quake3/q3map2/bspfile_abstract.c @@ -169,7 +169,7 @@ void SwapBlock( int *block, int size ){ void SwapBSPFile( void ){ int i, j; - + shaderInfo_t *si; /* models */ SwapBlock( (int*) bspModels, numBSPModels * sizeof( bspModels[ 0 ] ) ); @@ -177,6 +177,11 @@ void SwapBSPFile( void ){ /* shaders (don't swap the name) */ for ( i = 0; i < numBSPShaders ; i++ ) { + si = ShaderInfoForShader( bspShaders[ i ].shader ); + if ( si->remapShader && si->remapShader[ 0 ] ) { + strcpy( bspShaders[ i ].shader, si->remapShader ); + } + bspShaders[ i ].contentFlags = LittleLong( bspShaders[ i ].contentFlags ); bspShaders[ i ].surfaceFlags = LittleLong( bspShaders[ i ].surfaceFlags ); } @@ -592,6 +597,10 @@ void InjectCommandLine( char **argv, int beginArgs, int endArgs ){ char *sentinel = newCommandLine + sizeof( newCommandLine ) - 1; int i; +if (nocmdline) +{ + return; +} previousCommandLine = ValueForKey( &entities[0], "_q3map2_cmdline" ); if ( previousCommandLine && *previousCommandLine ) { inpos = previousCommandLine; diff --git a/tools/quake3/q3map2/game_quake3.h b/tools/quake3/q3map2/game_quake3.h index 66b40289..d4069556 100644 --- a/tools/quake3/q3map2/game_quake3.h +++ b/tools/quake3/q3map2/game_quake3.h @@ -86,6 +86,7 @@ #define Q_SURF_ALPHASHADOW 0x10000 /* do per-pixel light shadow casting in q3map */ #define Q_SURF_NODLIGHT 0x20000 /* don't dlight even if solid (solid lava, skies) */ #define Q_SURF_DUST 0x40000 /* leave a dust trail when walking on this surface */ +#define Q_SURF_NOOB 0x80000 /* no overbounces on this surface */ /* ydnar flags */ #define Q_SURF_VERTEXLIT ( Q_SURF_POINTLIGHT | Q_SURF_NOLIGHTMAP ) @@ -197,6 +198,9 @@ { "nosteps", 0, 0, Q_SURF_NOSTEPS, 0, 0, 0 }, { "nodlight", 0, 0, Q_SURF_NODLIGHT, 0, 0, 0 }, { "dust", 0, 0, Q_SURF_DUST, 0, 0, 0 }, + { "noob", 0, 0, Q_SURF_NOOB, 0, 0, 0 }, + { "ob", 0, 0, 0, 0, C_OB, 0 }, + /* null */ { NULL, 0, 0, 0, 0, 0, 0 } diff --git a/tools/quake3/q3map2/light.c b/tools/quake3/q3map2/light.c index a0965979..f4c81889 100644 --- a/tools/quake3/q3map2/light.c +++ b/tools/quake3/q3map2/light.c @@ -2248,6 +2248,18 @@ int LightMain( int argc, char **argv ){ i++; } + else if ( !strcmp( argv[ i ], "-vertexscale" ) ) { + f = atof( argv[ i + 1 ] ); + vertexglobalscale *= f; + Sys_Printf( "Vertexlight scaled by %f to %f\n", f, vertexglobalscale ); + i++; + } + + else if ( !strcmp( argv[ i ], "-nolm" ) ) { + nolm = qtrue; + Sys_Printf( "No lightmaps yo\n" ); + } + else if ( !strcmp( argv[ i ], "-bouncescale" ) ) { f = atof( argv[ i + 1 ] ); bounceScale *= f; @@ -2744,8 +2756,15 @@ int LightMain( int argc, char **argv ){ Sys_Printf( "Lightmaps sample scale set to %d\n", sampleScale ); } else if ( !strcmp( argv[ i ], "-novertex" ) ) { - noVertexLighting = qtrue; - Sys_Printf( "Disabling vertex lighting\n" ); + noVertexLighting = 1; + if ( ( atof( argv[ i + 1 ] ) != 0 ) && ( atof( argv[ i + 1 ] )) < 1 ) { + noVertexLighting = ( atof( argv[ i + 1 ] ) ); + i++; + Sys_Printf( "Setting vertex lighting globally to %d\n", noVertexLighting ); + } + else{ + Sys_Printf( "Disabling vertex lighting\n" ); + } } else if ( !strcmp( argv[ i ], "-nogrid" ) ) { noGridLighting = qtrue; @@ -2772,9 +2791,11 @@ int LightMain( int argc, char **argv ){ lightAngleHL = ( atoi( argv[ i + 1 ] ) != 0 ); if ( lightAngleHL ) { Sys_Printf( "Enabling half lambert light angle attenuation\n" ); + i++; } else{ Sys_Printf( "Disabling half lambert light angle attenuation\n" ); + i++; } } } diff --git a/tools/quake3/q3map2/light_ydnar.c b/tools/quake3/q3map2/light_ydnar.c index 91f5e047..df53d7ed 100644 --- a/tools/quake3/q3map2/light_ydnar.c +++ b/tools/quake3/q3map2/light_ydnar.c @@ -2222,7 +2222,7 @@ void IlluminateRawLightmap( int rawLightmapNum ){ } /* allocate sampling flags storage */ - if ( ( lightSamples > 1 || lightRandomSamples ) && luxelFilterRadius == 0 ) { + if ( lightSamples > 1 || lightRandomSamples ) { size = lm->sw * lm->sh * SUPER_LUXEL_SIZE * sizeof( unsigned char ); if ( lm->superFlags == NULL ) { lm->superFlags = safe_malloc( size ); @@ -2276,7 +2276,7 @@ void IlluminateRawLightmap( int rawLightmapNum ){ } /* check for evilness */ - if ( trace.forceSubsampling > 1.0f && ( lightSamples > 1 || lightRandomSamples ) && luxelFilterRadius == 0 ) { + if ( trace.forceSubsampling > 1.0f && ( lightSamples > 1 || lightRandomSamples ) ) { totalLighted++; *flag |= FLAG_FORCE_SUBSAMPLING; /* force */ } @@ -2295,7 +2295,7 @@ void IlluminateRawLightmap( int rawLightmapNum ){ /* secondary pass, adaptive supersampling (fixme: use a contrast function to determine if subsampling is necessary) */ /* 2003-09-27: changed it so filtering disamples supersampling, as it would waste time */ - if ( ( lightSamples > 1 || lightRandomSamples ) && luxelFilterRadius == 0 ) { + if ( lightSamples > 1 || lightRandomSamples ) { /* walk luxels */ for ( y = 0; y < ( lm->sh - 1 ); y++ ) { @@ -2858,6 +2858,14 @@ void IlluminateVertexes( int num ){ radVertLuxel[ 2 ] = ( verts[ i ].normal[ 2 ] + 1.0f ) * 127.5f; } + else if ( info->si->noVertexLight ) { + VectorSet( radVertLuxel, 127.5f, 127.5f, 127.5f ); + } + + else if ( noVertexLighting > 0 ) { + VectorSet( radVertLuxel, 127.5f * noVertexLighting, 127.5f * noVertexLighting, 127.5f * noVertexLighting ); + } + /* illuminate the vertex */ else { @@ -3107,6 +3115,14 @@ void IlluminateVertexes( int num ){ VectorCopy( debugColors[ num % 12 ], radVertLuxel ); } + else if ( info->si->noVertexLight ) { + VectorSet( radVertLuxel, 127.5f, 127.5f, 127.5f ); + } + + else if ( noVertexLighting > 0 ) { + VectorSet( radVertLuxel, 127.5f * noVertexLighting, 127.5f * noVertexLighting, 127.5f * noVertexLighting ); + } + /* divine color from the superluxels */ else { diff --git a/tools/quake3/q3map2/lightmaps_ydnar.c b/tools/quake3/q3map2/lightmaps_ydnar.c index 3db1a7f0..32c3ce50 100644 --- a/tools/quake3/q3map2/lightmaps_ydnar.c +++ b/tools/quake3/q3map2/lightmaps_ydnar.c @@ -1092,7 +1092,8 @@ void SetupSurfaceLightmaps( void ){ /* determine if surface requires a lightmap */ if ( ds->surfaceType == MST_TRIANGLE_SOUP || ds->surfaceType == MST_FOLIAGE || - ( info->si->compileFlags & C_VERTEXLIT ) ) { + ( info->si->compileFlags & C_VERTEXLIT ) || + nolm == qtrue ) { numSurfsVertexLit++; } else diff --git a/tools/quake3/q3map2/main.c b/tools/quake3/q3map2/main.c index 76591a2a..fe7eee41 100644 --- a/tools/quake3/q3map2/main.c +++ b/tools/quake3/q3map2/main.c @@ -1291,13 +1291,13 @@ int ScaleBSPMain( int argc, char **argv ){ GetVectorForKey( &entities[ i ], "origin", vec ); if ( ( vec[ 0 ] || vec[ 1 ] || vec[ 2 ] ) ) { if ( !strncmp( ValueForKey( &entities[i], "classname" ), "info_player_", 12 ) ) { - vec[2] += spawn_ref; +// vec[2] += spawn_ref; } vec[0] *= scale[0]; vec[1] *= scale[1]; vec[2] *= scale[2]; if ( !strncmp( ValueForKey( &entities[i], "classname" ), "info_player_", 12 ) ) { - vec[2] -= spawn_ref; + vec[2] += spawn_ref; } sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); SetKeyValue( &entities[ i ], "origin", str ); @@ -1469,6 +1469,265 @@ int ScaleBSPMain( int argc, char **argv ){ } +/* + ShiftBSPMain() + shifts a map: works correctly only with axial faces, placed in positive half of axis + for testing physics with huge coordinates + */ + +int ShiftBSPMain( int argc, char **argv ){ + int i, j; + float f, a; + vec3_t scale; + vec3_t vec; + char str[ 1024 ]; + int uniform, axis; + qboolean texscale; + float *old_xyzst = NULL; + float spawn_ref = 0; + + + /* arg checking */ + if ( argc < 3 ) { + Sys_Printf( "Usage: q3map [-v] -shift [-tex] [-spawn_ref ] \n" ); + return 0; + } + + texscale = qfalse; + for ( i = 1; i < argc - 2; ++i ) + { + if ( !strcmp( argv[i], "-tex" ) ) { + texscale = qtrue; + } + else if ( !strcmp( argv[i], "-spawn_ref" ) ) { + spawn_ref = atof( argv[i + 1] ); + ++i; + } + else{ + break; + } + } + + /* get scale */ + // if(argc-2 >= i) // always true + scale[2] = scale[1] = scale[0] = atof( argv[ argc - 2 ] ); + if ( argc - 3 >= i ) { + scale[1] = scale[0] = atof( argv[ argc - 3 ] ); + } + if ( argc - 4 >= i ) { + scale[0] = atof( argv[ argc - 4 ] ); + } + + uniform = ( ( scale[0] == scale[1] ) && ( scale[1] == scale[2] ) ); + + + /* do some path mangling */ + strcpy( source, ExpandArg( argv[ argc - 1 ] ) ); + StripExtension( source ); + DefaultExtension( source, ".bsp" ); + + /* load the bsp */ + Sys_Printf( "Loading %s\n", source ); + LoadBSPFile( source ); + ParseEntities(); + + /* note it */ + Sys_Printf( "--- ShiftBSP ---\n" ); + Sys_FPrintf( SYS_VRB, "%9d entities\n", numEntities ); + + /* scale entity keys */ + for ( i = 0; i < numBSPEntities && i < numEntities; i++ ) + { + /* scale origin */ + GetVectorForKey( &entities[ i ], "origin", vec ); + if ( ( vec[ 0 ] || vec[ 1 ] || vec[ 2 ] ) ) { + if ( !strncmp( ValueForKey( &entities[i], "classname" ), "info_player_", 12 ) ) { + vec[2] += spawn_ref; + } + vec[0] += scale[0]; + vec[1] += scale[1]; + vec[2] += scale[2]; + if ( !strncmp( ValueForKey( &entities[i], "classname" ), "info_player_", 12 ) ) { + vec[2] -= spawn_ref; + } + sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); + SetKeyValue( &entities[ i ], "origin", str ); + } + + } + + /* scale models */ + for ( i = 0; i < numBSPModels; i++ ) + { + bspModels[ i ].mins[0] += scale[0]; + bspModels[ i ].mins[1] += scale[1]; + bspModels[ i ].mins[2] += scale[2]; + bspModels[ i ].maxs[0] += scale[0]; + bspModels[ i ].maxs[1] += scale[1]; + bspModels[ i ].maxs[2] += scale[2]; + } + + /* scale nodes */ + for ( i = 0; i < numBSPNodes; i++ ) + { + bspNodes[ i ].mins[0] += scale[0]; + bspNodes[ i ].mins[1] += scale[1]; + bspNodes[ i ].mins[2] += scale[2]; + bspNodes[ i ].maxs[0] += scale[0]; + bspNodes[ i ].maxs[1] += scale[1]; + bspNodes[ i ].maxs[2] += scale[2]; + } + + /* scale leafs */ + for ( i = 0; i < numBSPLeafs; i++ ) + { + bspLeafs[ i ].mins[0] += scale[0]; + bspLeafs[ i ].mins[1] += scale[1]; + bspLeafs[ i ].mins[2] += scale[2]; + bspLeafs[ i ].maxs[0] += scale[0]; + bspLeafs[ i ].maxs[1] += scale[1]; + bspLeafs[ i ].maxs[2] += scale[2]; + } +/* + if ( texscale ) { + Sys_Printf( "Using texture unlocking (and probably breaking texture alignment a lot)\n" ); + old_xyzst = safe_malloc( sizeof( *old_xyzst ) * numBSPDrawVerts * 5 ); + for ( i = 0; i < numBSPDrawVerts; i++ ) + { + old_xyzst[5 * i + 0] = bspDrawVerts[i].xyz[0]; + old_xyzst[5 * i + 1] = bspDrawVerts[i].xyz[1]; + old_xyzst[5 * i + 2] = bspDrawVerts[i].xyz[2]; + old_xyzst[5 * i + 3] = bspDrawVerts[i].st[0]; + old_xyzst[5 * i + 4] = bspDrawVerts[i].st[1]; + } + } +*/ + /* scale drawverts */ + for ( i = 0; i < numBSPDrawVerts; i++ ) + { + bspDrawVerts[i].xyz[0] += scale[0]; + bspDrawVerts[i].xyz[1] += scale[1]; + bspDrawVerts[i].xyz[2] += scale[2]; +// bspDrawVerts[i].normal[0] /= scale[0]; +// bspDrawVerts[i].normal[1] /= scale[1]; +// bspDrawVerts[i].normal[2] /= scale[2]; +// VectorNormalize( bspDrawVerts[i].normal, bspDrawVerts[i].normal ); + } +/* + if ( texscale ) { + for ( i = 0; i < numBSPDrawSurfaces; i++ ) + { + switch ( bspDrawSurfaces[i].surfaceType ) + { + case SURFACE_FACE: + case SURFACE_META: + if ( bspDrawSurfaces[i].numIndexes % 3 ) { + Error( "Not a triangulation!" ); + } + for ( j = bspDrawSurfaces[i].firstIndex; j < bspDrawSurfaces[i].firstIndex + bspDrawSurfaces[i].numIndexes; j += 3 ) + { + int ia = bspDrawIndexes[j] + bspDrawSurfaces[i].firstVert, ib = bspDrawIndexes[j + 1] + bspDrawSurfaces[i].firstVert, ic = bspDrawIndexes[j + 2] + bspDrawSurfaces[i].firstVert; + bspDrawVert_t *a = &bspDrawVerts[ia], *b = &bspDrawVerts[ib], *c = &bspDrawVerts[ic]; + float *oa = &old_xyzst[ia * 5], *ob = &old_xyzst[ib * 5], *oc = &old_xyzst[ic * 5]; + // extrapolate: + // a->xyz -> oa + // b->xyz -> ob + // c->xyz -> oc + ExtrapolateTexcoords( + &oa[0], &oa[3], + &ob[0], &ob[3], + &oc[0], &oc[3], + a->xyz, a->st, + b->xyz, b->st, + c->xyz, c->st ); + } + break; + } + } + } +*/ + /* scale planes */ + + for ( i = 0; i < numBSPPlanes; i++ ) + { + if ( bspPlanes[ i ].dist > 0 ){ + if ( bspPlanes[ i ].normal[0] ){ + bspPlanes[ i ].dist += scale[0]; + continue; + } + else if ( bspPlanes[ i ].normal[1] ){ + bspPlanes[ i ].dist += scale[1]; + continue; + } + else if ( bspPlanes[ i ].normal[2] ){ + bspPlanes[ i ].dist += scale[2]; + continue; + } + } + else{ + if ( bspPlanes[ i ].normal[0] ){ + bspPlanes[ i ].dist -= scale[0]; + continue; + } + else if ( bspPlanes[ i ].normal[1] ){ + bspPlanes[ i ].dist -= scale[1]; + continue; + } + else if ( bspPlanes[ i ].normal[2] ){ + bspPlanes[ i ].dist -= scale[2]; + continue; + } + } + } + + +/* if ( uniform ) { + for ( i = 0; i < numBSPPlanes; i++ ) + { + bspPlanes[ i ].dist += scale[0]; + } + } + else + { + for ( i = 0; i < numBSPPlanes; i++ ) + { +// bspPlanes[ i ].normal[0] /= scale[0]; +// bspPlanes[ i ].normal[1] /= scale[1]; +// bspPlanes[ i ].normal[2] /= scale[2]; + f = 1 / VectorLength( bspPlanes[i].normal ); + VectorScale( bspPlanes[i].normal, f, bspPlanes[i].normal ); + bspPlanes[ i ].dist *= f; + } + }*/ + + /* scale gridsize */ + /* + GetVectorForKey( &entities[ 0 ], "gridsize", vec ); + if ( ( vec[ 0 ] + vec[ 1 ] + vec[ 2 ] ) == 0.0f ) { + VectorCopy( gridSize, vec ); + } + vec[0] *= scale[0]; + vec[1] *= scale[1]; + vec[2] *= scale[2]; + sprintf( str, "%f %f %f", vec[ 0 ], vec[ 1 ], vec[ 2 ] ); + SetKeyValue( &entities[ 0 ], "gridsize", str ); +*/ + /* inject command line parameters */ + InjectCommandLine( argv, 0, argc - 1 ); + + /* write the bsp */ + UnparseEntities(); + StripExtension( source ); + DefaultExtension( source, "_sh.bsp" ); + Sys_Printf( "Writing %s\n", source ); + WriteBSPFile( source ); + + /* return to sender */ + return 0; +} + + + /* PseudoCompileBSP() a stripped down ProcessModels @@ -1771,6 +2030,13 @@ int main( int argc, char **argv ){ numthreads = atoi( argv[ i ] ); argv[ i ] = NULL; } + else if( !strcmp( argv[ i ], "-nocmdline" ) ) + { + Sys_Printf( "noCmdLine\n" ); + nocmdline = qtrue; + argv[ i ] = NULL; + } + } /* init model library */ @@ -1859,6 +2125,11 @@ int main( int argc, char **argv ){ r = ScaleBSPMain( argc - 1, argv + 1 ); } + /* bsp shifting */ + else if ( !strcmp( argv[ 1 ], "-shift" ) ) { + r = ShiftBSPMain( argc - 1, argv + 1 ); + } + /* ydnar: bsp conversion */ else if ( !strcmp( argv[ 1 ], "-convert" ) ) { r = ConvertBSPMain( argc - 1, argv + 1 ); diff --git a/tools/quake3/q3map2/map.c b/tools/quake3/q3map2/map.c index d786fc54..e9bc3921 100644 --- a/tools/quake3/q3map2/map.c +++ b/tools/quake3/q3map2/map.c @@ -1769,6 +1769,9 @@ static qboolean ParseMapEntity( qboolean onlyLights, qboolean noCollapseGroups ) else if ( strcmp( "", ValueForKey( mapEnt, "_sn" ) ) ) { shadeAngle = FloatForKey( mapEnt, "_sn" ); } + else if ( strcmp( "", ValueForKey( mapEnt, "_sa" ) ) ) { + shadeAngle = FloatForKey( mapEnt, "_sa" ); + } else if ( strcmp( "", ValueForKey( mapEnt, "_smooth" ) ) ) { shadeAngle = FloatForKey( mapEnt, "_smooth" ); } @@ -1789,6 +1792,9 @@ static qboolean ParseMapEntity( qboolean onlyLights, qboolean noCollapseGroups ) else if ( strcmp( "", ValueForKey( mapEnt, "_samplesize" ) ) ) { lightmapSampleSize = IntForKey( mapEnt, "_samplesize" ); } + else if ( strcmp( "", ValueForKey( mapEnt, "_ss" ) ) ) { + lightmapSampleSize = IntForKey( mapEnt, "_ss" ); + } if ( lightmapSampleSize < 0 ) { lightmapSampleSize = 0; diff --git a/tools/quake3/q3map2/model.c b/tools/quake3/q3map2/model.c index 94a80487..5798918e 100644 --- a/tools/quake3/q3map2/model.c +++ b/tools/quake3/q3map2/model.c @@ -418,7 +418,15 @@ void InsertModel( const char *name, int skin, int frame, m4x4_t transform, remap if ( ( si != NULL && si->forceMeta ) || ( spawnFlags & 4 ) ) { /* 3rd bit */ ds->type = SURFACE_FORCED_META; } - +/* else + { + //fix not requested lightmapping of models :E + // else force vertexlit + // ApplySurfaceParm( "pointlight", &si->contentFlags, &si->surfaceFlags, &si->compileFlags ); + // si->compileFlags |= C_VERTEXLIT; + //ds->type == SURFACE_TRIANGLES; + } +*/ /* fix the surface's normals (jal: conditioned by shader info) */ if ( !( spawnFlags & 64 ) && ( shadeAngle == 0.0f || ds->type != SURFACE_FORCED_META ) ) { PicoFixSurfaceNormals( surface ); @@ -875,6 +883,9 @@ void AddTriangleModels( entity_t *e ){ else if ( strcmp( "", ValueForKey( e2, "_samplesize" ) ) ) { lightmapSampleSize = IntForKey( e2, "_samplesize" ); } + else if ( strcmp( "", ValueForKey( e2, "_ss" ) ) ) { + lightmapSampleSize = IntForKey( e2, "_ss" ); + } if ( lightmapSampleSize < 0 ) { lightmapSampleSize = 0; @@ -917,6 +928,9 @@ void AddTriangleModels( entity_t *e ){ else if ( strcmp( "", ValueForKey( e2, "_sn" ) ) ) { shadeAngle = FloatForKey( e2, "_sn" ); } + else if ( strcmp( "", ValueForKey( e2, "_sa" ) ) ) { + shadeAngle = FloatForKey( e2, "_sa" ); + } else if ( strcmp( "", ValueForKey( e2, "_smooth" ) ) ) { shadeAngle = FloatForKey( e2, "_smooth" ); } diff --git a/tools/quake3/q3map2/q3map2.h b/tools/quake3/q3map2/q3map2.h index 705f3517..bd7c030e 100644 --- a/tools/quake3/q3map2/q3map2.h +++ b/tools/quake3/q3map2/q3map2.h @@ -176,6 +176,7 @@ #define C_ANTIPORTAL 0x00004000 /* like hint, but doesn't generate portals */ #define C_SKIP 0x00008000 /* like hint, but skips this face (doesn't split bsp) */ #define C_NOMARKS 0x00010000 /* no decals */ +#define C_OB 0x00020000 /* skip -noob for this */ #define C_DETAIL 0x08000000 /* THIS MUST BE THE SAME AS IN RADIANT! */ @@ -316,7 +317,7 @@ /* ok to increase these at the expense of more memory */ #define MAX_MAP_AREAS 0x100 /* MAX_MAP_AREA_BYTES in q_shared must match! */ -#define MAX_MAP_FOGS 30 //& 0x100 /* RBSP (32 - world fog - goggles) */ +#define MAX_MAP_FOGS 0x100 //& 0x100 /* RBSP (32 - world fog - goggles) */ #define MAX_MAP_LEAFS 0x20000 #define MAX_MAP_PORTALS 0x20000 #define MAX_MAP_LIGHTING 0x800000 @@ -324,7 +325,7 @@ #define MAX_MAP_VISCLUSTERS 0x4000 // <= MAX_MAP_LEAFS #define MAX_MAP_VISIBILITY ( VIS_HEADER_SIZE + MAX_MAP_VISCLUSTERS * ( ( ( MAX_MAP_VISCLUSTERS + 63 ) & ~63 ) >> 3 ) ) -#define MAX_MAP_DRAW_SURFS 0x20000 +#define MAX_MAP_DRAW_SURFS 0x20000 #define MAX_MAP_ADVERTISEMENTS 30 @@ -1517,6 +1518,7 @@ char *Q_strcat( char *dst, size_t dlen, const char *src ) char *Q_strncat( char *dst, size_t dlen, const char *src, size_t slen ); int BSPInfo( int count, char **fileNames ); int ScaleBSPMain( int argc, char **argv ); +int ShiftBSPMain( int argc, char **argv ); int ConvertMain( int argc, char **argv ); @@ -1999,6 +2001,7 @@ Q_EXTERN float jitters[ MAX_JITTERS ]; /* commandline arguments */ +Q_EXTERN qboolean nocmdline Q_ASSIGN( qfalse ); Q_EXTERN qboolean verbose; Q_EXTERN qboolean verboseEntities Q_ASSIGN( qfalse ); Q_EXTERN qboolean force Q_ASSIGN( qfalse ); @@ -2043,6 +2046,7 @@ Q_EXTERN qboolean lightmapFill Q_ASSIGN( qfalse ); Q_EXTERN int metaAdequateScore Q_ASSIGN( -1 ); Q_EXTERN int metaGoodScore Q_ASSIGN( -1 ); Q_EXTERN float metaMaxBBoxDistance Q_ASSIGN( -1 ); +Q_EXTERN qboolean noob Q_ASSIGN( qfalse ); #if Q3MAP2_EXPERIMENTAL_SNAP_NORMAL_FIX // Increasing the normalEpsilon to compensate for new logic in SnapNormal(), where @@ -2172,6 +2176,7 @@ Q_EXTERN char inbase[ MAX_QPATH ]; Q_EXTERN char globalCelShader[ MAX_QPATH ]; Q_EXTERN float farPlaneDist; /* rr2do2, rf, mre, ydnar all contributed to this one... */ +Q_EXTERN int farPlaneDistMode; Q_EXTERN int numportals; Q_EXTERN int portalclusters; @@ -2217,7 +2222,8 @@ Q_EXTERN qboolean keepLights Q_ASSIGN( qfalse ); Q_EXTERN int sampleSize Q_ASSIGN( DEFAULT_LIGHTMAP_SAMPLE_SIZE ); Q_EXTERN int minSampleSize Q_ASSIGN( DEFAULT_LIGHTMAP_MIN_SAMPLE_SIZE ); -Q_EXTERN qboolean noVertexLighting Q_ASSIGN( qfalse ); +Q_EXTERN float noVertexLighting Q_ASSIGN( 0.0f ); +Q_EXTERN qboolean nolm Q_ASSIGN( qfalse ); Q_EXTERN qboolean noGridLighting Q_ASSIGN( qfalse ); Q_EXTERN qboolean noTrace Q_ASSIGN( qfalse ); @@ -2293,6 +2299,7 @@ Q_EXTERN float spotScale Q_ASSIGN( 7500.0f ); Q_EXTERN float areaScale Q_ASSIGN( 0.25f ); Q_EXTERN float skyScale Q_ASSIGN( 1.0f ); Q_EXTERN float bounceScale Q_ASSIGN( 0.25f ); +Q_EXTERN float vertexglobalscale Q_ASSIGN( 1.0f ); /* jal: alternative angle attenuation curve */ Q_EXTERN qboolean lightAngleHL Q_ASSIGN( qfalse ); diff --git a/tools/quake3/q3map2/shaders.c b/tools/quake3/q3map2/shaders.c index 75cab6b0..7127362a 100644 --- a/tools/quake3/q3map2/shaders.c +++ b/tools/quake3/q3map2/shaders.c @@ -660,7 +660,7 @@ static shaderInfo_t *AllocShaderInfo( void ){ si->patchShadows = qfalse; si->vertexShadows = qtrue; /* ydnar: changed default behavior */ si->forceSunlight = qfalse; - si->vertexScale = 1.0; + si->vertexScale = vertexglobalscale; si->notjunc = qfalse; /* ydnar: set texture coordinate transform matrix to identity */ @@ -727,6 +727,9 @@ void FinishShader( shaderInfo_t *si ){ } } } + if (noob && !(si->compileFlags & C_OB)){ + ApplySurfaceParm( "noob", &si->contentFlags, &si->surfaceFlags, &si->compileFlags ); + } /* set to finished */ si->finished = qtrue; @@ -1603,11 +1606,11 @@ static void ParseShaderFile( const char *filename ){ /* q3map_vertexScale (scale vertex lighting by this fraction) */ else if ( !Q_stricmp( token, "q3map_vertexScale" ) ) { GetTokenAppend( shaderText, qfalse ); - si->vertexScale = atof( token ); + si->vertexScale *= atof( token ); } /* q3map_noVertexLight */ - else if ( !Q_stricmp( token, "q3map_noVertexLight" ) ) { + else if ( !Q_stricmp( token, "q3map_noVertexLight" ) ) { si->noVertexLight = qtrue; } diff --git a/tools/quake3/q3map2/surface.c b/tools/quake3/q3map2/surface.c index 2aeda857..2bc185cd 100644 --- a/tools/quake3/q3map2/surface.c +++ b/tools/quake3/q3map2/surface.c @@ -598,7 +598,7 @@ void ClassifySurfaces( int numSurfs, mapDrawSurface_t *ds ){ ----------------------------------------------------------------- */ /* vertex lit surfaces don't need this information */ - if ( si->compileFlags & C_VERTEXLIT || ds->type == SURFACE_TRIANGLES ) { + if ( si->compileFlags & C_VERTEXLIT || ds->type == SURFACE_TRIANGLES || nolm == qtrue ) { VectorClear( ds->lightmapAxis ); //% VectorClear( ds->lightmapVecs[ 2 ] ); ds->sampleSize = 0; @@ -3648,10 +3648,10 @@ void FilterDrawsurfsIntoTree( entity_t *e, tree_t *tree ){ } /* ydnar: remap shader */ - if ( ds->shaderInfo->remapShader && ds->shaderInfo->remapShader[ 0 ] ) { +/* if ( ds->shaderInfo->remapShader && ds->shaderInfo->remapShader[ 0 ] ) { ds->shaderInfo = ShaderInfoForShader( ds->shaderInfo->remapShader ); } - +*/ /* ydnar: gs mods: handle the various types of surfaces */ switch ( ds->type ) { diff --git a/tools/quake3/q3map2/vis.c b/tools/quake3/q3map2/vis.c index b166c91f..fd3df83e 100644 --- a/tools/quake3/q3map2/vis.c +++ b/tools/quake3/q3map2/vis.c @@ -318,16 +318,25 @@ void CalcVis( void ){ } if ( value[ 0 ] != '\0' ) { farPlaneDist = atof( value ); - if ( farPlaneDist > 0.0f ) { + farPlaneDistMode = value[strlen(value) - 1 ]; + if ( farPlaneDist != 0.0f ) { Sys_Printf( "farplane distance = %.1f\n", farPlaneDist ); } - else{ - farPlaneDist = 0.0f; + if ( farPlaneDist != 0.0f && farPlaneDistMode == 'o' ) { + Sys_Printf( "farplane Origin2Origin mode on\n" ); } + if ( farPlaneDist != 0.0f && farPlaneDistMode == 'r' ) { + Sys_Printf( "farplane Radius+Radius mode on\n" ); + } + if ( farPlaneDist != 0.0f && farPlaneDistMode == 'e' ) { + Sys_Printf( "farplane Exact distance mode on\n" ); + } + } + Sys_Printf( "\n--- BasePortalVis (%d) ---\n", numportals * 2 ); RunThreadsOnIndividual( numportals * 2, qtrue, BasePortalVis ); diff --git a/tools/quake3/q3map2/visflow.c b/tools/quake3/q3map2/visflow.c index 5a7ffd92..0247691f 100644 --- a/tools/quake3/q3map2/visflow.c +++ b/tools/quake3/q3map2/visflow.c @@ -1614,8 +1614,28 @@ void BasePortalVis( int portalnum ){ } */ + if( !p->sky && !tp->sky && farPlaneDist != 0.0f && farPlaneDistMode == 'o' ) + { + VectorSubtract( p->origin, tp->origin, dir ); + if( VectorLength( dir ) > farPlaneDist ) + continue; + } + + if( !p->sky && !tp->sky && farPlaneDist != 0.0f && farPlaneDistMode == 'e' ) + { + VectorSubtract( p->origin, tp->origin, dir ); + if( VectorLength( dir ) + p->radius + tp->radius > 2.0f * farPlaneDist ) + continue; + } + + if( !p->sky && !tp->sky && farPlaneDist != 0.0f && farPlaneDistMode == 'r' ) + { + if( p->radius + tp->radius > farPlaneDist ) + continue; + } + /* ydnar: this is known-to-be-working farplane code */ - if ( !p->sky && !tp->sky && farPlaneDist > 0.0f ) { + if ( !p->sky && !tp->sky && farPlaneDist != 0.0f ) { VectorSubtract( p->origin, tp->origin, dir ); if ( VectorLength( dir ) - p->radius - tp->radius > farPlaneDist ) { continue; -- 2.39.2