2018-01-02 04:52:54 +08:00
using System ;
2017-09-21 18:33:05 +08:00
using System.Collections.Generic ;
using System.Text ;
using System.Threading.Tasks ;
using System.Windows.Forms ;
using System.Threading ;
using System.Diagnostics ;
2023-09-04 18:48:50 +08:00
using System.Linq ;
2017-09-21 18:33:05 +08:00
using SharpDX ;
using SharpDX.XInput ;
2018-01-02 04:52:54 +08:00
using Device = SharpDX . Direct3D11 . Device ;
using DeviceContext = SharpDX . Direct3D11 . DeviceContext ;
using CodeWalker.World ;
using CodeWalker.Project ;
using CodeWalker.Rendering ;
using CodeWalker.GameFiles ;
using CodeWalker.Properties ;
2020-02-25 19:26:34 +08:00
using CodeWalker.Tools ;
2017-09-21 18:33:05 +08:00
namespace CodeWalker
{
public partial class WorldForm : Form , DXForm
{
public Form Form { get { return this ; } } //for DXForm/DXManager use
2018-12-05 13:23:34 +08:00
public Renderer Renderer = null ;
2018-01-02 04:52:54 +08:00
public object RenderSyncRoot { get { return Renderer . RenderSyncRoot ; } }
2017-09-21 18:33:05 +08:00
volatile bool formopen = false ;
volatile bool running = false ;
volatile bool pauserendering = false ;
volatile bool initialised = false ;
Stopwatch frametimer = new Stopwatch ( ) ;
Space space = new Space ( ) ;
2018-01-02 04:52:54 +08:00
Camera camera ;
Timecycle timecycle ;
Weather weather ;
Clouds clouds ;
2017-09-21 18:33:05 +08:00
Water water = new Water ( ) ;
Trains trains = new Trains ( ) ;
Scenarios scenarios = new Scenarios ( ) ;
PopZones popzones = new PopZones ( ) ;
2021-04-21 04:26:32 +08:00
Heightmaps heightmaps = new Heightmaps ( ) ;
Watermaps watermaps = new Watermaps ( ) ;
2017-12-22 04:26:04 +08:00
AudioZones audiozones = new AudioZones ( ) ;
2017-09-21 18:33:05 +08:00
2018-06-02 00:25:12 +08:00
public Space Space { get { return space ; } }
2017-09-21 18:33:05 +08:00
bool MouseLButtonDown = false ;
bool MouseRButtonDown = false ;
int MouseX ;
int MouseY ;
System . Drawing . Point MouseDownPoint ;
System . Drawing . Point MouseLastPoint ;
bool rendermaps = false ;
bool renderworld = false ;
int startupviewmode = 0 ; //0=world, 1=ymap, 2=model
2018-03-07 19:24:37 +08:00
string modelname = "dt1_tc_dufo_core" ; //"dt1_11_fount_decal";//"v_22_overlays";//
2017-09-21 18:33:05 +08:00
string [ ] ymaplist ;
2018-01-02 04:52:54 +08:00
2024-08-05 18:24:59 +08:00
Vector3 prevworldpos = FloatUtil . ParseVector3String ( Settings . Default . StartPosition ) ;
2017-09-21 18:33:05 +08:00
public GameFileCache GameFileCache { get { return gameFileCache ; } }
2018-02-24 21:59:00 +08:00
GameFileCache gameFileCache = GameFileCacheFactory . Create ( ) ;
2017-09-21 18:33:05 +08:00
WorldControlMode ControlMode = WorldControlMode . Free ;
object MouseControlSyncRoot = new object ( ) ;
int MouseControlX = 0 ;
int MouseControlY = 0 ;
int MouseControlWheel = 0 ;
MouseButtons MouseControlButtons = MouseButtons . None ;
MouseButtons MouseControlButtonsPrev = MouseButtons . None ;
2018-01-02 08:07:24 +08:00
bool MouseInvert = Settings . Default . MouseInvert ;
2017-09-21 18:33:05 +08:00
bool ControlFireToggle = false ;
2018-06-08 00:42:41 +08:00
int ControlBrushTimer = 0 ;
bool ControlBrushEnabled ;
2018-12-04 14:09:28 +08:00
//float ControlBrushRadius;
2018-06-08 00:42:41 +08:00
2017-09-21 18:33:05 +08:00
Entity camEntity = new Entity ( ) ;
PedEntity pedEntity = new PedEntity ( ) ;
2018-01-02 04:52:54 +08:00
2017-09-21 18:33:05 +08:00
bool iseditmode = false ;
List < MapIcon > Icons ;
MapIcon MarkerIcon = null ;
MapIcon LocatorIcon = null ;
MapMarker LocatorMarker = null ;
MapMarker GrabbedMarker = null ;
MapMarker SelectedMarker = null ;
MapMarker MousedMarker = null ;
List < MapMarker > Markers = new List < MapMarker > ( ) ;
List < MapMarker > SortedMarkers = new List < MapMarker > ( ) ;
List < MapMarker > MarkerBatch = new List < MapMarker > ( ) ;
bool RenderLocator = false ;
object markersyncroot = new object ( ) ;
object markersortedsyncroot = new object ( ) ;
2018-01-02 04:52:54 +08:00
2018-06-08 00:42:41 +08:00
2018-01-02 04:52:54 +08:00
2017-09-21 18:33:05 +08:00
bool rendercollisionmeshes = Settings . Default . ShowCollisionMeshes ;
List < BoundsStoreItem > collisionitems = new List < BoundsStoreItem > ( ) ;
2020-01-03 19:50:23 +08:00
List < YbnFile > collisionybns = new List < YbnFile > ( ) ;
2020-01-13 20:31:27 +08:00
Dictionary < YmapEntityDef , YbnFile > collisioninteriors = new Dictionary < YmapEntityDef , YbnFile > ( ) ;
2017-09-21 18:33:05 +08:00
int collisionmeshrange = Settings . Default . CollisionMeshRange ;
bool [ ] collisionmeshlayers = { true , true , true } ;
Dictionary < MetaHash , YmapFile > renderworldVisibleYmapDict = new Dictionary < MetaHash , YmapFile > ( ) ;
bool worldymaptimefilter = true ;
bool worldymapweatherfilter = true ;
bool renderpathbounds = true ;
bool renderpaths = false ;
List < YndFile > renderpathynds = new List < YndFile > ( ) ;
bool renderwaterquads = true ;
bool rendertraintracks = false ;
List < TrainTrack > rendertraintracklist = new List < TrainTrack > ( ) ;
bool rendernavmeshes = false ;
List < YnvFile > rendernavmeshynvs = new List < YnvFile > ( ) ;
bool renderscenariobounds = false ;
bool renderscenarios = false ;
List < YmtFile > renderscenariolist = new List < YmtFile > ( ) ;
2017-09-22 15:31:02 +08:00
bool renderpopzones = false ;
2021-04-21 04:26:32 +08:00
bool renderheightmaps = false ;
bool renderwatermaps = false ;
2017-09-21 18:33:05 +08:00
2017-12-22 04:26:04 +08:00
bool renderaudiozones = false ;
2017-12-24 19:49:04 +08:00
bool renderaudioouterbounds = true ;
2018-12-26 21:20:39 +08:00
List < RelFile > renderaudfilelist = new List < RelFile > ( ) ;
List < AudioPlacement > renderaudplacementslist = new List < AudioPlacement > ( ) ;
2017-09-21 18:33:05 +08:00
bool MapViewEnabled = false ;
int MapViewDragX = 0 ;
int MapViewDragY = 0 ;
bool MouseSelectEnabled = false ;
bool ShowSelectionBounds = true ;
bool SelectByGeometry = false ; //select by geometry needs more work
MapSelection CurMouseHit = new MapSelection ( ) ;
MapSelection LastMouseHit = new MapSelection ( ) ;
MapSelection PrevMouseHit = new MapSelection ( ) ;
bool MouseRayCollisionEnabled = true ;
2019-12-09 19:33:36 +08:00
bool MouseRayCollisionVisible = false ;
2017-09-21 18:33:05 +08:00
SpaceRayIntersectResult MouseRayCollision = new SpaceRayIntersectResult ( ) ;
string SelectionModeStr = "Entity" ;
MapSelectionMode SelectionMode = MapSelectionMode . Entity ;
MapSelection SelectedItem ;
2020-01-08 21:44:35 +08:00
MapSelection CopiedItem ;
2017-09-21 18:33:05 +08:00
WorldInfoForm InfoForm = null ;
2021-11-12 18:07:06 +08:00
public MapSelection CurrentMapSelection { get { return SelectedItem ; } }
2017-10-01 14:29:31 +08:00
2017-09-21 18:33:05 +08:00
TransformWidget Widget = new TransformWidget ( ) ;
TransformWidget GrabbedWidget = null ;
bool ShowWidget = true ;
2018-03-03 21:09:31 +08:00
ProjectForm ProjectForm = null ;
2017-09-21 18:33:05 +08:00
Stack < UndoStep > UndoSteps = new Stack < UndoStep > ( ) ;
Stack < UndoStep > RedoSteps = new Stack < UndoStep > ( ) ;
Vector3 UndoStartPosition ;
Quaternion UndoStartRotation ;
Vector3 UndoStartScale ;
2018-02-25 20:30:29 +08:00
WorldSnapMode SnapMode = WorldSnapMode . None ;
WorldSnapMode SnapModePrev = WorldSnapMode . Ground ; //also the default snap mode
float SnapGridSize = 1.0f ;
2017-09-21 18:33:05 +08:00
public bool EditEntityPivot { get ; set ; } = false ;
SettingsForm SettingsForm = null ;
WorldSearchForm SearchForm = null ;
2019-11-25 17:44:16 +08:00
CutsceneForm CutsceneForm = null ;
2018-01-02 04:52:54 +08:00
InputManager Input = new InputManager ( ) ;
2017-09-21 18:33:05 +08:00
bool toolspanelexpanded = false ;
int toolspanellastwidth ;
bool toolsPanelResizing = false ;
int toolsPanelResizeStartX = 0 ;
int toolsPanelResizeStartLeft = 0 ;
int toolsPanelResizeStartRight = 0 ;
bool initedOk = false ;
public WorldForm ( )
{
InitializeComponent ( ) ;
2018-01-02 04:52:54 +08:00
Renderer = new Renderer ( this , gameFileCache ) ;
camera = Renderer . camera ;
timecycle = Renderer . timecycle ;
weather = Renderer . weather ;
clouds = Renderer . clouds ;
2023-09-04 18:48:50 +08:00
CurMouseHit . WorldForm = this ;
LastMouseHit . WorldForm = this ;
PrevMouseHit . WorldForm = this ;
2018-01-02 04:52:54 +08:00
initedOk = Renderer . Init ( ) ;
2017-09-21 18:33:05 +08:00
}
private void Init ( )
{
//called from WorldForm_Load
if ( ! initedOk )
{
Close ( ) ;
return ;
}
MouseWheel + = WorldForm_MouseWheel ;
2018-02-21 16:27:01 +08:00
if ( ! GTAFolder . UpdateGTAFolder ( true ) )
2017-09-21 18:33:05 +08:00
{
Close ( ) ;
return ;
}
Widget . Position = new Vector3 ( 1.0f , 10.0f , 100.0f ) ;
Widget . Rotation = Quaternion . Identity ;
Widget . Scale = Vector3 . One ;
Widget . Visible = false ;
Widget . OnPositionChange + = Widget_OnPositionChange ;
Widget . OnRotationChange + = Widget_OnRotationChange ;
Widget . OnScaleChange + = Widget_OnScaleChange ;
ymaplist = YmapsTextBox . Text . Split ( new [ ] { "\r\n" } , StringSplitOptions . RemoveEmptyEntries ) ;
ViewModeComboBox . SelectedIndex = startupviewmode ;
BoundsStyleComboBox . SelectedIndex = 0 ; //LoadSettings will handle this
SelectionModeComboBox . SelectedIndex = 0 ; //Entity mode
ShowSelectedExtensionTab ( false ) ;
toolspanellastwidth = ToolsPanel . Width * 2 ; //default expanded size
Icons = new List < MapIcon > ( ) ;
AddIcon ( "Google Marker" , "icon_google_marker_64x64.png" , 64 , 64 , 11.0f , 40.0f , 1.0f ) ;
AddIcon ( "Glokon Marker" , "icon_glokon_normal_32x32.png" , 32 , 32 , 11.0f , 32.0f , 1.0f ) ;
AddIcon ( "Glokon Debug" , "icon_glokon_debug_32x32.png" , 32 , 32 , 11.5f , 32.0f , 1.0f ) ;
MarkerIcon = Icons [ 1 ] ;
LocatorIcon = Icons [ 2 ] ;
foreach ( MapIcon icon in Icons )
{
MarkerStyleComboBox . Items . Add ( icon ) ;
LocatorStyleComboBox . Items . Add ( icon ) ;
}
MarkerStyleComboBox . SelectedItem = MarkerIcon ; //LoadSettings will handle this
LocatorStyleComboBox . SelectedItem = LocatorIcon ;
LocatorMarker = new MapMarker ( ) ;
LocatorMarker . Icon = LocatorIcon ;
LocatorMarker . IsMovable = true ;
//AddDefaultMarkers(); //some POI to start with
2019-10-31 14:11:12 +08:00
ShaderParamNames [ ] texsamplers = RenderableGeometry . GetTextureSamplerList ( ) ;
2017-09-21 18:33:05 +08:00
foreach ( var texsampler in texsamplers )
{
TextureSamplerComboBox . Items . Add ( texsampler ) ;
}
//TextureSamplerComboBox.SelectedIndex = 0; //LoadSettings will handle this
//RenderModeComboBox.SelectedIndex = 0; //Default
WorldMaxLodComboBox . SelectedIndex = 0 ; //should this be a setting?
WeatherComboBox . SelectedIndex = 0 ; //show "<Loading...>" until weather types are loaded
CameraModeComboBox . SelectedIndex = 0 ; //"Perspective"
DlcLevelComboBox . SelectedIndex = 0 ; //show "<Loading...>" until DLC list is loaded
UpdateToolbarShortcutsText ( ) ;
2018-01-02 04:52:54 +08:00
Input . Init ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . Start ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
2017-09-21 18:33:05 +08:00
private MapIcon AddIcon ( string name , string filename , int texw , int texh , float centerx , float centery , float scale )
{
2024-07-11 08:51:17 +08:00
string filepath = PathUtil . GetFilePath ( "icons\\" + filename ) ;
2017-09-21 18:33:05 +08:00
try
{
MapIcon mi = new MapIcon ( name , filepath , texw , texh , centerx , centery , scale ) ;
Icons . Add ( mi ) ;
return mi ;
}
catch ( Exception ex )
{
MessageBox . Show ( "Could not load map icon " + filepath + " for " + name + "!\n\n" + ex . ToString ( ) ) ;
}
return null ;
}
public void InitScene ( Device device )
{
int width = ClientSize . Width ;
int height = ClientSize . Height ;
try
{
2018-01-02 04:52:54 +08:00
Renderer . DeviceCreated ( device , width , height ) ;
2017-09-21 18:33:05 +08:00
}
catch ( Exception ex )
{
MessageBox . Show ( "Error loading shaders!\n" + ex . ToString ( ) ) ;
return ;
}
if ( Icons ! = null )
{
foreach ( MapIcon icon in Icons )
{
icon . LoadTexture ( device , LogError ) ;
}
}
camera . FollowEntity = camEntity ;
2018-01-02 04:52:54 +08:00
camEntity . Position = ( startupviewmode ! = 2 ) ? prevworldpos : Vector3 . Zero ;
camEntity . Orientation = Quaternion . LookAtLH ( Vector3 . Zero , Vector3 . Up , Vector3 . ForwardLH ) ;
2017-09-21 18:33:05 +08:00
space . AddPersistentEntity ( pedEntity ) ;
LoadSettings ( ) ;
formopen = true ;
new Thread ( new ThreadStart ( ContentThread ) ) . Start ( ) ;
frametimer . Start ( ) ;
}
public void CleanupScene ( )
{
formopen = false ;
2018-01-02 04:52:54 +08:00
Renderer . DeviceDestroyed ( ) ;
2017-09-21 18:33:05 +08:00
if ( Icons ! = null )
{
foreach ( MapIcon icon in Icons )
{
icon . UnloadTexture ( ) ;
}
}
int count = 0 ;
while ( running & & ( count < 5000 ) ) //wait for the content thread to exit gracefully
{
Thread . Sleep ( 1 ) ;
count + + ;
}
}
public void BuffersResized ( int w , int h )
{
2018-01-02 04:52:54 +08:00
Renderer . BuffersResized ( w , h ) ;
2017-09-21 18:33:05 +08:00
}
public void RenderScene ( DeviceContext context )
{
float elapsed = ( float ) frametimer . Elapsed . TotalSeconds ;
frametimer . Restart ( ) ;
if ( pauserendering ) return ;
2019-12-10 21:31:56 +08:00
GameFileCache . BeginFrame ( ) ;
2018-01-02 04:52:54 +08:00
if ( ! Monitor . TryEnter ( Renderer . RenderSyncRoot , 50 ) )
2017-09-21 18:33:05 +08:00
{ return ; } //couldn't get a lock, try again next time
UpdateControlInputs ( elapsed ) ;
2018-01-02 04:52:54 +08:00
space . Update ( elapsed ) ;
2017-09-21 18:33:05 +08:00
2019-11-25 17:44:16 +08:00
if ( CutsceneForm ! = null )
{
CutsceneForm . UpdateAnimation ( elapsed ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . Update ( elapsed , MouseLastPoint . X , MouseLastPoint . Y ) ;
2017-09-21 18:33:05 +08:00
UpdateWidgets ( ) ;
BeginMouseHitTest ( ) ;
2018-01-02 04:52:54 +08:00
Renderer . BeginRender ( context ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderSkyAndClouds ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . SelectedDrawable = SelectedItem . Drawable ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( renderworld )
2017-09-21 18:33:05 +08:00
{
RenderWorld ( ) ;
2018-01-02 04:52:54 +08:00
}
else if ( rendermaps )
{
RenderYmaps ( ) ;
2017-09-21 18:33:05 +08:00
}
else
{
RenderSingleItem ( ) ;
}
2019-12-30 15:05:02 +08:00
UpdateMouseHits ( ) ;
2018-01-02 04:52:54 +08:00
2017-10-01 14:29:31 +08:00
RenderSelection ( ) ;
2019-12-31 21:00:04 +08:00
RenderMoused ( ) ;
2018-01-02 04:52:54 +08:00
Renderer . RenderQueued ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderBounds ( SelectionMode ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderSelectionGeometry ( SelectionMode ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderFinalPass ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
RenderMarkers ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
RenderWidgets ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . EndRender ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Monitor . Exit ( Renderer . RenderSyncRoot ) ;
2017-09-21 18:33:05 +08:00
UpdateMarkerSelectionPanelInvoke ( ) ;
}
2020-01-14 14:56:11 +08:00
public bool ConfirmQuit ( )
{
if ( ( ProjectForm ! = null ) & & ( ProjectForm . CurrentProjectFile ! = null ) )
{
if ( MessageBox . Show ( "Are you sure you want to quit CodeWalker?" , "Confirm quit" , MessageBoxButtons . YesNo ) ! = DialogResult . Yes )
{
return false ;
}
}
return true ;
}
2017-09-21 18:33:05 +08:00
private void UpdateTimeOfDayLabel ( )
{
int v = TimeOfDayTrackBar . Value ;
float fh = v / 60.0f ;
int ih = ( int ) fh ;
int im = v - ( ih * 60 ) ;
if ( ih = = 24 ) ih = 0 ;
TimeOfDayLabel . Text = string . Format ( "{0:00}:{1:00}" , ih , im ) ;
}
2018-01-02 04:52:54 +08:00
private void UpdateControlInputs ( float elapsed )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
if ( elapsed > 0.1f ) elapsed = 0.1f ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
var s = Settings . Default ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
float moveSpeed = 50.0f ;
2017-09-21 18:33:05 +08:00
2019-12-11 15:46:36 +08:00
Input . Update ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( Input . xbenable )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
if ( Input . ControllerButtonJustPressed ( GamepadButtonFlags . Start ) )
2017-09-21 18:33:05 +08:00
{
SetControlMode ( ControlMode = = WorldControlMode . Free ? WorldControlMode . Ped : WorldControlMode . Free ) ;
}
}
2018-06-08 00:42:41 +08:00
if ( ControlMode = = WorldControlMode . Free | | ControlBrushEnabled )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
if ( Input . ShiftPressed )
2017-12-22 08:25:19 +08:00
{
moveSpeed * = 5.0f ;
}
2018-01-02 04:52:54 +08:00
if ( Input . CtrlPressed )
2017-12-22 08:25:19 +08:00
{
moveSpeed * = 0.2f ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Vector3 movevec = Input . KeyboardMoveVec ( MapViewEnabled ) ;
2019-12-11 15:46:36 +08:00
if ( Input . xbenable )
{
movevec . X + = Input . xblx ;
if ( MapViewEnabled ) movevec . Y + = Input . xbly ;
else movevec . Z - = Input . xbly ;
moveSpeed * = ( 1.0f + ( Math . Min ( Math . Max ( Input . xblt , 0.0f ) , 1.0f ) * 15.0f ) ) ; //boost with left trigger
if ( Input . ControllerButtonPressed ( GamepadButtonFlags . A | GamepadButtonFlags . RightShoulder | GamepadButtonFlags . LeftShoulder ) )
{
moveSpeed * = 5.0f ;
}
}
2017-12-22 04:26:04 +08:00
if ( MapViewEnabled )
2017-09-21 18:33:05 +08:00
{
movevec * = elapsed * moveSpeed * Math . Min ( camera . OrthographicTargetSize * 0.01f , 50.0f ) ;
float mapviewscale = 1.0f / camera . Height ;
float fdx = MapViewDragX * mapviewscale ;
float fdy = MapViewDragY * mapviewscale ;
movevec . X - = fdx * camera . OrthographicSize ;
movevec . Y + = fdy * camera . OrthographicSize ;
}
else
{
//normal movement
movevec * = elapsed * moveSpeed * Math . Min ( camera . TargetDistance , 20.0f ) ;
}
Vector3 movewvec = camera . ViewInvQuaternion . Multiply ( movevec ) ;
camEntity . Position + = movewvec ;
MapViewDragX = 0 ;
MapViewDragY = 0 ;
2018-01-02 04:52:54 +08:00
if ( Input . xbenable )
2017-09-21 18:33:05 +08:00
{
2019-12-11 15:46:36 +08:00
camera . ControllerRotate ( Input . xbrx , Input . xbry , elapsed ) ;
2017-09-21 18:33:05 +08:00
float zoom = 0.0f ;
float zoomspd = s . XInputZoomSpeed ;
float zoomamt = zoomspd * elapsed ;
2018-01-02 04:52:54 +08:00
if ( Input . ControllerButtonPressed ( GamepadButtonFlags . DPadUp ) ) zoom + = zoomamt ;
if ( Input . ControllerButtonPressed ( GamepadButtonFlags . DPadDown ) ) zoom - = zoomamt ;
2019-12-11 15:46:36 +08:00
if ( MapViewEnabled ) zoom - = zoomamt * Input . xbry ;
2017-09-21 18:33:05 +08:00
camera . ControllerZoom ( zoom ) ;
2019-12-11 15:46:36 +08:00
bool fire = ( Input . xbtrigs . Y > 0 ) ;
if ( fire & & ! ControlFireToggle )
2017-09-21 18:33:05 +08:00
{
SpawnTestEntity ( true ) ;
}
2019-12-11 15:46:36 +08:00
ControlFireToggle = fire ;
2017-09-21 18:33:05 +08:00
}
}
else
{
//"play" mode
int mcx , mcy , mcw ;
MouseButtons mcb , mcbp ;
bool mlb = false , mrb = false ;
bool mlbjustpressed = false , mrbjustpressed = false ;
lock ( MouseControlSyncRoot )
{
mcx = MouseControlX ;
mcy = MouseControlY ;
mcw = MouseControlWheel ;
mcb = MouseControlButtons ;
mcbp = MouseControlButtonsPrev ;
mlb = ( ( mcb & MouseButtons . Left ) > 0 ) ;
mrb = ( ( mcb & MouseButtons . Right ) > 0 ) ;
mlbjustpressed = mlb & & ( ( mcbp & MouseButtons . Left ) = = 0 ) ;
mrbjustpressed = mrb & & ( ( mcbp & MouseButtons . Right ) = = 0 ) ;
MouseControlX = 0 ;
MouseControlY = 0 ;
MouseControlWheel = 0 ;
MouseControlButtonsPrev = MouseControlButtons ;
//MouseControlButtons = MouseButtons.None;
}
camera . MouseRotate ( mcx , mcy ) ;
2018-01-02 04:52:54 +08:00
if ( Input . xbenable )
2017-09-21 18:33:05 +08:00
{
2019-12-11 15:46:36 +08:00
camera . ControllerRotate ( Input . xbrx , Input . xbry , elapsed ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
Vector2 movecontrol = new Vector2 ( Input . xbmainaxes . X , Input . xbmainaxes . Y ) ; //(L stick)
if ( Input . kbmovelft ) movecontrol . X - = 1.0f ;
if ( Input . kbmovergt ) movecontrol . X + = 1.0f ;
if ( Input . kbmovefwd ) movecontrol . Y + = 1.0f ;
if ( Input . kbmovebck ) movecontrol . Y - = 1.0f ;
2017-09-21 18:33:05 +08:00
movecontrol . X = Math . Min ( movecontrol . X , 1.0f ) ;
movecontrol . X = Math . Max ( movecontrol . X , - 1.0f ) ;
movecontrol . Y = Math . Min ( movecontrol . Y , 1.0f ) ;
movecontrol . Y = Math . Max ( movecontrol . Y , - 1.0f ) ;
Vector3 fwd = camera . ViewDirection ;
Vector3 fwdxy = Vector3 . Normalize ( new Vector3 ( fwd . X , fwd . Y , 0 ) ) ;
Vector3 lftxy = Vector3 . Normalize ( Vector3 . Cross ( fwd , Vector3 . UnitZ ) ) ;
Vector3 move = lftxy * movecontrol . X + fwdxy * movecontrol . Y ;
Vector2 movexy = new Vector2 ( move . X , move . Y ) ;
2019-12-09 19:33:36 +08:00
movexy * = ( 1.0f + ( Math . Min ( Math . Max ( Input . xblt , 0.0f ) , 1.0f ) * 15.0f ) ) ; //boost with left trigger
2017-09-21 18:33:05 +08:00
pedEntity . ControlMovement = movexy ;
2018-01-02 04:52:54 +08:00
pedEntity . ControlJump = Input . kbjump | | Input . ControllerButtonPressed ( GamepadButtonFlags . X ) ;
pedEntity . ControlBoost = Input . ShiftPressed | | Input . ControllerButtonPressed ( GamepadButtonFlags . A | GamepadButtonFlags . RightShoulder | GamepadButtonFlags . LeftShoulder ) ;
2017-09-21 18:33:05 +08:00
//Vector3 pedfwd = pedEntity.Orientation.Multiply(Vector3.UnitZ);
2018-01-02 04:52:54 +08:00
bool fire = mlb | | ( Input . xbtrigs . Y > 0 ) ;
2017-09-21 18:33:05 +08:00
if ( fire & & ! ControlFireToggle )
{
SpawnTestEntity ( true ) ;
}
ControlFireToggle = fire ;
}
}
2018-01-02 04:52:54 +08:00
private void RenderWorld ( )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
//start point for world view mode rendering.
//also used for the water, paths, collisions, nav mesh, and the project window items.
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
renderworldVisibleYmapDict . Clear ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
int hour = worldymaptimefilter ? ( int ) Renderer . timeofday : - 1 ;
MetaHash weathertype = worldymapweatherfilter ? ( ( weather . CurrentWeatherType ! = null ) ? weather . CurrentWeatherType . NameHash : new MetaHash ( 0 ) ) : new MetaHash ( 0 ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
IEnumerable < Entity > spaceEnts = null ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( renderworld )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
space . GetVisibleYmaps ( camera , hour , weathertype , renderworldVisibleYmapDict ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
spaceEnts = space . TemporaryEntities ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( ProjectForm ! = null )
{
ProjectForm . GetVisibleYmaps ( camera , renderworldVisibleYmapDict ) ;
}
2017-09-21 18:33:05 +08:00
2019-11-25 17:44:16 +08:00
if ( CutsceneForm ! = null )
{
CutsceneForm . GetVisibleYmaps ( camera , renderworldVisibleYmapDict ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderWorld ( renderworldVisibleYmapDict , spaceEnts ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
foreach ( var ymap in Renderer . VisibleYmaps )
{
UpdateMouseHits ( ymap ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( renderwaterquads | | ( SelectionMode = = MapSelectionMode . WaterQuad ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
RenderWorldWaterQuads ( ) ;
2017-09-21 18:33:05 +08:00
}
2021-12-02 16:15:12 +08:00
if ( SelectionMode = = MapSelectionMode . WaveQuad )
{
RenderWorldWaterWaveQuads ( ) ;
}
if ( SelectionMode = = MapSelectionMode . CalmingQuad )
{
RenderWorldWaterCalmingQuads ( ) ;
}
2018-01-02 04:52:54 +08:00
if ( rendercollisionmeshes | | ( SelectionMode = = MapSelectionMode . Collision ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
RenderWorldCollisionMeshes ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( renderpaths | | ( SelectionMode = = MapSelectionMode . Path ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
RenderWorldPaths ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( rendertraintracks | | ( SelectionMode = = MapSelectionMode . TrainTrack ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
RenderWorldTrainTracks ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( rendernavmeshes | | ( SelectionMode = = MapSelectionMode . NavMesh ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
RenderWorldNavMeshes ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( renderscenarios | | ( SelectionMode = = MapSelectionMode . Scenario ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
RenderWorldScenarios ( ) ;
}
if ( renderpopzones | | ( SelectionMode = = MapSelectionMode . PopZone ) )
{
RenderWorldPopZones ( ) ;
}
2021-04-21 04:26:32 +08:00
if ( renderheightmaps | | ( SelectionMode = = MapSelectionMode . Heightmap ) )
{
RenderWorldHeightmaps ( ) ;
}
if ( renderwatermaps | | ( SelectionMode = = MapSelectionMode . Watermap ) )
{
RenderWorldWatermaps ( ) ;
}
2018-01-02 04:52:54 +08:00
if ( renderaudiozones | | ( SelectionMode = = MapSelectionMode . Audio ) )
{
RenderWorldAudioZones ( ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
}
private void RenderWorldCollisionMeshes ( )
{
//enqueue collision meshes for rendering - from the world grid
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
collisionitems . Clear ( ) ;
space . GetVisibleBounds ( camera , collisionmeshrange , collisionmeshlayers , collisionitems ) ;
2017-09-21 18:33:05 +08:00
2020-01-03 19:50:23 +08:00
collisionybns . Clear ( ) ;
foreach ( var item in collisionitems )
{
YbnFile ybn = gameFileCache . GetYbn ( item . Name ) ;
if ( ( ybn ! = null ) & & ( ybn . Loaded ) )
{
collisionybns . Add ( ybn ) ;
}
}
2020-01-13 20:31:27 +08:00
collisioninteriors . Clear ( ) ;
foreach ( var mlo in Renderer . VisibleMlos )
{
if ( mlo . Archetype = = null ) return ;
var hash = mlo . Archetype . Hash ;
YbnFile ybn = gameFileCache . GetYbn ( hash ) ;
if ( ( ybn ! = null ) & & ( ybn . Loaded ) )
{
collisioninteriors [ mlo ] = ybn ;
}
}
2018-01-02 05:26:56 +08:00
if ( ProjectForm ! = null )
{
2020-01-13 20:31:27 +08:00
ProjectForm . GetVisibleYbns ( camera , collisionybns , collisioninteriors ) ;
2018-01-02 05:26:56 +08:00
}
2020-01-03 19:50:23 +08:00
foreach ( var ybn in collisionybns )
2018-01-02 04:52:54 +08:00
{
if ( ( ybn ! = null ) & & ( ybn . Loaded ) )
{
Renderer . RenderCollisionMesh ( ybn . Bounds , null ) ;
}
2017-09-21 18:33:05 +08:00
}
2020-01-13 20:31:27 +08:00
foreach ( var kvp in collisioninteriors )
{
if ( ( kvp . Value ! = null ) & & ( kvp . Value . Loaded ) )
{
Renderer . RenderCollisionMesh ( kvp . Value . Bounds , kvp . Key ) ;
}
}
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void RenderWorldWaterQuads ( )
2017-09-21 18:33:05 +08:00
{
2021-12-02 16:15:12 +08:00
var quads = RenderWorldBaseWaterQuads ( water . WaterQuads , MapSelectionMode . WaterQuad ) ;
Renderer . RenderWaterQuads ( quads ) ;
}
2018-01-02 04:52:54 +08:00
2021-12-02 16:15:12 +08:00
private void RenderWorldWaterCalmingQuads ( ) = > RenderWorldBaseWaterQuads ( water . CalmingQuads , MapSelectionMode . CalmingQuad ) ;
2018-01-02 04:52:54 +08:00
2021-12-02 16:15:12 +08:00
private void RenderWorldWaterWaveQuads ( ) = > RenderWorldBaseWaterQuads ( water . WaveQuads , MapSelectionMode . WaveQuad ) ;
private List < T > RenderWorldBaseWaterQuads < T > ( IEnumerable < T > quads , MapSelectionMode requiredMode ) where T : BaseWaterQuad
{
List < T > renderwaterquadlist = water . GetVisibleQuads < T > ( camera , quads ) ;
2017-09-21 18:33:05 +08:00
2021-12-02 16:15:12 +08:00
ProjectForm ? . GetVisibleWaterQuads < T > ( camera , renderwaterquadlist ) ;
2017-09-21 18:33:05 +08:00
2021-12-02 16:15:12 +08:00
if ( SelectionMode = = requiredMode ) UpdateMouseHits ( renderwaterquadlist ) ;
2017-09-21 18:33:05 +08:00
2021-12-02 16:15:12 +08:00
return renderwaterquadlist ;
2018-01-02 04:52:54 +08:00
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void RenderWorldPaths ( )
{
renderpathynds . Clear ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
space . GetVisibleYnds ( camera , renderpathynds ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( ProjectForm ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
ProjectForm . GetVisibleYnds ( camera , renderpathynds ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderPaths ( renderpathynds ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
UpdateMouseHits ( renderpathynds ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void RenderWorldTrainTracks ( )
{
if ( ! trains . Inited ) return ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
rendertraintracklist . Clear ( ) ;
rendertraintracklist . AddRange ( trains . TrainTracks ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( ProjectForm ! = null )
{
ProjectForm . GetVisibleTrainTracks ( camera , rendertraintracklist ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderTrainTracks ( rendertraintracklist ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
UpdateMouseHits ( rendertraintracklist ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void RenderWorldNavMeshes ( )
{
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
rendernavmeshynvs . Clear ( ) ;
2018-03-12 01:42:20 +08:00
space . GetVisibleYnvs ( camera , collisionmeshrange , rendernavmeshynvs ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( ProjectForm ! = null )
{
2018-03-10 01:58:44 +08:00
ProjectForm . GetVisibleYnvs ( camera , rendernavmeshynvs ) ;
2018-01-02 04:52:54 +08:00
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderNavMeshes ( rendernavmeshynvs ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
UpdateMouseHits ( rendernavmeshynvs ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void RenderWorldScenarios ( )
{
if ( ! scenarios . Inited ) return ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
renderscenariolist . Clear ( ) ;
renderscenariolist . AddRange ( scenarios . ScenarioRegions ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( ProjectForm ! = null )
{
ProjectForm . GetVisibleScenarios ( camera , renderscenariolist ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
Renderer . RenderScenarios ( renderscenariolist ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
UpdateMouseHits ( renderscenariolist ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void RenderWorldPopZones ( )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
if ( ! popzones . Inited ) return ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
//renderpopzonelist.Clear();
//renderpopzonelist.AddRange(popzones.Groups.Values);
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( ProjectForm ! = null )
{
//ProjectForm.GetVisiblePopZones(camera, renderpopzonelist);
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderPopZones ( popzones ) ;
}
2017-09-21 18:33:05 +08:00
2021-04-21 04:26:32 +08:00
private void RenderWorldHeightmaps ( )
{
if ( ! heightmaps . Inited ) return ;
//renderheightmaplist.Clear();
//renderheightmaplist.AddRange(heightmaps.Heightmaps);
if ( ProjectForm ! = null )
{
//ProjectForm.GetVisibleHeightmaps(camera, renderheightmaplist);
}
Renderer . RenderBasePath ( heightmaps ) ;
}
private void RenderWorldWatermaps ( )
{
if ( ! watermaps . Inited ) return ;
//renderwatermaplist.Clear();
//renderwatermaplist.AddRange(watermaps.Watermaps);
if ( ProjectForm ! = null )
{
//ProjectForm.GetVisibleWatermaps(camera, renderwatermaplist);
}
Renderer . RenderBasePath ( watermaps ) ;
}
2018-01-02 04:52:54 +08:00
private void RenderWorldAudioZones ( )
{
if ( ! audiozones . Inited ) return ;
2017-09-21 18:33:05 +08:00
2018-12-26 21:20:39 +08:00
renderaudfilelist . Clear ( ) ;
2022-01-13 02:07:07 +08:00
renderaudfilelist . AddRange ( GameFileCache . AudioDatRelFiles ) ;
2017-09-21 18:33:05 +08:00
if ( ProjectForm ! = null )
{
2018-12-26 21:20:39 +08:00
ProjectForm . GetVisibleAudioFiles ( camera , renderaudfilelist ) ;
2017-09-21 18:33:05 +08:00
}
2018-12-26 21:20:39 +08:00
renderaudplacementslist . Clear ( ) ;
audiozones . GetPlacements ( renderaudfilelist , renderaudplacementslist ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
BoundingBox bbox = new BoundingBox ( ) ;
BoundingSphere bsph = new BoundingSphere ( ) ;
Ray mray = new Ray ( ) ;
mray . Position = camera . MouseRay . Position + camera . Position ;
mray . Direction = camera . MouseRay . Direction ;
float hitdist = float . MaxValue ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
MapBox lastHitOuterBox = new MapBox ( ) ;
MapSphere lastHitOuterSphere = new MapSphere ( ) ;
MapBox mb = new MapBox ( ) ;
MapSphere ms = new MapSphere ( ) ;
2017-09-21 18:33:05 +08:00
2018-12-26 21:20:39 +08:00
for ( int i = 0 ; i < renderaudplacementslist . Count ; i + + )
2017-09-21 18:33:05 +08:00
{
2018-12-26 21:20:39 +08:00
var placement = renderaudplacementslist [ i ] ;
2018-01-02 04:52:54 +08:00
switch ( placement . Shape )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
case Dat151ZoneShape . Box :
case Dat151ZoneShape . Line :
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
mb . CamRelPos = placement . InnerPos - camera . Position ;
mb . BBMin = placement . InnerMin ;
mb . BBMax = placement . InnerMax ;
mb . Orientation = placement . InnerOri ;
mb . Scale = Vector3 . One ;
Renderer . HilightBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( renderaudioouterbounds )
{
mb . CamRelPos = placement . OuterPos - camera . Position ;
mb . BBMin = placement . OuterMin ;
mb . BBMax = placement . OuterMax ;
mb . Orientation = placement . OuterOri ;
mb . Scale = Vector3 . One ;
Renderer . BoundingBoxes . Add ( mb ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Vector3 hbcamrel = ( placement . Position - camera . Position ) ;
Ray mraytrn = new Ray ( ) ;
mraytrn . Position = placement . OrientationInv . Multiply ( camera . MouseRay . Position - hbcamrel ) ;
mraytrn . Direction = placement . OrientationInv . Multiply ( mray . Direction ) ;
bbox . Minimum = placement . HitboxMin ;
bbox . Maximum = placement . HitboxMax ;
if ( mraytrn . Intersects ( ref bbox , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
CurMouseHit . Audio = placement ;
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = hbcamrel ;
CurMouseHit . AABB = bbox ;
lastHitOuterBox = mb ; //highlight the outer box
}
break ;
case Dat151ZoneShape . Sphere :
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( ( placement . InnerPos ! = Vector3 . Zero ) & & ( placement . OuterPos ! = Vector3 . Zero ) )
{
ms . CamRelPos = placement . InnerPos - camera . Position ;
2023-08-21 13:27:13 +08:00
ms . Radius = placement . InnerRadius ;
2018-01-02 04:52:54 +08:00
Renderer . HilightSpheres . Add ( ms ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( renderaudioouterbounds )
{
ms . CamRelPos = placement . OuterPos - camera . Position ;
2023-08-21 13:27:13 +08:00
ms . Radius = placement . OuterRadius ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingSpheres . Add ( ms ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
bsph . Center = placement . Position ;
bsph . Radius = placement . HitSphereRad ;
if ( mray . Intersects ( ref bsph , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
CurMouseHit . Audio = placement ;
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = placement . Position - camera . Position ;
CurMouseHit . AABB = new BoundingBox ( ) ; //no box here
CurMouseHit . BSphere = bsph ;
lastHitOuterSphere = ms ; //highlight the outer sphere
2017-09-21 18:33:05 +08:00
}
}
2018-01-02 04:52:54 +08:00
else
{ }
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
break ;
default :
break ; //shouldn't get here
2017-09-21 18:33:05 +08:00
}
}
2018-01-02 04:52:54 +08:00
if ( CurMouseHit . Audio ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
//hilight the outer bounds of moused item
switch ( CurMouseHit . Audio . Shape )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
case Dat151ZoneShape . Box :
case Dat151ZoneShape . Line :
Renderer . HilightBoxes . Add ( lastHitOuterBox ) ;
break ;
case Dat151ZoneShape . Sphere :
Renderer . HilightSpheres . Add ( lastHitOuterSphere ) ;
break ;
2017-09-21 18:33:05 +08:00
}
}
2018-01-02 04:52:54 +08:00
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void RenderSingleItem ( )
{
//start point for model view mode rendering
uint hash = 0 ; // JenkHash.GenHash(modelname);
if ( ! uint . TryParse ( modelname , out hash ) ) //try use a hash directly
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
hash = JenkHash . GenHash ( modelname ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
Archetype arche = gameFileCache . GetArchetype ( hash ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Archetype selarch = null ;
DrawableBase seldrwbl = null ;
YmapEntityDef selent = null ;
if ( arche ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . RenderArchetype ( arche , null ) ;
selarch = arche ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
else
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
YmapFile ymap = gameFileCache . GetYmap ( hash ) ;
if ( ymap ! = null )
{
Renderer . RenderYmap ( ymap ) ;
}
else
{
//not a ymap... see if it's a ydr or yft
YdrFile ydr = gameFileCache . GetYdr ( hash ) ;
if ( ydr ! = null )
{
if ( ydr . Loaded )
{
Renderer . RenderDrawable ( ydr . Drawable , null , null , hash ) ;
seldrwbl = ydr . Drawable ;
}
}
else
{
YftFile yft = gameFileCache . GetYft ( hash ) ;
if ( yft ! = null )
{
if ( yft . Loaded )
{
if ( yft . Fragment ! = null )
{
var f = yft . Fragment ;
Renderer . RenderFragment ( null , null , f , hash ) ;
seldrwbl = f . Drawable ;
}
}
}
else
{
//TODO: collision bounds single model...
//YbnFile ybn = gameFileCache.GetYbn(hash);
}
}
}
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( ( selarch ! = null ) & & ( seldrwbl = = null ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
seldrwbl = gameFileCache . TryGetDrawable ( selarch ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
//select this item for viewing by the UI...
if ( ( SelectedItem . Archetype ! = selarch ) | | ( SelectedItem . Drawable ! = seldrwbl ) | | ( SelectedItem . EntityDef ! = selent ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SelectedItem . Clear ( ) ;
SelectedItem . Archetype = selarch ;
SelectedItem . Drawable = seldrwbl ;
SelectedItem . EntityDef = selent ;
UpdateSelectionUI ( false ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
}
private void RenderYmaps ( )
{
//start point for ymap view mode rendering
foreach ( string lod in ymaplist )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
uint hash = JenkHash . GenHash ( lod ) ;
YmapFile ymap = gameFileCache . GetYmap ( hash ) ;
Renderer . RenderYmap ( ymap ) ;
UpdateMouseHits ( ymap ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
}
private void RenderMoused ( )
{
//immediately render the bounding box of the currently moused entity.
if ( ! MouseSelectEnabled )
{ return ; }
PrevMouseHit = LastMouseHit ;
LastMouseHit = CurMouseHit ;
2020-01-08 21:44:35 +08:00
bool change = LastMouseHit . CheckForChanges ( PrevMouseHit ) ; //(LastMouseHit.EntityDef != PrevMouseHit.EntityDef);
2018-01-02 04:52:54 +08:00
if ( SelectByGeometry )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
change = change | | ( LastMouseHit . Geometry ! = PrevMouseHit . Geometry ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( change )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
string text = LastMouseHit . GetFullNameString ( string . Empty ) ;
UpdateMousedLabel ( text ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( ! CurMouseHit . HasHit )
{ return ; }
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
BoundsShaderMode mode = BoundsShaderMode . Box ;
float bsphrad = CurMouseHit . BSphere . Radius ;
Vector3 bbmin = CurMouseHit . AABB . Minimum ;
Vector3 bbmax = CurMouseHit . AABB . Maximum ;
Vector3 camrel = CurMouseHit . CamRel ;
Vector3 scale = Vector3 . One ;
Quaternion ori = Quaternion . Identity ;
bool ext = ( CurMouseHit . ArchetypeExtension ! = null ) | | ( CurMouseHit . EntityExtension ! = null ) | | ( CurMouseHit . CollisionBounds ! = null ) ;
if ( CurMouseHit . EntityDef ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
scale = ext ? Vector3 . One : CurMouseHit . EntityDef . Scale ;
ori = CurMouseHit . EntityDef . Orientation ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( CurMouseHit . Archetype ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
bbmin = CurMouseHit . Archetype . BBMin ;
bbmax = CurMouseHit . Archetype . BBMax ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( ( CurMouseHit . Geometry ! = null ) | | ext )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
bbmin = CurMouseHit . AABB . Minimum ; //override archetype AABB..
bbmax = CurMouseHit . AABB . Maximum ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( CurMouseHit . CarGenerator ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
ori = CurMouseHit . CarGenerator . Orientation ;
2017-09-21 18:33:05 +08:00
}
2018-12-14 22:46:48 +08:00
if ( CurMouseHit . BoxOccluder ! = null )
{
ori = CurMouseHit . BoxOccluder . Orientation ;
}
2021-04-30 00:15:23 +08:00
if ( CurMouseHit . OccludeModelTri ! = null )
2018-12-14 22:46:48 +08:00
{
2021-04-30 00:15:23 +08:00
var otri = CurMouseHit . OccludeModelTri ;
Renderer . RenderSelectionTriangleOutline ( otri . Corner1 , otri . Corner2 , otri . Corner3 , 0xFFFFFFFF ) ;
return ;
2018-12-14 22:46:48 +08:00
}
2018-01-02 04:52:54 +08:00
if ( CurMouseHit . MloEntityDef ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
scale = Vector3 . One ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( CurMouseHit . WaterQuad ! = null )
2017-09-21 18:33:05 +08:00
{
}
2018-01-02 04:52:54 +08:00
if ( CurMouseHit . ScenarioNode ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
var sp = CurMouseHit . ScenarioNode . MyPoint ;
if ( sp = = null ) sp = CurMouseHit . ScenarioNode . ClusterMyPoint ;
if ( sp ! = null ) //orientate the moused box for the correct scenario point direction...
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
ori = sp . Orientation ;
2017-09-21 18:33:05 +08:00
}
}
2018-03-12 01:42:20 +08:00
if ( CurMouseHit . NavPoint ! = null )
{
ori = CurMouseHit . NavPoint . Orientation ;
}
2018-03-14 09:36:43 +08:00
if ( CurMouseHit . NavPortal ! = null )
{
ori = CurMouseHit . NavPortal . Orientation ;
}
2019-12-31 21:00:04 +08:00
if ( CurMouseHit . NavPoly ! = null )
{
Renderer . RenderSelectionNavPolyOutline ( CurMouseHit . NavPoly , 0xFFFFFFFF ) ;
return ;
}
2018-01-02 04:52:54 +08:00
if ( CurMouseHit . Audio ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
ori = CurMouseHit . Audio . Orientation ;
if ( CurMouseHit . Audio . Shape = = Dat151ZoneShape . Sphere )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
mode = BoundsShaderMode . Sphere ;
2017-09-21 18:33:05 +08:00
}
}
2020-01-07 17:51:53 +08:00
if ( CurMouseHit . CollisionVertex ! = null )
{
var vpos = CurMouseHit . CollisionVertex . Position ;
var crpos = camrel + ori . Multiply ( vpos ) ;
var vertexSize = 0.1f ;
Renderer . RenderSelectionCircle ( vpos , vertexSize , 0xFFFFFFFF ) ;
}
2019-12-31 21:00:04 +08:00
if ( CurMouseHit . CollisionPoly ! = null )
{
Renderer . RenderSelectionCollisionPolyOutline ( CurMouseHit . CollisionPoly , 0xFFFFFFFF , CurMouseHit . EntityDef ) ;
}
2019-12-09 14:06:59 +08:00
if ( CurMouseHit . CollisionBounds ! = null )
{
ori = ori * CurMouseHit . BBOrientation ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
2019-12-31 21:00:04 +08:00
Renderer . RenderMouseHit ( mode , ref camrel , ref bbmin , ref bbmax , ref scale , ref ori , bsphrad ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void RenderSelection ( )
2017-09-21 18:33:05 +08:00
{
2020-01-08 21:44:35 +08:00
if ( SelectedItem . MultipleSelectionItems ! = null )
2017-09-21 18:33:05 +08:00
{
2020-01-08 21:44:35 +08:00
for ( int i = 0 ; i < SelectedItem . MultipleSelectionItems . Length ; i + + )
2017-09-21 18:33:05 +08:00
{
2020-01-08 21:44:35 +08:00
var item = SelectedItem . MultipleSelectionItems [ i ] ;
2018-01-02 04:52:54 +08:00
RenderSelection ( ref item ) ;
2017-09-21 18:33:05 +08:00
}
}
2018-01-02 04:52:54 +08:00
else
{
RenderSelection ( ref SelectedItem ) ;
}
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void RenderSelection ( ref MapSelection selectionItem )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
//immediately render the bounding box of the current selection. also, arrows.
2017-09-21 18:33:05 +08:00
2019-12-28 20:24:36 +08:00
const uint cred = 0xFF0000FF ;
const uint cgrn = 0xFF00FF00 ;
const uint cblu = 0xFFFF0000 ;
const uint caqu = 0xFFFFFF00 ;
//const uint cyel = 0xFF00FFFF;
2017-09-21 18:33:05 +08:00
2019-12-09 19:33:36 +08:00
if ( ControlBrushEnabled & & MouseRayCollision . Hit )
2017-09-21 18:33:05 +08:00
{
2019-12-31 21:00:04 +08:00
var arup = MouseRayCollision . Normal . GetPerpVec ( ) ;
2019-12-09 19:33:36 +08:00
Renderer . RenderBrushRadiusOutline ( MouseRayCollision . Position , MouseRayCollision . Normal , arup , ProjectForm . GetInstanceBrushRadius ( ) , cgrn ) ;
}
if ( MouseRayCollisionVisible & & MouseRayCollision . Hit )
{
2019-12-31 21:00:04 +08:00
var arup = MouseRayCollision . Normal . GetPerpVec ( ) ;
2019-12-09 19:33:36 +08:00
Renderer . RenderSelectionArrowOutline ( MouseRayCollision . Position , MouseRayCollision . Normal , arup , Quaternion . Identity , 1.0f , 0.05f , cgrn ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( ! ShowSelectionBounds )
{ return ; }
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( ! selectionItem . HasValue )
{ return ; }
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
BoundsShaderMode mode = BoundsShaderMode . Box ;
float bsphrad = selectionItem . BSphere . Radius ;
Vector3 bbmin = selectionItem . AABB . Minimum ;
Vector3 bbmax = selectionItem . AABB . Maximum ;
Vector3 camrel = - camera . Position ;
Vector3 scale = Vector3 . One ;
Quaternion ori = Quaternion . Identity ;
var arch = selectionItem . Archetype ;
var ent = selectionItem . EntityDef ;
if ( selectionItem . Archetype ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
bbmin = selectionItem . Archetype . BBMin ;
bbmax = selectionItem . Archetype . BBMax ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( selectionItem . EntityDef ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
camrel = ent . Position - camera . Position ;
scale = ent . Scale ;
ori = ent . Orientation ;
if ( EditEntityPivot )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . RenderSelectionEntityPivot ( ent ) ;
2017-09-21 18:33:05 +08:00
}
}
2018-01-02 04:52:54 +08:00
if ( selectionItem . CarGenerator ! = null )
{
var cg = selectionItem . CarGenerator ;
camrel = cg . Position - camera . Position ;
ori = cg . Orientation ;
bbmin = cg . BBMin ;
bbmax = cg . BBMax ;
float arrowlen = cg . _CCarGen . perpendicularLength ;
float arrowrad = arrowlen * 0.066f ;
Renderer . RenderSelectionArrowOutline ( cg . Position , Vector3 . UnitX , Vector3 . UnitY , ori , arrowlen , arrowrad , cgrn ) ;
2017-09-21 18:33:05 +08:00
2018-12-23 14:20:49 +08:00
if ( ! Renderer . rendercars ) //only render selected car if not already rendering cars..
{
Quaternion cgtrn = Quaternion . RotationAxis ( Vector3 . UnitZ , ( float ) Math . PI * - 0.5f ) ; //car fragments currently need to be rotated 90 deg right...
Quaternion cgori = Quaternion . Multiply ( ori , cgtrn ) ;
2017-09-21 18:33:05 +08:00
2018-12-23 14:20:49 +08:00
Renderer . RenderCar ( cg . Position , cgori , cg . _CCarGen . carModel , cg . _CCarGen . popGroup ) ;
}
2018-01-02 04:52:54 +08:00
}
2021-12-02 16:15:12 +08:00
if ( selectionItem . WaveQuad ! = null )
{
var quad = selectionItem . WaveQuad ;
Vector3 quadArrowPos = new Vector3 ( quad . minX + ( quad . maxX - quad . minX ) * 0.5f , quad . minY + ( quad . maxY - quad . minY ) * 0.5f , 5 ) ;
Quaternion waveOri = quad . WaveOrientation ;
float arrowlen = quad . Amplitude * 50 ;
float arrowrad = arrowlen * 0.066f ;
Renderer . RenderSelectionArrowOutline ( quadArrowPos , Vector3 . UnitX , Vector3 . UnitY , waveOri , arrowlen , arrowrad , cgrn ) ;
}
2021-04-22 13:16:11 +08:00
if ( selectionItem . LodLight ! = null )
{
Renderer . RenderSelectionLodLight ( selectionItem . LodLight ) ;
if ( selectionItem . LodLight . LodLights ! = null )
{
bbmin = selectionItem . LodLight . LodLights . BBMin ;
bbmax = selectionItem . LodLight . LodLights . BBMax ;
}
}
2018-01-02 04:52:54 +08:00
if ( selectionItem . PathNode ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
camrel = selectionItem . PathNode . Position - camera . Position ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( selectionItem . TrainTrackNode ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
camrel = selectionItem . TrainTrackNode . Position - camera . Position ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
if ( selectionItem . ScenarioNode ! = null )
{
camrel = selectionItem . ScenarioNode . Position - camera . Position ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
var sn = selectionItem . ScenarioNode ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
//render direction arrow for ScenarioPoint
ori = sn . Orientation ;
float arrowlen = 2.0f ;
float arrowrad = 0.25f ;
Renderer . RenderSelectionArrowOutline ( sn . Position , Vector3 . UnitY , Vector3 . UnitZ , ori , arrowlen , arrowrad , cgrn ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
MCScenarioPoint vpoint = sn . MyPoint ? ? sn . ClusterMyPoint ;
if ( ( vpoint ! = null ) & & ( vpoint ? . Type ? . IsVehicle ? ? false ) )
{
2021-11-06 21:58:08 +08:00
var vhash = vpoint . ModelSet ? . NameHash ? ? 493038497 ; //"none"
if ( ( vhash = = 0 ) | | ( vhash = = 493038497 ) )
{
vhash = vpoint . Type ? . VehicleModelSetHash ? ? 0 ;
}
2018-01-02 04:52:54 +08:00
if ( ( vhash = = 0 ) & & ( sn . ChainingNode ? . Chain ? . Edges ! = null ) & & ( sn . ChainingNode . Chain . Edges . Length > 0 ) )
{
var fedge = sn . ChainingNode . Chain . Edges [ 0 ] ; //for chain nodes, show the first node's model...
var fnode = fedge ? . NodeFrom ? . ScenarioNode ;
if ( fnode ! = null )
{
vpoint = fnode . MyPoint ? ? fnode . ClusterMyPoint ;
2021-11-06 21:58:08 +08:00
vhash = vpoint . ModelSet ? . NameHash ? ? 493038497 ; //"none"
if ( ( vhash = = 0 ) | | ( vhash = = 493038497 ) )
{
vhash = vpoint . Type ? . VehicleModelSetHash ? ? 0 ;
}
2018-01-02 04:52:54 +08:00
}
}
2017-09-21 18:33:05 +08:00
2018-03-04 03:24:15 +08:00
Renderer . RenderCar ( sn . Position , sn . Orientation , 0 , vhash , true ) ;
2018-01-02 04:52:54 +08:00
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
}
if ( selectionItem . ScenarioEdge ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
//render scenario edge arrow
var se = selectionItem . ScenarioEdge ;
var sn1 = se . NodeFrom ;
var sn2 = se . NodeTo ;
if ( ( sn1 ! = null ) & & ( sn2 ! = null ) )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
var dirp = sn2 . Position - sn1 . Position ;
float dl = dirp . Length ( ) ;
Vector3 dir = dirp * ( 1.0f / dl ) ;
Vector3 dup = Vector3 . UnitZ ;
var aori = Quaternion . Invert ( Quaternion . RotationLookAtRH ( dir , dup ) ) ;
float arrowrad = 0.25f ;
float arrowlen = Math . Max ( dl - arrowrad * 5.0f , 0 ) ;
Renderer . RenderSelectionArrowOutline ( sn1 . Position , - Vector3 . UnitZ , Vector3 . UnitY , aori , arrowlen , arrowrad , cblu ) ;
2017-09-21 18:33:05 +08:00
}
}
2018-01-02 04:52:54 +08:00
if ( selectionItem . MloEntityDef ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
bbmin = selectionItem . AABB . Minimum ;
bbmax = selectionItem . AABB . Maximum ;
2018-03-07 10:12:20 +08:00
var mlo = selectionItem . MloEntityDef ;
var mlop = mlo . Position ;
var mloa = mlo . Archetype as MloArchetype ;
if ( mloa ! = null )
{
VertexTypePC p1 = new VertexTypePC ( ) ;
VertexTypePC p2 = new VertexTypePC ( ) ;
if ( mloa . portals ! = null )
{
for ( int ip = 0 ; ip < mloa . portals . Length ; ip + + )
{
var portal = mloa . portals [ ip ] ;
if ( portal . Corners = = null ) continue ;
2018-03-08 00:05:23 +08:00
p2 . Colour = caqu ;
if ( ( portal . _Data . flags & 4 ) > 0 )
{
p2 . Colour = cblu ;
}
2019-12-28 01:08:45 +08:00
var pcl = portal . Corners . Length ;
for ( int ic = 0 ; ic < pcl ; ic + + )
2018-03-07 10:12:20 +08:00
{
2019-12-28 01:08:45 +08:00
var icn = ic + 1 ; if ( icn > = pcl ) icn = 0 ;
p1 . Colour = ( ic = = 0 ) ? cred : p2 . Colour ; //highlight index 0 and winding direction
p1 . Position = mlop + mlo . Orientation . Multiply ( portal . Corners [ ic ] . XYZ ( ) ) ;
p2 . Position = mlop + mlo . Orientation . Multiply ( portal . Corners [ icn ] . XYZ ( ) ) ;
2018-03-07 10:12:20 +08:00
Renderer . SelectionLineVerts . Add ( p1 ) ;
Renderer . SelectionLineVerts . Add ( p2 ) ;
}
}
}
if ( mloa . rooms ! = null )
{
MapBox wbox = new MapBox ( ) ;
wbox . Scale = Vector3 . One ;
for ( int ir = 0 ; ir < mloa . rooms . Length ; ir + + )
{
var room = mloa . rooms [ ir ] ;
wbox . CamRelPos = mlop - camera . Position ;
wbox . BBMin = room . _Data . bbMin ; // + offset;
wbox . BBMax = room . _Data . bbMax ; // + offset;
wbox . Orientation = mlo . Orientation ;
if ( ( ir = = 0 ) | | ( room . RoomName = = "limbo" ) )
{
bbmin = room . _Data . bbMin ;
bbmax = room . _Data . bbMax ;
//////Renderer.BoundingBoxes.Add(wbox);
}
else
{
wbox . BBMin = room . BBMin_CW ; //hack method to use CW calculated room AABBs,
wbox . BBMax = room . BBMax_CW ; //R* ones are right size, but wrong position??
Renderer . WhiteBoxes . Add ( wbox ) ;
}
}
}
}
2018-01-02 04:52:54 +08:00
}
2019-12-28 13:01:09 +08:00
if ( selectionItem . MloRoomDef ! = null )
{
camrel + = ori . Multiply ( selectionItem . BBOffset ) ;
ori = ori * selectionItem . BBOrientation ;
}
2018-12-07 10:41:18 +08:00
if ( ( selectionItem . ArchetypeExtension ! = null ) | | ( selectionItem . EntityExtension ! = null ) | | ( selectionItem . CollisionBounds ! = null ) )
2018-01-02 04:52:54 +08:00
{
bbmin = selectionItem . AABB . Minimum ;
bbmax = selectionItem . AABB . Maximum ;
scale = Vector3 . One ;
}
2018-12-07 10:41:18 +08:00
if ( selectionItem . GrassBatch ! = null )
{
bbmin = selectionItem . GrassBatch . AABBMin ;
bbmax = selectionItem . GrassBatch . AABBMax ;
scale = Vector3 . One ;
}
2018-12-14 22:46:48 +08:00
if ( selectionItem . BoxOccluder ! = null )
{
var bo = selectionItem . BoxOccluder ;
camrel = bo . Position - camera . Position ;
ori = bo . Orientation ;
bbmin = bo . BBMin ;
bbmax = bo . BBMax ;
}
2021-04-30 00:15:23 +08:00
if ( selectionItem . OccludeModelTri ! = null )
{
var ot = selectionItem . OccludeModelTri ;
var om = ot . Model ;
bbmin = om . _OccludeModel . bmin ;
bbmax = om . _OccludeModel . bmax ;
Renderer . RenderSelectionTriangleOutline ( ot . Corner1 , ot . Corner2 , ot . Corner3 , cgrn ) ;
}
2018-01-02 04:52:54 +08:00
if ( selectionItem . NavPoly ! = null )
{
Renderer . RenderSelectionNavPoly ( selectionItem . NavPoly ) ;
2018-05-01 16:03:20 +08:00
Renderer . RenderSelectionNavPolyOutline ( selectionItem . NavPoly , cgrn ) ;
return ; //don't render a selection box for nav poly
2017-09-21 18:33:05 +08:00
}
2018-03-12 01:42:20 +08:00
if ( selectionItem . NavPoint ! = null )
{
var navp = selectionItem . NavPoint ;
camrel = navp . Position - camera . Position ;
//render direction arrow for NavPoint
ori = navp . Orientation ;
float arrowlen = 2.0f ;
float arrowrad = 0.25f ;
Renderer . RenderSelectionArrowOutline ( navp . Position , - Vector3 . UnitY , Vector3 . UnitZ , ori , arrowlen , arrowrad , cgrn ) ;
}
if ( selectionItem . NavPortal ! = null )
{
2018-03-14 09:36:43 +08:00
var navp = selectionItem . NavPortal ;
camrel = navp . Position - camera . Position ;
2017-09-21 18:33:05 +08:00
2018-03-14 09:36:43 +08:00
//render direction arrow for NavPortal
ori = navp . Orientation ;
float arrowlen = 2.0f ;
float arrowrad = 0.25f ;
Renderer . RenderSelectionArrowOutline ( navp . Position , Vector3 . UnitY , Vector3 . UnitZ , ori , arrowlen , arrowrad , cgrn ) ;
}
2018-01-02 04:52:54 +08:00
if ( selectionItem . Audio ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
var au = selectionItem . Audio ;
camrel = au . Position - camera . Position ;
ori = au . Orientation ;
bbmin = au . HitboxMin ;
bbmax = au . HitboxMax ;
if ( selectionItem . Audio . Shape = = Dat151ZoneShape . Sphere )
{
mode = BoundsShaderMode . Sphere ;
MapSphere wsph = new MapSphere ( ) ;
wsph . CamRelPos = au . OuterPos - camera . Position ;
2023-08-21 13:27:13 +08:00
wsph . Radius = au . OuterRadius ;
2018-01-02 04:52:54 +08:00
Renderer . WhiteSpheres . Add ( wsph ) ;
}
else
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
MapBox wbox = new MapBox ( ) ;
wbox . CamRelPos = au . OuterPos - camera . Position ;
wbox . BBMin = au . OuterMin ;
wbox . BBMax = au . OuterMax ;
wbox . Orientation = au . OuterOri ;
wbox . Scale = scale ;
Renderer . WhiteBoxes . Add ( wbox ) ;
2017-09-21 18:33:05 +08:00
}
}
2020-01-07 17:51:53 +08:00
if ( selectionItem . CollisionVertex ! = null )
{
var vpos = selectionItem . CollisionVertex . Position ;
var crpos = camrel + ori . Multiply ( vpos ) ;
var vertexSize = 0.1f ;
Renderer . RenderSelectionCircle ( vpos , vertexSize , cgrn ) ;
}
else if ( selectionItem . CollisionPoly ! = null )
2019-12-31 21:00:04 +08:00
{
Renderer . RenderSelectionCollisionPolyOutline ( selectionItem . CollisionPoly , cgrn , selectionItem . EntityDef ) ;
}
2019-12-09 14:06:59 +08:00
if ( selectionItem . CollisionBounds ! = null )
{
camrel + = ori . Multiply ( selectionItem . BBOffset ) ;
ori = ori * selectionItem . BBOrientation ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( mode = = BoundsShaderMode . Box )
{
MapBox box = new MapBox ( ) ;
box . CamRelPos = camrel ;
box . BBMin = bbmin ;
box . BBMax = bbmax ;
box . Orientation = ori ;
box . Scale = scale ;
Renderer . SelectionBoxes . Add ( box ) ;
}
else if ( mode = = BoundsShaderMode . Sphere )
{
MapSphere sph = new MapSphere ( ) ;
sph . CamRelPos = camrel ;
sph . Radius = bsphrad ;
Renderer . SelectionSpheres . Add ( sph ) ;
}
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void RenderMarkers ( )
{
//immediately render all the current markers.
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
lock ( markersyncroot ) //should only cause delays if markers moved/updated
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
foreach ( var marker in Markers )
{
marker . CamRelPos = marker . WorldPos - camera . Position ;
marker . Distance = marker . CamRelPos . Length ( ) ;
marker . ScreenPos = camera . ViewProjMatrix . MultiplyW ( marker . CamRelPos ) ;
}
lock ( markersortedsyncroot ) //stop collisions with mouse testing
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SortedMarkers . Clear ( ) ;
SortedMarkers . AddRange ( Markers ) ;
if ( RenderLocator )
{
LocatorMarker . CamRelPos = LocatorMarker . WorldPos - camera . Position ;
LocatorMarker . Distance = LocatorMarker . CamRelPos . Length ( ) ;
LocatorMarker . ScreenPos = camera . ViewProjMatrix . MultiplyW ( LocatorMarker . CamRelPos ) ;
SortedMarkers . Add ( LocatorMarker ) ;
}
SortedMarkers . Sort ( ( m1 , m2 ) = > m2 . Distance . CompareTo ( m1 . Distance ) ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
MarkerBatch . Clear ( ) ;
MarkerBatch . AddRange ( SortedMarkers ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
Renderer . RenderMarkers ( MarkerBatch ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void RenderWidgets ( )
{
if ( ! ShowWidget ) return ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Renderer . RenderTransformWidget ( Widget ) ;
}
private void UpdateWidgets ( )
{
if ( ! ShowWidget ) return ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Widget . Update ( camera ) ;
2017-12-22 04:26:04 +08:00
}
2017-09-22 15:31:02 +08:00
2018-02-25 20:30:29 +08:00
private Vector3 GetGroundPoint ( Vector3 p )
{
float uplimit = 3.0f ;
float downlimit = 20.0f ;
Ray ray = new Ray ( p , new Vector3 ( 0 , 0 , - 1.0f ) ) ;
ray . Position . Z + = 0.1f ;
SpaceRayIntersectResult hit = space . RayIntersect ( ray , downlimit ) ;
if ( hit . Hit )
{
return hit . Position ;
}
ray . Position . Z + = uplimit ;
hit = space . RayIntersect ( ray , downlimit ) ;
if ( hit . Hit )
{
return hit . Position ;
}
return p ;
}
private Vector3 SnapPosition ( Vector3 p )
{
Vector3 gpos = ( p / SnapGridSize ) . Round ( ) * SnapGridSize ;
switch ( SnapMode )
{
case WorldSnapMode . Grid :
p = gpos ;
break ;
case WorldSnapMode . Ground :
p = GetGroundPoint ( p ) ;
break ;
case WorldSnapMode . Hybrid :
p = GetGroundPoint ( gpos ) ;
break ;
}
return p ;
}
2018-01-02 04:52:54 +08:00
private void Widget_OnPositionChange ( Vector3 newpos , Vector3 oldpos )
2017-12-22 04:26:04 +08:00
{
2018-01-02 04:52:54 +08:00
//called during UpdateWidgets()
2018-02-25 20:30:29 +08:00
newpos = SnapPosition ( newpos ) ;
2018-01-02 04:52:54 +08:00
if ( newpos = = oldpos ) return ;
2017-09-21 18:33:05 +08:00
2020-01-08 21:44:35 +08:00
SelectedItem . SetPosition ( newpos , EditEntityPivot ) ;
2020-01-14 10:26:38 +08:00
SelectedItem . UpdateGraphics ( this ) ;
2017-12-22 04:26:04 +08:00
if ( ProjectForm ! = null )
{
2020-01-08 21:44:35 +08:00
ProjectForm . OnWorldSelectionModified ( SelectedItem ) ;
2017-09-21 18:33:05 +08:00
}
}
private void Widget_OnRotationChange ( Quaternion newrot , Quaternion oldrot )
{
2017-09-26 08:27:18 +08:00
//called during UpdateWidgets()
2017-09-21 18:33:05 +08:00
if ( newrot = = oldrot ) return ;
2020-01-08 21:44:35 +08:00
SelectedItem . SetRotation ( newrot , EditEntityPivot ) ;
2020-01-14 10:26:38 +08:00
SelectedItem . UpdateGraphics ( this ) ;
2017-09-26 08:27:18 +08:00
if ( ProjectForm ! = null )
2017-09-21 18:33:05 +08:00
{
2020-01-08 21:44:35 +08:00
ProjectForm . OnWorldSelectionModified ( SelectedItem ) ;
2017-09-21 18:33:05 +08:00
}
}
private void Widget_OnScaleChange ( Vector3 newscale , Vector3 oldscale )
{
2017-09-26 08:27:18 +08:00
//called during UpdateWidgets()
2017-09-21 18:33:05 +08:00
if ( newscale = = oldscale ) return ;
2020-01-08 21:44:35 +08:00
SelectedItem . SetScale ( newscale , EditEntityPivot ) ;
2020-01-14 10:26:38 +08:00
SelectedItem . UpdateGraphics ( this ) ;
2017-09-26 08:27:18 +08:00
if ( ProjectForm ! = null )
{
2020-01-08 21:44:35 +08:00
ProjectForm . OnWorldSelectionModified ( SelectedItem ) ;
2017-09-21 18:33:05 +08:00
}
}
public void SetWidgetPosition ( Vector3 pos , bool enableUndo = false )
{
if ( enableUndo )
{
SetWidgetMode ( "Position" ) ;
MarkUndoStart ( Widget ) ;
}
Widget . Position = pos ;
if ( enableUndo )
{
MarkUndoEnd ( Widget ) ;
}
}
public void SetWidgetRotation ( Quaternion q , bool enableUndo = false )
{
if ( enableUndo )
{
SetWidgetMode ( "Rotation" ) ;
MarkUndoStart ( Widget ) ;
}
Widget . Rotation = q ;
if ( enableUndo )
{
MarkUndoEnd ( Widget ) ;
}
}
public void SetWidgetScale ( Vector3 s , bool enableUndo = false )
{
if ( enableUndo )
{
SetWidgetMode ( "Scale" ) ;
MarkUndoStart ( Widget ) ;
}
Widget . Scale = s ;
if ( enableUndo )
{
MarkUndoEnd ( Widget ) ;
}
}
2020-01-14 14:56:11 +08:00
public void ChangeMultiPosition ( MapSelection [ ] items , Vector3 pos , bool editPivot = false )
{
if ( items = = SelectedItem . MultipleSelectionItems )
{
SelectedItem . SetPosition ( pos , editPivot ) ;
SetWidgetPosition ( pos , true ) ;
}
}
public void ChangeMultiRotation ( MapSelection [ ] items , Quaternion rot , bool editPivot = false )
{
if ( items = = SelectedItem . MultipleSelectionItems )
{
SelectedItem . SetRotation ( rot , editPivot ) ;
SetWidgetRotation ( rot , true ) ;
}
}
public void ChangeMultiScale ( MapSelection [ ] items , Vector3 scale , bool editPivot = false )
{
if ( items = = SelectedItem . MultipleSelectionItems )
{
SelectedItem . SetScale ( scale , editPivot ) ;
SetWidgetScale ( scale , true ) ;
}
}
2017-09-21 18:33:05 +08:00
public void UpdatePathYndGraphics ( YndFile ynd , bool fullupdate )
{
2023-09-04 18:48:50 +08:00
if ( ynd = = null )
{
return ;
}
var selection = SelectedItem . PathNode ! = null
? new [ ] { SelectedItem . PathNode }
: null ;
2017-09-21 18:33:05 +08:00
if ( fullupdate )
{
2017-09-26 10:07:45 +08:00
ynd . UpdateAllNodePositions ( ) ;
ynd . BuildBVH ( ) ;
2017-09-21 18:33:05 +08:00
space . BuildYndData ( ynd ) ;
}
else
{
2021-11-28 14:55:55 +08:00
ynd . UpdateAllNodePositions ( ) ;
2023-09-04 18:48:50 +08:00
space . BuildYndVerts ( ynd , selection ) ;
2017-09-21 18:33:05 +08:00
}
2018-12-05 15:26:28 +08:00
//lock (Renderer.RenderSyncRoot)
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . Invalidate ( ynd ) ;
2017-09-21 18:33:05 +08:00
}
}
public void UpdatePathNodeGraphics ( YndNode pathnode , bool fullupdate )
{
if ( pathnode = = null ) return ;
pathnode . Ynd . UpdateBvhForNode ( pathnode ) ;
UpdatePathYndGraphics ( pathnode . Ynd , fullupdate ) ;
}
public YndNode GetPathNodeFromSpace ( ushort areaid , ushort nodeid )
{
return space . NodeGrid . GetYndNode ( areaid , nodeid ) ;
}
2020-01-01 21:16:49 +08:00
public void UpdateCollisionBoundsGraphics ( Bounds b )
{
2020-01-14 09:54:45 +08:00
lock ( Renderer . RenderSyncRoot )
2020-01-01 21:16:49 +08:00
{
2020-01-14 09:54:45 +08:00
if ( b is BoundBVH bvh )
{
bvh . BuildBVH ( ) ;
}
else if ( b is BoundComposite bc )
{
bc . BuildBVH ( ) ;
}
2020-01-01 21:16:49 +08:00
2020-01-14 09:54:45 +08:00
var ib = b ;
while ( ib . Parent ! = null )
{
ib = ib . Parent ;
}
2020-01-01 21:16:49 +08:00
Renderer . Invalidate ( ib ) ;
}
}
2018-03-10 22:12:08 +08:00
public void UpdateNavYnvGraphics ( YnvFile ynv , bool fullupdate )
2017-09-21 18:33:05 +08:00
{
2018-03-14 09:36:43 +08:00
ynv . UpdateAllNodePositions ( ) ;
2018-03-10 22:12:08 +08:00
ynv . UpdateTriangleVertices ( ) ;
2018-03-12 01:42:20 +08:00
ynv . BuildBVH ( ) ;
2018-03-10 22:12:08 +08:00
2018-12-05 15:26:28 +08:00
//lock (Renderer.RenderSyncRoot)
2018-03-10 22:12:08 +08:00
{
Renderer . Invalidate ( ynv ) ;
}
2017-09-21 18:33:05 +08:00
}
2018-03-10 22:12:08 +08:00
public void UpdateNavPolyGraphics ( YnvPoly poly , bool fullupdate )
2017-09-21 18:33:05 +08:00
{
2018-03-10 22:12:08 +08:00
if ( poly = = null ) return ;
//poly.Ynv.UpdateBvhForPoly(poly);//TODO!
UpdateNavYnvGraphics ( poly . Ynv , fullupdate ) ;
2017-09-21 18:33:05 +08:00
}
2018-03-14 09:36:43 +08:00
public void UpdateNavPointGraphics ( YnvPoint point , bool fullupdate )
{
if ( point = = null ) return ;
//poly.Ynv.UpdateBvhForPoint(point);//TODO!
UpdateNavYnvGraphics ( point . Ynv , fullupdate ) ;
}
public void UpdateNavPortalGraphics ( YnvPortal portal , bool fullupdate )
{
if ( portal = = null ) return ;
//poly.Ynv.UpdateBvhForPortal(portal);//TODO!
UpdateNavYnvGraphics ( portal . Ynv , fullupdate ) ;
}
2017-09-21 18:33:05 +08:00
public void UpdateTrainTrackGraphics ( TrainTrack tt , bool fullupdate )
{
tt . BuildVertices ( ) ;
2017-09-26 10:07:45 +08:00
tt . BuildBVH ( ) ;
2017-09-21 18:33:05 +08:00
//if (fullupdate)
//{
// //space.BuildYndData(ynd);
//}
//else
//{
// //space.BuildYndVerts(ynd);
//}
2018-12-05 15:26:28 +08:00
//lock (Renderer.RenderSyncRoot)
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . Invalidate ( tt ) ;
2017-09-21 18:33:05 +08:00
}
}
public void UpdateTrainTrackNodeGraphics ( TrainTrackNode node , bool fullupdate )
{
if ( node = = null ) return ;
node . Track . UpdateBvhForNode ( node ) ;
UpdateTrainTrackGraphics ( node . Track , fullupdate ) ;
}
public void UpdateScenarioGraphics ( YmtFile ymt , bool fullupdate )
{
var scenario = ymt . ScenarioRegion ;
if ( scenario = = null ) return ;
scenario . BuildBVH ( ) ;
scenario . BuildVertices ( ) ;
2018-12-05 15:26:28 +08:00
//lock (Renderer.RenderSyncRoot)
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . Invalidate ( scenario ) ;
2017-09-21 18:33:05 +08:00
}
}
2021-04-26 02:41:02 +08:00
public void UpdateLodLightGraphics ( YmapLODLight lodlight )
{
lodlight . LodLights ? . BuildBVH ( ) ;
//lock (Renderer.RenderSyncRoot)
{
Renderer . Invalidate ( lodlight ) ;
}
}
2021-04-30 00:15:23 +08:00
public void UpdateBoxOccluderGraphics ( YmapBoxOccluder box )
{
//lock (Renderer.RenderSyncRoot)
{
Renderer . Invalidate ( box ) ;
}
}
public void UpdateOccludeModelGraphics ( YmapOccludeModel model )
{
model . BuildBVH ( ) ;
model . BuildVertices ( ) ;
//lock (Renderer.RenderSyncRoot)
{
Renderer . Invalidate ( model ) ;
}
}
2018-06-08 00:42:41 +08:00
public void UpdateGrassBatchGraphics ( YmapGrassInstanceBatch grassBatch )
{
2018-12-05 15:26:28 +08:00
//lock (Renderer.RenderSyncRoot)
2018-06-08 00:42:41 +08:00
{
Renderer . Invalidate ( grassBatch ) ;
}
}
2018-12-26 21:20:39 +08:00
public void UpdateAudioPlacementGraphics ( RelFile rel )
{
audiozones . PlacementsDict . Remove ( rel ) ; //should cause a rebuild to add/remove items
}
2024-07-27 11:40:12 +08:00
public AudioPlacement GetAudioPlacement ( RelFile rel , Dat151RelData reldata )
{
var placement = audiozones . FindPlacement ( rel , reldata ) ;
if ( placement = = null )
{
if ( reldata is Dat151AmbientZone az ) placement = new AudioPlacement ( rel , az ) ;
if ( reldata is Dat151AmbientRule ar ) placement = new AudioPlacement ( rel , ar ) ;
if ( reldata is Dat151StaticEmitter se ) placement = new AudioPlacement ( rel , se ) ;
}
return placement ;
}
2018-12-26 21:20:39 +08:00
2017-09-21 18:33:05 +08:00
2019-11-25 17:44:16 +08:00
public void SetCameraTransform ( Vector3 pos , Quaternion rot )
{
camera . FollowEntity . Position = pos ;
camera . FollowEntity . Orientation = rot ;
camera . FollowEntity . OrientationInv = Quaternion . Invert ( rot ) ;
camera . TargetRotation = Vector3 . Zero ;
camera . TargetDistance = 0.01f ;
}
2019-11-28 13:36:32 +08:00
public void SetCameraClipPlanes ( float znear , float zfar )
{
//sets the camera clip planes to the specified values, for use in eg cutscenes
camera . ZNear = znear ;
camera . ZFar = zfar ;
camera . UpdateProj = true ;
}
public void ResetCameraClipPlanes ( )
{
//resets the camera clip planes to the values in the UI controls.
camera . ZNear = ( float ) NearClipUpDown . Value ;
camera . ZFar = ( float ) FarClipUpDown . Value ;
camera . UpdateProj = true ;
}
2019-11-25 17:44:16 +08:00
2017-09-21 18:33:05 +08:00
public Vector3 GetCameraPosition ( )
{
//currently used by ProjectForm when creating entities
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
return camera . Position ;
}
}
public Vector3 GetCameraViewDir ( )
{
//currently used by ProjectForm when creating entities
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
return camera . ViewDirection ;
}
}
public void SetCameraSensitivity ( float sensitivity , float smoothing )
{
camera . Sensitivity = sensitivity ;
camera . Smoothness = smoothing ;
}
2018-01-02 08:07:24 +08:00
public void SetMouseInverted ( bool invert )
{
MouseInvert = invert ;
}
2017-09-21 18:33:05 +08:00
public void SetKeyBindings ( KeyBindings kb )
{
2018-01-02 04:52:54 +08:00
Input . keyBindings = kb . Copy ( ) ;
2017-09-21 18:33:05 +08:00
UpdateToolbarShortcutsText ( ) ;
}
private void UpdateToolbarShortcutsText ( )
{
2018-01-02 04:52:54 +08:00
var kb = Input . keyBindings ;
ToolbarSelectButton . ToolTipText = string . Format ( "Select objects / Exit edit mode ({0}, {1})" , kb . ToggleMouseSelect , kb . ExitEditMode ) ;
ToolbarMoveButton . ToolTipText = string . Format ( "Move ({0})" , kb . EditPosition ) ;
ToolbarRotateButton . ToolTipText = string . Format ( "Rotate ({0})" , kb . EditRotation ) ;
ToolbarScaleButton . ToolTipText = string . Format ( "Scale ({0})" , kb . EditScale ) ;
ShowToolbarCheckBox . Text = string . Format ( "Show Toolbar ({0})" , kb . ToggleToolbar ) ;
2017-09-21 18:33:05 +08:00
}
private MapBox GetExtensionBox ( Vector3 camrel , MetaWrapper ext )
{
MapBox b = new MapBox ( ) ;
Vector3 pos = Vector3 . Zero ;
float size = 0.5f ;
if ( ext is MCExtensionDefLightEffect )
{
var le = ext as MCExtensionDefLightEffect ;
pos = le . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefSpawnPointOverride )
{
var spo = ext as MCExtensionDefSpawnPointOverride ;
pos = spo . Data . offsetPosition ;
size = spo . Data . Radius ;
}
else if ( ext is MCExtensionDefDoor )
{
var door = ext as MCExtensionDefDoor ;
pos = door . Data . offsetPosition ;
}
else if ( ext is Mrage__phVerletClothCustomBounds )
{
var cb = ext as Mrage__phVerletClothCustomBounds ;
if ( ( cb . CollisionData ! = null ) & & ( cb . CollisionData . Length > 0 ) )
{
pos = cb . CollisionData [ 0 ] . Data . Position ;
}
}
else if ( ext is MCExtensionDefParticleEffect )
{
var pe = ext as MCExtensionDefParticleEffect ;
pos = pe . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefAudioCollisionSettings )
{
var acs = ext as MCExtensionDefAudioCollisionSettings ;
pos = acs . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefAudioEmitter )
{
var ae = ext as MCExtensionDefAudioEmitter ;
pos = ae . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefSpawnPoint )
{
var sp = ext as MCExtensionDefSpawnPoint ;
pos = sp . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefExplosionEffect )
{
var ee = ext as MCExtensionDefExplosionEffect ;
pos = ee . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefLadder )
{
var ld = ext as MCExtensionDefLadder ;
pos = ld . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefBuoyancy )
{
var bu = ext as MCExtensionDefBuoyancy ;
pos = bu . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefExpression )
{
var exp = ext as MCExtensionDefExpression ;
pos = exp . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefLightShaft )
{
var ls = ext as MCExtensionDefLightShaft ;
pos = ls . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefWindDisturbance )
{
var wd = ext as MCExtensionDefWindDisturbance ;
pos = wd . Data . offsetPosition ;
}
else if ( ext is MCExtensionDefProcObject )
{
var po = ext as MCExtensionDefProcObject ;
pos = po . Data . offsetPosition ;
}
b . BBMin = pos - size ;
b . BBMax = pos + size ;
b . CamRelPos = camrel ;
return b ;
}
private void SpawnTestEntity ( bool cameraCenter = false )
{
if ( ! space . Inited ) return ;
Vector3 dir = ( cameraCenter ? camera . ViewDirection : camera . MouseRay . Direction ) ;
Vector3 ofs = ( cameraCenter ? Vector3 . Zero : camera . MouseRay . Position ) ;
Vector3 pos = ofs + camera . Position + ( dir * 1.5f ) ;
Vector3 vel = dir * 50.0f ; //m/s
var hash = JenkHash . GenHash ( "prop_alien_egg_01" ) ;
var arch = GameFileCache . GetArchetype ( hash ) ;
if ( arch = = null ) return ;
CEntityDef cent = new CEntityDef ( ) ;
cent . archetypeName = hash ;
cent . rotation = new Vector4 ( 0 , 0 , 0 , 1 ) ;
cent . scaleXY = 1.0f ;
cent . scaleZ = 1.0f ;
cent . flags = 1572872 ;
cent . parentIndex = - 1 ;
cent . lodDist = 200.0f ;
2019-01-13 16:51:49 +08:00
cent . lodLevel = rage__eLodType . LODTYPES_DEPTH_ORPHANHD ;
cent . priorityLevel = rage__ePriorityLevel . PRI_REQUIRED ;
2017-09-21 18:33:05 +08:00
cent . ambientOcclusionMultiplier = 255 ;
cent . artificialAmbientOcclusion = 255 ;
cent . position = pos ;
YmapEntityDef ent = new YmapEntityDef ( null , 0 , ref cent ) ;
ent . SetArchetype ( arch ) ;
Entity e = new Entity ( ) ;
e . Position = pos ;
e . Velocity = vel ;
e . Mass = 10.0f ;
e . Momentum = vel * e . Mass ;
e . EntityDef = ent ;
e . Radius = arch . BSRadius * 0.7f ;
e . EnableCollisions = true ;
e . Enabled = true ;
2019-12-10 15:33:45 +08:00
e . Lifetime = 20.0f ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
space . AddTemporaryEntity ( e ) ;
}
}
public void SetControlMode ( WorldControlMode mode )
{
if ( InvokeRequired )
{
try
{
Invoke ( new Action ( ( ) = > { SetControlMode ( mode ) ; } ) ) ;
}
catch
{ }
return ;
}
if ( mode = = ControlMode ) return ;
2018-06-08 00:42:41 +08:00
bool wasfree = ( ControlMode = = WorldControlMode . Free | | ControlBrushEnabled ) ;
bool isfree = ( mode = = WorldControlMode . Free | | ControlBrushEnabled ) ;
2017-09-21 18:33:05 +08:00
if ( isfree & & ! wasfree )
{
camEntity . Position = pedEntity . Position ;
pedEntity . Enabled = false ;
2018-01-02 04:52:54 +08:00
Renderer . timerunning = false ;
2017-09-21 18:33:05 +08:00
camera . SetFollowEntity ( camEntity ) ;
camera . TargetDistance = 1.0f ; //default?
camera . Smoothness = Settings . Default . CameraSmoothing ;
Cursor . Show ( ) ;
}
else if ( ! isfree & & wasfree )
{
pedEntity . Position = camEntity . Position ;
pedEntity . Velocity = Vector3 . Zero ;
pedEntity . Enabled = true ;
2018-01-02 04:52:54 +08:00
Renderer . timerunning = true ;
2017-09-21 18:33:05 +08:00
camera . SetFollowEntity ( pedEntity . CameraEntity ) ;
camera . TargetDistance = 0.01f ; //1cm
camera . Smoothness = 20.0f ;
//center the mouse in the window
System . Drawing . Point centerp = new System . Drawing . Point ( ClientSize . Width / 2 , ClientSize . Height / 2 ) ;
MouseLastPoint = centerp ;
MouseX = centerp . X ;
MouseY = centerp . Y ;
Cursor . Position = PointToScreen ( centerp ) ;
Cursor . Hide ( ) ;
}
ControlMode = mode ;
}
private void BeginMouseHitTest ( )
{
//reset variables for beginning the mouse hit test
CurMouseHit . Clear ( ) ;
2019-12-30 15:05:02 +08:00
if ( Input . CtrlPressed & & ProjectForm ! = null & & ProjectForm . CanPaintInstances ( ) ) // Get whether or not we can brush from the project form.
2017-09-21 18:33:05 +08:00
{
2018-06-08 00:42:41 +08:00
ControlBrushEnabled = true ;
2019-12-09 19:33:36 +08:00
MouseRayCollisionVisible = false ;
2018-06-08 00:42:41 +08:00
MouseRayCollision = GetSpaceMouseRay ( ) ;
}
2019-12-09 19:33:36 +08:00
else
2018-06-08 00:42:41 +08:00
{
ControlBrushEnabled = false ;
2019-12-09 19:33:36 +08:00
if ( Input . CtrlPressed & & MouseRayCollisionEnabled )
{
MouseRayCollisionVisible = true ;
MouseRayCollision = GetSpaceMouseRay ( ) ;
}
else
{
MouseRayCollisionVisible = false ;
}
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
Renderer . RenderedDrawablesListEnable =
( ( SelectionMode = = MapSelectionMode . Entity ) & & MouseSelectEnabled ) | |
( SelectionMode = = MapSelectionMode . EntityExtension ) | |
( SelectionMode = = MapSelectionMode . ArchetypeExtension ) ;
Renderer . RenderedBoundCompsListEnable = ( SelectionMode = = MapSelectionMode . Collision ) ;
}
2018-06-10 21:36:50 +08:00
2018-06-08 00:42:41 +08:00
public SpaceRayIntersectResult GetSpaceMouseRay ( )
{
SpaceRayIntersectResult ret = new SpaceRayIntersectResult ( ) ;
2019-12-05 18:05:31 +08:00
if ( space . Inited & & space . BoundsStore ! = null )
2018-06-08 00:42:41 +08:00
{
Ray mray = new Ray ( ) ;
mray . Position = camera . MouseRay . Position + camera . Position ;
mray . Direction = camera . MouseRay . Direction ;
2019-12-10 15:33:45 +08:00
return space . RayIntersect ( mray , float . MaxValue , collisionmeshlayers ) ;
2018-06-08 00:42:41 +08:00
}
return ret ;
}
public SpaceRayIntersectResult Raycast ( Ray ray )
{
2019-12-10 15:33:45 +08:00
return space . RayIntersect ( ray , float . MaxValue , collisionmeshlayers ) ;
2018-06-08 00:42:41 +08:00
}
2019-12-30 15:05:02 +08:00
private void UpdateMouseHits ( )
{
UpdateMouseHitsFromRenderer ( ) ;
UpdateMouseHitsFromSpace ( ) ;
2020-01-10 20:41:58 +08:00
UpdateMouseHitsFromProject ( ) ;
2019-12-30 15:05:02 +08:00
}
2018-01-02 04:52:54 +08:00
private void UpdateMouseHitsFromRenderer ( )
{
foreach ( var rd in Renderer . RenderedDrawables )
{
UpdateMouseHits ( rd . Drawable , rd . Archetype , rd . Entity ) ;
}
2019-12-30 15:05:02 +08:00
}
private void UpdateMouseHitsFromSpace ( )
{
if ( SelectionMode = = MapSelectionMode . Collision )
2018-01-02 04:52:54 +08:00
{
2019-12-30 15:05:02 +08:00
MouseRayCollision = GetSpaceMouseRay ( ) ;
if ( MouseRayCollision . Hit )
{
2020-01-10 20:41:58 +08:00
CurMouseHit . UpdateCollisionFromRayHit ( ref MouseRayCollision , camera ) ;
2019-12-30 15:05:02 +08:00
}
2018-01-02 04:52:54 +08:00
}
2017-09-21 18:33:05 +08:00
}
2020-01-10 20:41:58 +08:00
private void UpdateMouseHitsFromProject ( )
{
if ( ProjectForm = = null ) return ;
if ( SelectionMode = = MapSelectionMode . Collision )
{
ProjectForm . GetMouseCollision ( camera , ref CurMouseHit ) ;
}
}
2018-01-02 04:52:54 +08:00
private void UpdateMouseHits ( DrawableBase drawable , Archetype arche , YmapEntityDef entity )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
//if ((SelectionMode == MapSelectionMode.Entity) && !MouseSelectEnabled) return; //performance improvement when not selecting entities...
2017-09-21 18:33:05 +08:00
//test the selected entity/archetype for mouse hit.
//first test the bounding sphere for mouse hit..
Quaternion orinv ;
Ray mraytrn ;
float hitdist = 0.0f ;
int geometryIndex = 0 ;
DrawableGeometry geometry = null ;
BoundingBox geometryAABB = new BoundingBox ( ) ;
BoundingSphere bsph = new BoundingSphere ( ) ;
BoundingBox bbox = new BoundingBox ( ) ;
BoundingBox gbbox = new BoundingBox ( ) ;
Quaternion orientation = Quaternion . Identity ;
Vector3 scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Vector3 camrel = - camera . Position ;
2017-09-21 18:33:05 +08:00
if ( entity ! = null )
{
orientation = entity . Orientation ;
scale = entity . Scale ;
2018-01-02 04:52:54 +08:00
camrel + = entity . Position ;
2017-09-21 18:33:05 +08:00
}
if ( arche ! = null )
{
bsph . Center = camrel + orientation . Multiply ( arche . BSCenter ) ; //could use entity.BSCenter
bsph . Radius = arche . BSRadius ;
bbox . Minimum = arche . BBMin * scale ;
bbox . Maximum = arche . BBMax * scale ;
}
else
{
bsph . Center = camrel + drawable . BoundingCenter ;
bsph . Radius = drawable . BoundingSphereRadius ;
2020-01-23 15:36:34 +08:00
bbox . Minimum = drawable . BoundingBoxMin * scale ;
bbox . Maximum = drawable . BoundingBoxMax * scale ;
2017-09-21 18:33:05 +08:00
}
bool mousespherehit = camera . MouseRay . Intersects ( ref bsph ) ;
if ( ( SelectionMode = = MapSelectionMode . EntityExtension ) | | ( SelectionMode = = MapSelectionMode . ArchetypeExtension ) )
{
//transform the mouse ray into the entity space.
orinv = Quaternion . Invert ( orientation ) ;
mraytrn = new Ray ( ) ;
mraytrn . Position = orinv . Multiply ( camera . MouseRay . Position - camrel ) ;
mraytrn . Direction = orinv . Multiply ( camera . MouseRay . Direction ) ;
if ( SelectionMode = = MapSelectionMode . EntityExtension )
{
if ( ( entity ! = null ) & & ( entity . Extensions ! = null ) )
{
for ( int i = 0 ; i < entity . Extensions . Length ; i + + )
{
var extension = entity . Extensions [ i ] ;
MapBox mb = GetExtensionBox ( camrel , extension ) ;
mb . Orientation = orientation ;
mb . Scale = Vector3 . One ; // scale;
mb . BBMin * = scale ;
mb . BBMax * = scale ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
bbox . Minimum = mb . BBMin ; //TODO: refactor this!
bbox . Maximum = mb . BBMax ;
if ( mraytrn . Intersects ( ref bbox , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
{
CurMouseHit . EntityDef = entity ;
CurMouseHit . Archetype = arche ;
CurMouseHit . EntityExtension = extension ;
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = mb . CamRelPos ;
CurMouseHit . AABB = bbox ;
}
}
}
return ; //only test extensions when in select extension mode...
}
if ( SelectionMode = = MapSelectionMode . ArchetypeExtension )
{
if ( ( arche ! = null ) & & ( arche . Extensions ! = null ) )
{
for ( int i = 0 ; i < arche . Extensions . Length ; i + + )
{
var extension = arche . Extensions [ i ] ;
MapBox mb = GetExtensionBox ( camrel , extension ) ;
mb . Orientation = orientation ;
mb . Scale = Vector3 . One ; // scale;
mb . BBMin * = scale ;
mb . BBMax * = scale ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
bbox . Minimum = mb . BBMin ; //TODO: refactor this!
bbox . Maximum = mb . BBMax ;
if ( mraytrn . Intersects ( ref bbox , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
{
CurMouseHit . EntityDef = entity ;
CurMouseHit . Archetype = arche ;
CurMouseHit . ArchetypeExtension = extension ;
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = mb . CamRelPos ;
CurMouseHit . AABB = bbox ;
}
}
}
return ; //only test extensions when in select extension mode...
}
}
if ( ! mousespherehit )
{ return ; } //no sphere hit, so no entity hit.
bool usegeomboxes = SelectByGeometry ;
2020-03-14 19:23:40 +08:00
var dmodels = drawable . DrawableModels ? . High ;
if ( dmodels = = null )
2017-09-21 18:33:05 +08:00
{ usegeomboxes = false ; }
if ( usegeomboxes )
{
2020-03-14 19:23:40 +08:00
for ( int i = 0 ; i < dmodels . Length ; i + + )
2017-09-21 18:33:05 +08:00
{
2020-03-14 19:23:40 +08:00
var m = dmodels [ i ] ;
2018-01-04 17:35:38 +08:00
if ( m . BoundsData = = null )
2017-09-21 18:33:05 +08:00
{ usegeomboxes = false ; break ; }
}
}
//transform the mouse ray into the entity space.
orinv = Quaternion . Invert ( orientation ) ;
mraytrn = new Ray ( ) ;
mraytrn . Position = orinv . Multiply ( camera . MouseRay . Position - camrel ) ;
mraytrn . Direction = orinv . Multiply ( camera . MouseRay . Direction ) ;
hitdist = 0.0f ;
if ( usegeomboxes )
{
//geometry bounding boxes version
float ghitdist = float . MaxValue ;
2020-03-14 19:23:40 +08:00
for ( int i = 0 ; i < dmodels . Length ; i + + )
2017-09-21 18:33:05 +08:00
{
2020-03-14 19:23:40 +08:00
var m = dmodels [ i ] ;
2018-01-04 17:35:38 +08:00
int gbbcount = m . BoundsData . Length ;
2017-09-21 18:33:05 +08:00
for ( int j = 0 ; j < gbbcount ; j + + ) //first box seems to be whole model
{
2018-01-04 17:35:38 +08:00
var gbox = m . BoundsData [ j ] ;
2017-09-21 18:33:05 +08:00
gbbox . Minimum = gbox . Min . XYZ ( ) ;
gbbox . Maximum = gbox . Max . XYZ ( ) ;
bbox . Minimum = gbbox . Minimum * scale ;
bbox . Maximum = gbbox . Maximum * scale ;
bool usehit = false ;
if ( mraytrn . Intersects ( ref bbox , out hitdist ) )
{
if ( ( j = = 0 ) & & ( gbbcount > 1 ) ) continue ; //ignore a model hit
//bool firsthit = (mousehit.EntityDef == null);
if ( hitdist > 0.0f ) //firsthit || //ignore when inside the box
{
bool nearer = ( ( hitdist < CurMouseHit . HitDist ) & & ( hitdist < ghitdist ) ) ;
bool radsm = true ;
if ( CurMouseHit . Geometry ! = null )
{
var b1 = ( gbbox . Maximum - gbbox . Minimum ) * scale ;
var b2 = ( CurMouseHit . AABB . Maximum - CurMouseHit . AABB . Minimum ) * scale ;
float r1 = b1 . Length ( ) * 0.5f ;
float r2 = b2 . Length ( ) * 0.5f ;
radsm = ( r1 < ( r2 ) ) ; // * 0.5f));
}
if ( ( nearer & & radsm ) | | radsm ) usehit = true ;
}
}
else if ( j = = 0 ) //no hit on model box
{
break ; //don't try this model's geometries
}
if ( usehit )
{
int gind = ( j > 0 ) ? j - 1 : 0 ;
ghitdist = hitdist ;
geometry = m . Geometries [ gind ] ;
geometryAABB = gbbox ;
geometryIndex = gind ;
}
}
}
if ( geometry = = null )
{
return ; //no geometry hit.
}
hitdist = ghitdist ;
}
else
{
//archetype/drawable bounding boxes version
bool outerhit = false ;
if ( mraytrn . Intersects ( ref bbox , out hitdist ) ) //test primary box
{
bool firsthit = ( CurMouseHit . EntityDef = = null ) ;
if ( firsthit | | ( hitdist > 0.0f ) ) //ignore when inside the box..
{
bool nearer = ( hitdist < CurMouseHit . HitDist ) ; //closer than the last..
bool radsm = true ;
2017-10-01 22:06:12 +08:00
if ( ( CurMouseHit . Archetype ! = null ) & & ( arche ! = null ) ) //compare hit archetype sizes...
2017-09-21 18:33:05 +08:00
{
//var b1 = (arche.BBMax - arche.BBMin) * scale;
//var b2 = (mousehit.Archetype.BBMax - mousehit.Archetype.BBMin) * scale;
float r1 = arche . BSRadius ;
float r2 = CurMouseHit . Archetype . BSRadius ;
radsm = ( r1 < = ( r2 ) ) ; // * 0.5f)); //prefer selecting smaller things
}
if ( ( nearer & & radsm ) | | radsm )
{
outerhit = true ;
}
}
}
if ( ! outerhit )
{ return ; } //no hit.
}
CurMouseHit . HitDist = ( hitdist > 0.0f ) ? hitdist : CurMouseHit . HitDist ;
CurMouseHit . EntityDef = entity ;
CurMouseHit . Archetype = arche ;
CurMouseHit . Drawable = drawable ;
CurMouseHit . Geometry = geometry ;
CurMouseHit . AABB = geometryAABB ;
CurMouseHit . GeometryIndex = geometryIndex ;
CurMouseHit . CamRel = camrel ;
//go through geometries...? need to use skeleton?
//if (drawable.DrawableModelsHigh == null)
//{ return; }
//if (drawable.DrawableModelsHigh.data_items == null)
//{ return; }
//for (int i = 0; i < drawable.DrawableModelsHigh.data_items.Length; i++)
//{
// var model = drawable.DrawableModelsHigh.data_items[i];
// if ((model.Geometries == null) || (model.Geometries.data_items == null))
// { continue; }
// if ((model.Unknown_18h_Data == null))
// { continue; }
// int boffset = 0;
// if ((model.Unknown_18h_Data.Length > model.Geometries.data_items.Length))
// { boffset = 1; }
// for (int j = 0; j < model.Geometries.data_items.Length; j++)
// {
// var geom = model.Geometries.data_items[j];
// var gbox = model.Unknown_18h_Data[j + boffset];
// bbox.Minimum = gbox.AABB_Max.XYZ();
// bbox.Maximum = gbox.AABB_Min.XYZ();
// if (mraytrn.Intersects(ref bbox, out hitdist)) //test geom box
// {
// bool firsthit = (mousehit.EntityDef == null);
// if (firsthit || (hitdist > 0.0f)) //ignore when inside the box..
// {
// bool nearer = (hitdist < mousehit.HitDist); //closer than the last..
// if (nearer)
// {
// mousehit.HitDist = (hitdist > 0.0f) ? hitdist : mousehit.HitDist;
// mousehit.EntityDef = entity;
// mousehit.Archetype = arche;
// mousehit.Drawable = drawable;
// mousehit.CamRel = camrel;
// }
// }
// }
// }
//}
//Bounds b = null;
//var dd = drawable as Drawable;
//if (dd != null)
//{
// b = dd.Bound;
//}
//else
//{
// var fd = drawable as FragDrawable;
// if (fd != null)
// {
// b = fd.Bound;
// }
//}
//if (b == null)
//{ return; }
//else
//{ }
}
private void UpdateMouseHits ( YmapFile ymap )
{
2022-07-29 21:16:13 +08:00
//find mouse hits for things like MLOs, time cycle mods, grass batches, and car generators in ymaps.
2017-09-21 18:33:05 +08:00
BoundingBox bbox = new BoundingBox ( ) ;
Ray mray = new Ray ( ) ;
mray . Position = camera . MouseRay . Position + camera . Position ;
mray . Direction = camera . MouseRay . Direction ;
float hitdist = float . MaxValue ;
2018-01-02 04:52:54 +08:00
float dmax = Renderer . renderboundsmaxdist ;
2017-09-21 18:33:05 +08:00
if ( ( SelectionMode = = MapSelectionMode . TimeCycleModifier ) & & ( ymap . TimeCycleModifiers ! = null ) )
{
for ( int i = 0 ; i < ymap . TimeCycleModifiers . Length ; i + + )
{
var tcm = ymap . TimeCycleModifiers [ i ] ;
2018-01-02 04:52:54 +08:00
if ( ( ( ( tcm . BBMin + tcm . BBMax ) * 0.5f ) - camera . Position ) . Length ( ) > dmax ) continue ;
2017-09-21 18:33:05 +08:00
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = - camera . Position ;
mb . BBMin = tcm . BBMin ;
mb . BBMax = tcm . BBMax ;
mb . Orientation = Quaternion . Identity ;
mb . Scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
bbox . Minimum = mb . BBMin ;
bbox . Maximum = mb . BBMax ;
if ( mray . Intersects ( ref bbox , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
{
CurMouseHit . TimeCycleModifier = tcm ;
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = mb . CamRelPos ;
CurMouseHit . AABB = bbox ;
}
}
}
if ( ( SelectionMode = = MapSelectionMode . CarGenerator ) & & ( ymap . CarGenerators ! = null ) )
{
for ( int i = 0 ; i < ymap . CarGenerators . Length ; i + + )
{
var cg = ymap . CarGenerators [ i ] ;
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = cg . Position - camera . Position ;
mb . BBMin = cg . BBMin ;
mb . BBMax = cg . BBMax ;
mb . Orientation = cg . Orientation ;
mb . Scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
Quaternion orinv = Quaternion . Invert ( cg . Orientation ) ;
Ray mraytrn = new Ray ( ) ;
mraytrn . Position = orinv . Multiply ( camera . MouseRay . Position - mb . CamRelPos ) ;
mraytrn . Direction = orinv . Multiply ( mray . Direction ) ;
bbox . Minimum = mb . BBMin ;
bbox . Maximum = mb . BBMax ;
if ( mraytrn . Intersects ( ref bbox , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
{
CurMouseHit . CarGenerator = cg ;
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = mb . CamRelPos ;
CurMouseHit . AABB = bbox ;
}
}
2017-10-01 14:29:31 +08:00
if ( SelectedItem . CarGenerator ! = null )
{
}
2017-09-21 18:33:05 +08:00
}
2017-09-28 00:24:21 +08:00
if ( ( SelectionMode = = MapSelectionMode . MloInstance ) & & ( ymap . MloEntities ! = null ) )
2017-09-21 18:33:05 +08:00
{
2017-09-28 00:24:21 +08:00
for ( int i = 0 ; i < ymap . MloEntities . Length ; i + + )
2017-09-21 18:33:05 +08:00
{
2017-09-28 00:24:21 +08:00
var ent = ymap . MloEntities [ i ] ;
2018-03-07 10:12:20 +08:00
if ( SelectedItem . MloEntityDef = = ent ) continue ;
2017-09-21 18:33:05 +08:00
MapBox mb = new MapBox ( ) ;
2017-09-28 00:24:21 +08:00
mb . CamRelPos = ent . Position - camera . Position ;
2017-09-21 18:33:05 +08:00
mb . BBMin = /*ent?.BBMin ??*/ new Vector3 ( - 1.5f ) ;
mb . BBMax = /*ent?.BBMax ??*/ new Vector3 ( 1.5f ) ;
mb . Orientation = ent ? . Orientation ? ? Quaternion . Identity ;
mb . Scale = /*ent?.Scale ??*/ Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
Quaternion orinv = Quaternion . Invert ( mb . Orientation ) ;
Ray mraytrn = new Ray ( ) ;
mraytrn . Position = orinv . Multiply ( camera . MouseRay . Position - mb . CamRelPos ) ;
mraytrn . Direction = orinv . Multiply ( mray . Direction ) ;
bbox . Minimum = mb . BBMin ;
bbox . Maximum = mb . BBMax ;
if ( mraytrn . Intersects ( ref bbox , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
{
CurMouseHit . MloEntityDef = ent ;
CurMouseHit . EntityDef = ent ;
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = mb . CamRelPos ;
CurMouseHit . AABB = new BoundingBox ( mb . BBMin , mb . BBMax ) ;
}
}
}
if ( ( SelectionMode = = MapSelectionMode . Grass ) & & ( ymap . GrassInstanceBatches ! = null ) )
{
for ( int i = 0 ; i < ymap . GrassInstanceBatches . Length ; i + + )
{
var gb = ymap . GrassInstanceBatches [ i ] ;
2018-01-02 04:52:54 +08:00
if ( ( gb . Position - camera . Position ) . Length ( ) > dmax ) continue ;
2017-09-21 18:33:05 +08:00
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = - camera . Position ;
mb . BBMin = gb . AABBMin ;
mb . BBMax = gb . AABBMax ;
mb . Orientation = Quaternion . Identity ;
mb . Scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
bbox . Minimum = mb . BBMin ;
bbox . Maximum = mb . BBMax ;
if ( mray . Intersects ( ref bbox , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
{
CurMouseHit . GrassBatch = gb ;
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = mb . CamRelPos ;
CurMouseHit . AABB = bbox ;
}
}
}
2021-04-22 13:16:11 +08:00
if ( ( SelectionMode = = MapSelectionMode . LodLights ) & & ( ymap . LODLights ! = null ) )
{
var ll = ymap . LODLights ;
if ( ( ( ( ll . BBMin + ll . BBMax ) * 0.5f ) - camera . Position ) . Length ( ) < = dmax )
{
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = - camera . Position ;
mb . BBMin = ll . BBMin ;
mb . BBMax = ll . BBMax ;
mb . Orientation = Quaternion . Identity ;
mb . Scale = Vector3 . One ;
Renderer . BoundingBoxes . Add ( mb ) ;
if ( ll . BVH ! = null )
{
UpdateMouseHits ( ll . BVH , ref mray ) ;
}
}
}
if ( ( SelectionMode = = MapSelectionMode . LodLights ) & & ( ymap . DistantLODLights ! = null ) )
2017-09-21 18:33:05 +08:00
{
var dll = ymap . DistantLODLights ;
2018-01-02 04:52:54 +08:00
if ( ( ( ( dll . BBMin + dll . BBMax ) * 0.5f ) - camera . Position ) . Length ( ) < = dmax )
2017-09-21 18:33:05 +08:00
{
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = - camera . Position ;
mb . BBMin = dll . BBMin ;
mb . BBMax = dll . BBMax ;
mb . Orientation = Quaternion . Identity ;
mb . Scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
}
2018-12-14 22:46:48 +08:00
if ( ( SelectionMode = = MapSelectionMode . Occlusion ) & & ( ymap . BoxOccluders ! = null ) )
{
for ( int i = 0 ; i < ymap . BoxOccluders . Length ; i + + )
{
var bo = ymap . BoxOccluders [ i ] ;
if ( ( bo . Position - camera . Position ) . Length ( ) > dmax ) continue ;
2017-09-21 18:33:05 +08:00
2021-04-30 00:15:23 +08:00
Renderer . RenderBasePath ( bo ) ;
2018-12-14 22:46:48 +08:00
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = bo . Position - camera . Position ;
mb . BBMin = bo . BBMin ;
mb . BBMax = bo . BBMax ;
mb . Orientation = bo . Orientation ;
mb . Scale = Vector3 . One ;
2021-04-30 00:15:23 +08:00
//Renderer.BoundingBoxes.Add(mb);
2018-12-14 22:46:48 +08:00
Quaternion orinv = Quaternion . Invert ( bo . Orientation ) ;
Ray mraytrn = new Ray ( ) ;
mraytrn . Position = orinv . Multiply ( camera . MouseRay . Position - mb . CamRelPos ) ;
mraytrn . Direction = orinv . Multiply ( mray . Direction ) ;
bbox . Minimum = mb . BBMin ;
bbox . Maximum = mb . BBMax ;
2021-04-30 00:15:23 +08:00
if ( mraytrn . Intersects ( ref bbox , out float hd ) & & ( hd < CurMouseHit . HitDist ) & & ( hd > 0 ) )
2018-12-14 22:46:48 +08:00
{
2021-04-30 00:15:23 +08:00
hitdist = hd ;
2018-12-14 22:46:48 +08:00
CurMouseHit . BoxOccluder = bo ;
2021-04-30 00:15:23 +08:00
CurMouseHit . OccludeModelTri = null ;
2018-12-14 22:46:48 +08:00
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = mb . CamRelPos ;
CurMouseHit . AABB = bbox ;
}
}
}
if ( ( SelectionMode = = MapSelectionMode . Occlusion ) & & ( ymap . OccludeModels ! = null ) )
{
2018-12-15 01:09:02 +08:00
for ( int i = 0 ; i < ymap . OccludeModels . Length ; i + + )
{
var om = ymap . OccludeModels [ i ] ;
Renderer . RenderBasePath ( om ) ;
2021-04-30 00:15:23 +08:00
var hittri = om . RayIntersect ( ref mray , ref hitdist ) ;
if ( ( hittri ! = null ) & & ( hitdist < CurMouseHit . HitDist ) )
2018-12-15 09:12:57 +08:00
{
CurMouseHit . BoxOccluder = null ;
2021-04-30 00:15:23 +08:00
CurMouseHit . OccludeModelTri = hittri ;
2018-12-15 09:12:57 +08:00
CurMouseHit . HitDist = hitdist ;
2021-04-30 00:15:23 +08:00
CurMouseHit . CamRel = - camera . Position ;
CurMouseHit . AABB = hittri . Box ;
2018-12-15 09:12:57 +08:00
}
2018-12-15 01:09:02 +08:00
}
2018-12-14 22:46:48 +08:00
}
2017-09-21 18:33:05 +08:00
}
2021-12-02 16:15:12 +08:00
private void UpdateMouseHits < T > ( List < T > waterquads ) where T : BaseWaterQuad
2017-09-21 18:33:05 +08:00
{
BoundingBox bbox = new BoundingBox ( ) ;
Ray mray = new Ray ( ) ;
mray . Position = camera . MouseRay . Position + camera . Position ;
mray . Direction = camera . MouseRay . Direction ;
2021-12-02 16:15:12 +08:00
float hitdist ;
2017-09-21 18:33:05 +08:00
2021-12-02 16:15:12 +08:00
foreach ( T quad in waterquads )
2017-09-21 18:33:05 +08:00
{
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = - camera . Position ;
2021-12-02 16:15:12 +08:00
mb . BBMin = new Vector3 ( quad . minX , quad . minY , quad . z ? ? 0 ) ;
mb . BBMax = new Vector3 ( quad . maxX , quad . maxY , quad . z ? ? 0 ) ;
2017-09-21 18:33:05 +08:00
mb . Orientation = Quaternion . Identity ;
mb . Scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
bbox . Minimum = mb . BBMin ;
bbox . Maximum = mb . BBMax ;
2021-12-02 16:15:12 +08:00
if ( mray . Intersects ( ref bbox , out hitdist ) & & hitdist > 0 & & hitdist < = CurMouseHit . HitDist )
2017-09-21 18:33:05 +08:00
{
2021-12-02 16:15:12 +08:00
float curSize = CurMouseHit . AABB . Size . X * CurMouseHit . AABB . Size . Y ;
float newSize = bbox . Size . X * bbox . Size . Y ;
if ( ( curSize = = 0 ) | | ( newSize < curSize ) )
{
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = mb . CamRelPos ;
CurMouseHit . AABB = bbox ;
CurMouseHit . WaterQuad = quad as WaterQuad ;
CurMouseHit . WaveQuad = quad as WaterWaveQuad ;
CurMouseHit . CalmingQuad = quad as WaterCalmingQuad ;
}
2017-09-21 18:33:05 +08:00
}
}
}
private void UpdateMouseHits ( List < YnvFile > ynvs )
{
if ( SelectionMode ! = MapSelectionMode . NavMesh ) return ;
Ray mray = new Ray ( ) ;
mray . Position = camera . MouseRay . Position + camera . Position ;
mray . Direction = camera . MouseRay . Direction ;
foreach ( var ynv in ynvs )
{
if ( renderpathbounds )
{
if ( ynv . Nav = = null ) continue ;
if ( ynv . Nav . SectorTree = = null ) continue ;
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = - camera . Position ;
mb . BBMin = ynv . Nav . SectorTree . AABBMin . XYZ ( ) ;
mb . BBMax = ynv . Nav . SectorTree . AABBMax . XYZ ( ) ;
mb . Orientation = Quaternion . Identity ;
mb . Scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
2018-03-12 01:42:20 +08:00
if ( ynv . BVH ! = null )
{
UpdateMouseHits ( ynv . BVH , ref mray ) ;
}
//if ((CurMouseHit.NavPoint != null) || (CurMouseHit.NavPortal != null)) continue;
2017-09-21 18:33:05 +08:00
if ( ( ynv . Nav ! = null ) & & ( ynv . Vertices ! = null ) & & ( ynv . Indices ! = null ) & & ( ynv . Polys ! = null ) )
{
UpdateMouseHits ( ynv , ynv . Nav . SectorTree , ynv . Nav . SectorTree , ref mray ) ;
}
}
}
private void UpdateMouseHits ( YnvFile ynv , NavMeshSector navsector , NavMeshSector rootsec , ref Ray mray )
{
if ( navsector = = null ) return ;
float hitdist = float . MaxValue ;
BoundingBox bbox = new BoundingBox ( ) ;
bbox . Minimum = navsector . AABBMin . XYZ ( ) ;
bbox . Maximum = navsector . AABBMax . XYZ ( ) ;
if ( rootsec ! = null ) //apparently the Z values are incorrect :(
{
bbox . Minimum . Z = rootsec . AABBMin . Z ;
bbox . Maximum . Z = rootsec . AABBMax . Z ;
}
float fhd ;
if ( mray . Intersects ( ref bbox , out fhd ) ) //ray intersects this node... check children for hits!
{
////test vis
//MapBox mb = new MapBox();
//mb.CamRelPos = -camera.Position;
//mb.BBMin = bbox.Minimum;
//mb.BBMax = bbox.Maximum;
//mb.Orientation = Quaternion.Identity;
//mb.Scale = Vector3.One;
//BoundingBoxes.Add(mb);
if ( navsector . SubTree1 ! = null )
{
UpdateMouseHits ( ynv , navsector . SubTree1 , rootsec , ref mray ) ;
}
if ( navsector . SubTree2 ! = null )
{
UpdateMouseHits ( ynv , navsector . SubTree2 , rootsec , ref mray ) ;
}
if ( navsector . SubTree3 ! = null )
{
UpdateMouseHits ( ynv , navsector . SubTree3 , rootsec , ref mray ) ;
}
if ( navsector . SubTree4 ! = null )
{
UpdateMouseHits ( ynv , navsector . SubTree4 , rootsec , ref mray ) ;
}
if ( ( navsector . Data ! = null ) & & ( navsector . Data . PolyIDs ! = null ) )
{
BoundingBox cbox = new BoundingBox ( ) ;
cbox . Minimum = bbox . Minimum - camera . Position ;
cbox . Maximum = bbox . Maximum - camera . Position ;
var polys = ynv . Polys ;
var polyids = navsector . Data . PolyIDs ;
for ( int i = 0 ; i < polyids . Length ; i + + )
{
var polyid = polyids [ i ] ;
if ( polyid > = polys . Count )
{ continue ; }
var poly = polys [ polyid ] ;
var ic = poly . _RawData . IndexCount ;
var startid = poly . _RawData . IndexID ;
var endid = startid + ic ;
if ( startid > = ynv . Indices . Count )
{ continue ; }
if ( endid > ynv . Indices . Count )
{ continue ; }
var vc = ynv . Vertices . Count ;
var startind = ynv . Indices [ startid ] ;
if ( startind > = vc )
{ continue ; }
Vector3 p0 = ynv . Vertices [ startind ] ;
//test triangles for the poly.
int tricount = ic - 2 ;
for ( int t = 0 ; t < tricount ; t + + )
{
int tid = startid + t ;
int ind1 = ynv . Indices [ tid + 1 ] ;
int ind2 = ynv . Indices [ tid + 2 ] ;
if ( ( ind1 > = vc ) | | ( ind2 > = vc ) )
{ continue ; }
Vector3 p1 = ynv . Vertices [ ind1 ] ;
Vector3 p2 = ynv . Vertices [ ind2 ] ;
if ( mray . Intersects ( ref p0 , ref p1 , ref p2 , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
{
var cellaabb = poly . _RawData . CellAABB ;
CurMouseHit . NavPoly = poly ;
2018-03-12 01:42:20 +08:00
CurMouseHit . NavPoint = null ;
CurMouseHit . NavPortal = null ;
2017-09-21 18:33:05 +08:00
CurMouseHit . HitDist = hitdist ;
CurMouseHit . AABB = new BoundingBox ( cellaabb . Min , cellaabb . Max ) ;
break ; //no need to test further tris in this poly
}
}
}
}
}
}
private void UpdateMouseHits ( List < YndFile > ynds )
{
if ( SelectionMode ! = MapSelectionMode . Path ) return ;
Ray mray = new Ray ( ) ;
mray . Position = camera . MouseRay . Position + camera . Position ;
mray . Direction = camera . MouseRay . Direction ;
foreach ( var ynd in ynds )
{
if ( renderpathbounds )
{
float minz = ( ynd . BVH ! = null ) ? ynd . BVH . Box . Minimum . Z : 0.0f ;
float maxz = ( ynd . BVH ! = null ) ? ynd . BVH . Box . Maximum . Z : 0.0f ;
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = - camera . Position ;
mb . BBMin = new Vector3 ( ynd . BBMin . X , ynd . BBMin . Y , minz ) ;
mb . BBMax = new Vector3 ( ynd . BBMax . X , ynd . BBMax . Y , maxz ) ;
mb . Orientation = Quaternion . Identity ;
mb . Scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
if ( ynd . BVH ! = null )
{
UpdateMouseHits ( ynd . BVH , ref mray ) ;
}
}
if ( SelectedItem . PathNode ! = null )
{
float linkrad = 0.25f ;
var n = SelectedItem . PathNode ;
if ( n . Links ! = null )
{
foreach ( var ln in n . Links )
{
if ( ln . Node2 = = null ) continue ; //invalid links can hit here...
Vector3 dv = n . Position - ln . Node2 . Position ;
float dl = dv . Length ( ) ;
Vector3 dir = dv * ( 1.0f / dl ) ;
Vector3 dup = Vector3 . UnitZ ;
MapBox mb = new MapBox ( ) ;
int lanestot = ln . LaneCountForward + ln . LaneCountBackward ;
2023-09-04 18:48:50 +08:00
float lanewidth = ln . GetLaneWidth ( ) ;
2017-09-21 18:33:05 +08:00
float inner = ln . LaneOffset * lanewidth ; // 0.0f;
float outer = inner + Math . Max ( lanewidth * ln . LaneCountForward , 0.5f ) ;
float totwidth = lanestot * lanewidth ;
float halfwidth = totwidth * 0.5f ;
if ( ln . LaneCountBackward = = 0 )
{
inner - = halfwidth ;
outer - = halfwidth ;
}
if ( ln . LaneCountForward = = 0 )
{
inner + = halfwidth ;
outer + = halfwidth ;
}
mb . CamRelPos = n . Position - camera . Position ;
mb . BBMin = new Vector3 ( - linkrad - outer , - linkrad , 0.0f ) ;
mb . BBMax = new Vector3 ( linkrad - inner , linkrad , dl ) ;
mb . Orientation = Quaternion . Invert ( Quaternion . RotationLookAtRH ( dir , dup ) ) ;
mb . Scale = Vector3 . One ;
if ( ln = = SelectedItem . PathLink )
{
2018-01-02 04:52:54 +08:00
Renderer . HilightBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
else
{
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
}
}
}
}
private void UpdateMouseHits ( List < TrainTrack > tracks )
{
if ( SelectionMode ! = MapSelectionMode . TrainTrack ) return ;
Ray mray = new Ray ( ) ;
mray . Position = camera . MouseRay . Position + camera . Position ;
mray . Direction = camera . MouseRay . Direction ;
foreach ( var track in tracks )
{
if ( renderpathbounds )
{
//MapBox mb = new MapBox();
//mb.CamRelPos = -camera.Position;
//mb.BBMin = track.BVH?.Box.Minimum ?? Vector3.Zero;
//mb.BBMax = track.BVH?.Box.Maximum ?? Vector3.Zero;
//mb.Orientation = Quaternion.Identity;
//mb.Scale = Vector3.One;
//BoundingBoxes.Add(mb);
}
if ( track . BVH ! = null )
{
UpdateMouseHits ( track . BVH , ref mray ) ;
}
}
if ( SelectedItem . TrainTrackNode ! = null )
{
float linkrad = 0.25f ;
var n = SelectedItem . TrainTrackNode ;
if ( n . Links ! = null )
{
foreach ( var ln in n . Links )
{
if ( ln = = null ) continue ;
Vector3 dv = n . Position - ln . Position ;
float dl = dv . Length ( ) ;
Vector3 dir = dv * ( 1.0f / dl ) ;
Vector3 dup = Vector3 . UnitZ ;
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = n . Position - camera . Position ;
mb . BBMin = new Vector3 ( - linkrad , - linkrad , 0.0f ) ;
mb . BBMax = new Vector3 ( linkrad , linkrad , dl ) ;
mb . Orientation = Quaternion . Invert ( Quaternion . RotationLookAtRH ( dir , dup ) ) ;
mb . Scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
}
}
}
private void UpdateMouseHits ( List < YmtFile > scenarios )
{
if ( SelectionMode ! = MapSelectionMode . Scenario ) return ;
Ray mray = new Ray ( ) ;
mray . Position = camera . MouseRay . Position + camera . Position ;
mray . Direction = camera . MouseRay . Direction ;
foreach ( var scenario in scenarios )
{
var sr = scenario . ScenarioRegion ;
if ( sr = = null ) continue ;
if ( renderscenariobounds )
{
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = - camera . Position ;
mb . BBMin = sr ? . BVH ? . Box . Minimum ? ? Vector3 . Zero ;
mb . BBMax = sr ? . BVH ? . Box . Maximum ? ? Vector3 . Zero ;
mb . Orientation = Quaternion . Identity ;
mb . Scale = Vector3 . One ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
if ( sr . BVH ! = null )
{
UpdateMouseHits ( sr . BVH , ref mray ) ;
}
}
if ( SelectedItem . ScenarioNode ! = null ) //move this stuff to renderselection..?
{
var n = SelectedItem . ScenarioNode ;
var nc = n . ChainingNode ? . Chain ;
var ncl = n . Cluster ;
//float linkrad = 0.25f;
//if (n.Links != null)
//{
// foreach (var ln in n.Links)
// {
// if (ln == null) continue;
// Vector3 dv = n.Position - ln.Position;
// float dl = dv.Length();
// Vector3 dir = dv * (1.0f / dl);
// Vector3 dup = Vector3.UnitZ;
// MapBox mb = new MapBox();
// mb.CamRelPos = n.Position - camera.Position;
// mb.BBMin = new Vector3(-linkrad, -linkrad, 0.0f);
// mb.BBMax = new Vector3(linkrad, linkrad, dl);
// mb.Orientation = Quaternion.Invert(Quaternion.RotationLookAtRH(dir, dup));
// mb.Scale = Vector3.One;
// BoundingBoxes.Add(mb);
// }
//}
var sr = SelectedItem . ScenarioNode . Ymt . ScenarioRegion ;
//if (renderscenariobounds)
{
MapBox mb = new MapBox ( ) ;
mb . CamRelPos = - camera . Position ;
mb . BBMin = sr ? . BVH ? . Box . Minimum ? ? Vector3 . Zero ;
mb . BBMax = sr ? . BVH ? . Box . Maximum ? ? Vector3 . Zero ;
mb . Orientation = Quaternion . Identity ;
mb . Scale = Vector3 . One ;
if ( renderscenariobounds )
{
2018-01-02 04:52:54 +08:00
Renderer . HilightBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
else
{
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
}
if ( ncl ! = null )
{
//hilight the cluster itself
MapBox mb = new MapBox ( ) ;
mb . Scale = Vector3 . One ;
mb . BBMin = new Vector3 ( - 0.5f ) ;
mb . BBMax = new Vector3 ( 0.5f ) ;
mb . CamRelPos = ncl . Position - camera . Position ;
mb . Orientation = Quaternion . Identity ;
2018-01-02 04:52:54 +08:00
Renderer . HilightBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
//show boxes for points in the cluster
if ( ( ncl . Points ! = null ) & & ( ncl . Points . MyPoints ! = null ) )
{
foreach ( var clpoint in ncl . Points . MyPoints )
{
if ( clpoint = = n . ClusterMyPoint ) continue ; //don't highlight the selected node...
mb = new MapBox ( ) ;
mb . Scale = Vector3 . One ;
mb . BBMin = new Vector3 ( - 0.5f ) ;
mb . BBMax = new Vector3 ( 0.5f ) ;
mb . CamRelPos = clpoint . Position - camera . Position ;
mb . Orientation = clpoint . Orientation ;
2018-01-02 04:52:54 +08:00
Renderer . BoundingBoxes . Add ( mb ) ;
2017-09-21 18:33:05 +08:00
}
}
}
}
}
private void UpdateMouseHits ( PathBVHNode pathbvhnode , ref Ray mray )
{
float nrad = 0.5f ;
float hitdist = float . MaxValue ;
BoundingSphere bsph = new BoundingSphere ( ) ;
bsph . Radius = nrad ;
BoundingBox bbox = new BoundingBox ( ) ;
bbox . Minimum = pathbvhnode . Box . Minimum - nrad ;
bbox . Maximum = pathbvhnode . Box . Maximum + nrad ;
BoundingBox nbox = new BoundingBox ( ) ;
nbox . Minimum = new Vector3 ( - nrad ) ;
nbox . Maximum = new Vector3 ( nrad ) ;
float fhd ;
if ( mray . Intersects ( ref bbox , out fhd ) ) //ray intersects this node... check children for hits!
{
if ( ( pathbvhnode . Node1 ! = null ) & & ( pathbvhnode . Node2 ! = null ) ) //node is split. recurse
{
UpdateMouseHits ( pathbvhnode . Node1 , ref mray ) ;
UpdateMouseHits ( pathbvhnode . Node2 , ref mray ) ;
}
else if ( pathbvhnode . Nodes ! = null ) //leaf node. test contaned pathnodes
{
foreach ( var n in pathbvhnode . Nodes )
{
bsph . Center = n . Position ;
if ( mray . Intersects ( ref bsph , out hitdist ) & & ( hitdist < CurMouseHit . HitDist ) & & ( hitdist > 0 ) )
{
CurMouseHit . PathNode = n as YndNode ;
CurMouseHit . TrainTrackNode = n as TrainTrackNode ;
CurMouseHit . ScenarioNode = n as ScenarioNode ;
2021-04-22 13:16:11 +08:00
CurMouseHit . LodLight = n as YmapLODLight ;
2018-03-12 01:42:20 +08:00
CurMouseHit . NavPoint = n as YnvPoint ;
CurMouseHit . NavPortal = n as YnvPortal ;
CurMouseHit . NavPoly = null ;
2017-09-21 18:33:05 +08:00
CurMouseHit . HitDist = hitdist ;
CurMouseHit . CamRel = ( n . Position - camera . Position ) ;
CurMouseHit . AABB = nbox ;
}
}
}
}
}
2020-01-15 14:48:27 +08:00
public void SelectObject ( object obj , object parent = null , bool addSelection = false )
2020-01-12 16:25:41 +08:00
{
if ( obj = = null )
{
SelectItem ( null , addSelection ) ;
return ;
}
if ( obj is object [ ] arr )
{
SelectItem ( null , addSelection ) ;
foreach ( var mobj in arr )
{
2020-01-15 14:48:27 +08:00
SelectObject ( mobj , null , true ) ;
2020-01-12 16:25:41 +08:00
}
if ( ! addSelection )
{
UpdateSelectionUI ( true ) ;
}
if ( ( ProjectForm ! = null ) & & ! addSelection )
{
ProjectForm . OnWorldSelectionChanged ( SelectedItem ) ;
}
}
2020-01-15 14:48:27 +08:00
else
{
2023-09-04 18:48:50 +08:00
var ms = MapSelection . FromProjectObject ( this , obj , parent ) ;
2020-01-15 14:48:27 +08:00
if ( ! ms . HasValue )
{
SelectItem ( null , addSelection ) ;
}
else
{
SelectItem ( ms , addSelection ) ;
}
}
2020-01-12 16:25:41 +08:00
}
2020-01-15 16:00:19 +08:00
public void SelectItem ( MapSelection ? mhit = null , bool addSelection = false , bool manualSelection = false , bool notifyProject = true )
2017-09-21 18:33:05 +08:00
{
2017-09-26 08:27:18 +08:00
var mhitv = mhit . HasValue ? mhit . Value : new MapSelection ( ) ;
if ( mhit ! = null )
2017-09-21 18:33:05 +08:00
{
2017-09-26 08:27:18 +08:00
if ( ( mhitv . Archetype = = null ) & & ( mhitv . EntityDef ! = null ) )
{
mhitv . Archetype = mhitv . EntityDef . Archetype ; //use the entity archetype if no archetype given
}
if ( mhitv . GrassBatch ! = null )
{
mhitv . Archetype = mhitv . GrassBatch . Archetype ;
}
2017-09-21 18:33:05 +08:00
}
2017-09-26 08:27:18 +08:00
if ( ( mhitv . Archetype ! = null ) & & ( mhitv . Drawable = = null ) )
{
2018-01-02 04:52:54 +08:00
mhitv . Drawable = gameFileCache . TryGetDrawable ( mhitv . Archetype ) ; //no drawable given.. try to get it from the cache.. if it's not there, drawable info won't display...
2017-09-26 08:27:18 +08:00
}
2023-09-04 18:48:50 +08:00
var oldnode = SelectedItem . PathNode ;
2017-09-26 08:27:18 +08:00
bool change = false ;
2017-09-21 18:33:05 +08:00
if ( mhit ! = null )
{
2017-09-26 08:27:18 +08:00
change = SelectedItem . CheckForChanges ( mhitv ) ;
}
else
{
change = SelectedItem . CheckForChanges ( ) ;
}
if ( addSelection )
{
2020-01-08 21:44:35 +08:00
var items = new List < MapSelection > ( ) ;
if ( SelectedItem . MultipleSelectionItems ! = null )
2017-09-26 08:27:18 +08:00
{
2020-01-08 21:44:35 +08:00
items . AddRange ( SelectedItem . MultipleSelectionItems ) ;
2017-09-26 08:27:18 +08:00
if ( mhitv . HasValue ) //incoming selection isn't empty...
{
//search the list for a match, remove it if already there, otherwise add it.
bool found = false ;
2020-01-08 21:44:35 +08:00
foreach ( var item in items )
2017-09-26 08:27:18 +08:00
{
if ( ! item . CheckForChanges ( mhitv ) )
{
2020-01-08 21:44:35 +08:00
items . Remove ( item ) ;
2017-09-26 08:27:18 +08:00
found = true ;
break ;
}
}
if ( found )
{
2020-01-08 21:44:35 +08:00
if ( items . Count = = 1 )
2017-09-26 08:27:18 +08:00
{
2020-01-08 21:44:35 +08:00
mhitv = items [ 0 ] ;
items . Clear ( ) ;
2017-09-26 08:27:18 +08:00
}
2020-01-08 21:44:35 +08:00
else if ( items . Count < = 0 )
2017-09-26 08:27:18 +08:00
{
mhitv . Clear ( ) ;
2020-01-08 21:44:35 +08:00
items . Clear ( ) ; //this shouldn't really happen..
2017-09-26 08:27:18 +08:00
}
2020-01-09 23:12:16 +08:00
mhitv . SetMultipleSelectionItems ( items . ToArray ( ) ) ;
2017-09-26 08:27:18 +08:00
}
else
{
2020-01-09 23:12:16 +08:00
mhitv . SetMultipleSelectionItems ( null ) ;
2020-01-08 21:44:35 +08:00
items . Add ( mhitv ) ;
2017-09-26 08:27:18 +08:00
}
change = true ;
}
else //empty incoming value... do nothing?
{
return ;
}
}
else //current selection is single item, or empty
{
if ( change ) //incoming selection item is different from the current one
{
if ( mhitv . HasValue ) //incoming selection isn't empty, add it to the list
{
if ( SelectedItem . HasValue ) //add the existing item to the selection list, if it's not empty
{
2020-01-09 23:12:16 +08:00
mhitv . SetMultipleSelectionItems ( null ) ;
SelectedItem . SetMultipleSelectionItems ( null ) ;
2020-01-08 21:44:35 +08:00
items . Add ( SelectedItem ) ;
items . Add ( mhitv ) ;
2020-01-09 23:12:16 +08:00
SelectedItem . SetMultipleSelectionItems ( items . ToArray ( ) ) ;
2017-09-26 08:27:18 +08:00
}
}
else //empty incoming value... do nothing?
{
return ;
}
}
else //same thing was selected a 2nd time, just clear the selection.
{
SelectedItem . Clear ( ) ;
mhit = null ; //dont's wants to selects it agains!
change = true ;
}
}
2020-01-08 21:44:35 +08:00
if ( items . Count > 1 )
2017-09-26 08:27:18 +08:00
{
//iterate the selected items, and calculate the selection position
mhitv . Clear ( ) ;
2020-01-09 23:12:16 +08:00
mhitv . SetMultipleSelectionItems ( items . ToArray ( ) ) ;
2017-09-26 08:27:18 +08:00
}
2017-09-21 18:33:05 +08:00
}
else
{
2020-01-08 21:44:35 +08:00
if ( SelectedItem . MultipleSelectionItems ! = null )
2017-09-26 08:27:18 +08:00
{
change = true ;
SelectedItem . Clear ( ) ;
}
2017-09-21 18:33:05 +08:00
}
if ( ! change )
{
if ( mhit . HasValue )
{
//make sure the path link gets changed (sub-selection!)
2018-12-16 21:07:20 +08:00
//lock (Renderer.RenderSyncRoot)
2017-09-21 18:33:05 +08:00
{
2017-09-26 08:27:18 +08:00
SelectedItem . PathLink = mhitv . PathLink ;
SelectedItem . ScenarioEdge = mhitv . ScenarioEdge ;
2017-09-21 18:33:05 +08:00
}
}
return ;
}
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot ) //drawflags is used when rendering.. need that lock
2017-09-21 18:33:05 +08:00
{
if ( mhit . HasValue )
{
2017-09-26 08:27:18 +08:00
SelectedItem = mhitv ;
2017-09-21 18:33:05 +08:00
}
else
{
SelectedItem . Clear ( ) ;
}
if ( change )
{
2020-01-12 16:25:41 +08:00
if ( ! addSelection )
{
UpdateSelectionUI ( true ) ;
}
2017-09-21 18:33:05 +08:00
2017-09-26 08:27:18 +08:00
Widget . Visible = SelectedItem . CanShowWidget ;
if ( Widget . Visible )
2017-09-21 18:33:05 +08:00
{
2017-09-26 08:27:18 +08:00
Widget . Position = SelectedItem . WidgetPosition ;
Widget . Rotation = SelectedItem . WidgetRotation ;
Widget . RotationWidget . EnableAxes = SelectedItem . WidgetRotationAxes ;
2020-01-07 22:02:51 +08:00
Widget . ScaleWidget . LockXY = SelectedItem . WidgetScaleLockXY ;
2017-09-26 08:27:18 +08:00
Widget . Scale = SelectedItem . WidgetScale ;
2017-09-21 18:33:05 +08:00
}
}
}
2020-01-15 16:00:19 +08:00
if ( notifyProject & & change & & ( ProjectForm ! = null ) & & ( ! addSelection | | manualSelection ) )
2017-09-21 18:33:05 +08:00
{
ProjectForm . OnWorldSelectionChanged ( SelectedItem ) ;
}
2023-09-04 18:48:50 +08:00
var newnode = SelectedItem . PathNode ;
if ( newnode ! = oldnode ) //this is to allow junction heightmaps to be displayed when selecting a junction node
{
UpdatePathYndGraphics ( oldnode ? . Ynd , false ) ;
UpdatePathYndGraphics ( newnode ? . Ynd , false ) ;
}
if ( change )
{
// If an item has been selected the user is likely to use a keybind. We need focus!
2024-07-27 11:40:12 +08:00
//Focus();//DISABLED THIS due to causing problems with using arrows to select in project window!
2023-09-04 18:48:50 +08:00
}
2017-09-21 18:33:05 +08:00
}
2020-01-15 16:00:19 +08:00
public void SelectMulti ( MapSelection [ ] items , bool addSelection = false , bool notifyProject = true )
2017-09-26 08:27:18 +08:00
{
2020-01-15 16:00:19 +08:00
SelectItem ( null , addSelection , false , notifyProject ) ;
2017-09-26 08:27:18 +08:00
if ( items ! = null )
{
foreach ( var item in items )
{
2020-01-15 16:00:19 +08:00
SelectItem ( item , true , false , notifyProject ) ;
2017-09-26 08:27:18 +08:00
}
2020-01-12 16:25:41 +08:00
if ( ! addSelection )
{
UpdateSelectionUI ( true ) ;
}
2020-01-15 16:00:19 +08:00
if ( notifyProject & & ( ProjectForm ! = null ) & & ! addSelection )
2020-01-12 16:25:41 +08:00
{
ProjectForm . OnWorldSelectionChanged ( SelectedItem ) ;
}
2017-09-26 08:27:18 +08:00
}
}
2017-09-21 18:33:05 +08:00
private void SelectMousedItem ( )
{
//when clicked, select the currently moused item and update the selection info UI
if ( ! MouseSelectEnabled )
{ return ; }
2020-01-14 14:56:11 +08:00
SelectItem ( LastMouseHit , Input . CtrlPressed , true ) ;
2017-09-21 18:33:05 +08:00
}
private void UpdateSelectionUI ( bool wait )
{
try
{
if ( InvokeRequired )
{
if ( wait )
{
Invoke ( new Action ( ( ) = > { UpdateSelectionUI ( wait ) ; } ) ) ;
}
else
{
BeginInvoke ( new Action ( ( ) = > { UpdateSelectionUI ( wait ) ; } ) ) ;
}
}
else
{
SetSelectionUI ( SelectedItem ) ;
if ( InfoForm ! = null )
{
2020-01-08 21:44:35 +08:00
InfoForm . SetSelection ( SelectedItem ) ;
2017-09-21 18:33:05 +08:00
}
}
}
catch { }
}
private void SetSelectionUI ( MapSelection item )
{
SelectionNameTextBox . Text = item . GetNameString ( "Nothing selected" ) ;
//SelEntityPropertyGrid.SelectedObject = item.EntityDef;
SelArchetypePropertyGrid . SelectedObject = item . Archetype ;
SelDrawablePropertyGrid . SelectedObject = item . Drawable ;
2018-01-02 04:52:54 +08:00
Renderer . SelectionModelDrawFlags . Clear ( ) ;
Renderer . SelectionGeometryDrawFlags . Clear ( ) ;
2017-09-21 18:33:05 +08:00
SelDrawableModelsTreeView . Nodes . Clear ( ) ;
SelDrawableTexturesTreeView . Nodes . Clear ( ) ;
if ( item . Drawable ! = null )
{
2020-03-14 19:23:40 +08:00
AddSelectionDrawableModelsTreeNodes ( item . Drawable . DrawableModels ? . High , "High Detail" , true ) ;
AddSelectionDrawableModelsTreeNodes ( item . Drawable . DrawableModels ? . Med , "Medium Detail" , false ) ;
AddSelectionDrawableModelsTreeNodes ( item . Drawable . DrawableModels ? . Low , "Low Detail" , false ) ;
AddSelectionDrawableModelsTreeNodes ( item . Drawable . DrawableModels ? . VLow , "Very Low Detail" , false ) ;
//AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModels?.Extra, "X Detail", false);
2017-09-21 18:33:05 +08:00
}
YmapFile ymap = null ;
YnvFile ynv = null ;
YndFile ynd = null ;
TrainTrack traintr = null ;
YmtFile scenario = null ;
2018-03-16 21:16:57 +08:00
RelFile audiofile = null ;
2017-09-21 18:33:05 +08:00
ToolbarCopyButton . Enabled = false ;
ToolbarDeleteItemButton . Enabled = false ;
ToolbarDeleteItemButton . Text = "Delete" ;
2020-01-12 16:25:41 +08:00
ToolbarAddItemButton . ToolTipText = "Add" ;
ToolbarAddItemButton . Enabled = false ;
ToolbarPasteButton . Enabled = CopiedItem . CanCopyPaste ;
2017-09-21 18:33:05 +08:00
2020-01-08 21:44:35 +08:00
if ( item . MultipleSelectionItems ! = null )
2017-09-26 08:27:18 +08:00
{
SelectionEntityTabPage . Text = "Multiple items" ;
2020-01-08 21:44:35 +08:00
SelEntityPropertyGrid . SelectedObject = item . MultipleSelectionItems ;
2020-01-12 16:25:41 +08:00
ToolbarCopyButton . Enabled = item . CanCopyPaste ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete multiple items" ;
2017-09-26 08:27:18 +08:00
}
else if ( item . TimeCycleModifier ! = null )
2017-09-21 18:33:05 +08:00
{
SelectionEntityTabPage . Text = "TCMod" ;
SelEntityPropertyGrid . SelectedObject = item . TimeCycleModifier ;
}
else if ( item . CarGenerator ! = null )
{
SelectionEntityTabPage . Text = "CarGen" ;
SelEntityPropertyGrid . SelectedObject = item . CarGenerator ;
ymap = item . CarGenerator . Ymap ;
ToolbarCopyButton . Enabled = true ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete car generator" ;
}
2021-04-22 13:16:11 +08:00
else if ( item . LodLight ! = null )
2017-09-21 18:33:05 +08:00
{
2021-04-22 13:16:11 +08:00
SelectionEntityTabPage . Text = "LodLight" ;
SelEntityPropertyGrid . SelectedObject = item . LodLight ;
2021-04-26 02:41:02 +08:00
ymap = item . LodLight . Ymap ;
ToolbarCopyButton . Enabled = true ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete LOD light" ;
2017-09-21 18:33:05 +08:00
}
else if ( item . GrassBatch ! = null )
{
SelectionEntityTabPage . Text = "Grass" ;
SelEntityPropertyGrid . SelectedObject = item . GrassBatch ;
}
2018-12-14 22:46:48 +08:00
else if ( item . BoxOccluder ! = null )
{
2021-04-30 00:15:23 +08:00
SelectionEntityTabPage . Text = "BoxOccluder" ;
2018-12-14 22:46:48 +08:00
SelEntityPropertyGrid . SelectedObject = item . BoxOccluder ;
2021-04-30 00:15:23 +08:00
ymap = item . BoxOccluder . Ymap ;
ToolbarCopyButton . Enabled = true ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete Box Occluder" ;
2018-12-14 22:46:48 +08:00
}
2021-04-30 00:15:23 +08:00
else if ( item . OccludeModelTri ! = null )
2018-12-14 22:46:48 +08:00
{
2021-04-30 00:15:23 +08:00
SelectionEntityTabPage . Text = "OccludeTriangle" ;
SelEntityPropertyGrid . SelectedObject = item . OccludeModelTri ;
ymap = item . OccludeModelTri . Ymap ;
ToolbarCopyButton . Enabled = true ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete Occlude Model Triangle" ;
2018-12-14 22:46:48 +08:00
}
2017-09-21 18:33:05 +08:00
else if ( item . WaterQuad ! = null )
{
SelectionEntityTabPage . Text = "WaterQuad" ;
SelEntityPropertyGrid . SelectedObject = item . WaterQuad ;
}
2021-12-02 16:15:12 +08:00
else if ( item . CalmingQuad ! = null )
{
SelectionEntityTabPage . Text = "CalmingQuad" ;
SelEntityPropertyGrid . SelectedObject = item . CalmingQuad ;
}
else if ( item . WaveQuad ! = null )
{
SelectionEntityTabPage . Text = "WaveQuad" ;
SelEntityPropertyGrid . SelectedObject = item . WaveQuad ;
}
2017-09-21 18:33:05 +08:00
else if ( item . PathNode ! = null )
{
SelectionEntityTabPage . Text = "PathNode" ;
SelEntityPropertyGrid . SelectedObject = item . PathNode ;
ynd = item . PathNode . Ynd ;
ToolbarCopyButton . Enabled = true ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete path node" ;
}
else if ( item . NavPoly ! = null )
{
SelectionEntityTabPage . Text = "NavPoly" ;
SelEntityPropertyGrid . SelectedObject = item . NavPoly ;
ynv = item . NavPoly . Ynv ;
//ToolbarCopyButton.Enabled = true;
//ToolbarDeleteItemButton.Enabled = true;
//ToolbarDeleteItemButton.Text = "Delete nav poly";
}
2018-03-12 01:42:20 +08:00
else if ( item . NavPoint ! = null )
{
SelectionEntityTabPage . Text = "NavPoint" ;
SelEntityPropertyGrid . SelectedObject = item . NavPoint ;
ynv = item . NavPoint . Ynv ;
//ToolbarCopyButton.Enabled = true;
//ToolbarDeleteItemButton.Enabled = true;
//ToolbarDeleteItemButton.Text = "Delete nav point";
}
else if ( item . NavPortal ! = null )
{
SelectionEntityTabPage . Text = "NavPortal" ;
SelEntityPropertyGrid . SelectedObject = item . NavPortal ;
ynv = item . NavPortal . Ynv ;
//ToolbarCopyButton.Enabled = true;
//ToolbarDeleteItemButton.Enabled = true;
//ToolbarDeleteItemButton.Text = "Delete nav portal";
}
2017-09-21 18:33:05 +08:00
else if ( item . TrainTrackNode ! = null )
{
SelectionEntityTabPage . Text = "TrainNode" ;
SelEntityPropertyGrid . SelectedObject = item . TrainTrackNode ;
traintr = item . TrainTrackNode . Track ;
ToolbarCopyButton . Enabled = true ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete train track node" ;
}
else if ( item . ScenarioNode ! = null )
{
SelectionEntityTabPage . Text = item . ScenarioNode . ShortTypeName ;
SelEntityPropertyGrid . SelectedObject = item . ScenarioNode ;
scenario = item . ScenarioNode . Ymt ;
ToolbarCopyButton . Enabled = true ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete scenario point" ;
}
2017-12-22 04:26:04 +08:00
else if ( item . Audio ! = null )
{
SelectionEntityTabPage . Text = item . Audio . ShortTypeName ;
SelEntityPropertyGrid . SelectedObject = item . Audio ;
2018-03-16 21:16:57 +08:00
audiofile = item . Audio . RelFile ;
2017-12-22 04:26:04 +08:00
}
2017-09-21 18:33:05 +08:00
else
{
SelectionEntityTabPage . Text = "Entity" ;
SelEntityPropertyGrid . SelectedObject = item . EntityDef ;
if ( item . EntityDef ! = null )
{
ymap = item . EntityDef ? . Ymap ;
ToolbarCopyButton . Enabled = true ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete entity" ;
}
}
if ( item . EntityExtension ! = null )
{
SelExtensionPropertyGrid . SelectedObject = item . EntityExtension ;
ShowSelectedExtensionTab ( true ) ;
}
else if ( item . ArchetypeExtension ! = null )
{
SelExtensionPropertyGrid . SelectedObject = item . ArchetypeExtension ;
ShowSelectedExtensionTab ( true ) ;
}
2020-01-11 16:20:14 +08:00
else if ( item . CollisionVertex ! = null )
{
SelExtensionPropertyGrid . SelectedObject = item . CollisionVertex ;
ShowSelectedExtensionTab ( true , "Coll" ) ;
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete collision vertex" ;
}
2019-12-31 21:00:04 +08:00
else if ( item . CollisionPoly ! = null )
{
SelExtensionPropertyGrid . SelectedObject = item . CollisionPoly ;
ShowSelectedExtensionTab ( true , "Coll" ) ;
2020-01-11 16:20:14 +08:00
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete collision poly" ;
2019-12-31 21:00:04 +08:00
}
2017-09-21 18:33:05 +08:00
else if ( item . CollisionBounds ! = null )
{
SelExtensionPropertyGrid . SelectedObject = item . CollisionBounds ;
ShowSelectedExtensionTab ( true , "Coll" ) ;
2020-01-11 16:20:14 +08:00
ToolbarDeleteItemButton . Enabled = true ;
ToolbarDeleteItemButton . Text = "Delete collision bounds" ;
2017-09-21 18:33:05 +08:00
}
else
{
SelExtensionPropertyGrid . SelectedObject = null ;
ShowSelectedExtensionTab ( false ) ;
}
2020-01-12 16:25:41 +08:00
if ( ymap ! = null )
{
EnableYmapUI ( true , ymap . Name ) ;
}
2017-09-21 18:33:05 +08:00
if ( ynd ! = null )
{
EnableYndUI ( true , ynd . Name ) ;
}
if ( ynv ! = null )
{
EnableYnvUI ( true , ynv . Name ) ;
}
if ( traintr ! = null )
{
EnableTrainsUI ( true , traintr . Name ) ;
}
if ( scenario ! = null )
{
EnableScenarioUI ( true , scenario . Name ) ;
}
2018-03-16 21:16:57 +08:00
if ( audiofile ! = null )
{
EnableAudioUI ( true , audiofile . Name ) ;
}
2017-09-21 18:33:05 +08:00
}
private void ShowSelectedExtensionTab ( bool show , string text = "Ext" )
{
SelectionExtensionTabPage . Text = text ;
if ( show )
{
if ( ! SelectionTabControl . TabPages . Contains ( SelectionExtensionTabPage ) )
{
SelectionTabControl . TabPages . Add ( SelectionExtensionTabPage ) ;
SelectionTabControl . SelectedTab = SelectionExtensionTabPage ;
}
}
else
{
if ( SelectionTabControl . TabPages . Contains ( SelectionExtensionTabPage ) )
{
SelectionTabControl . TabPages . Remove ( SelectionExtensionTabPage ) ;
}
}
}
2020-03-14 19:23:40 +08:00
private void AddSelectionDrawableModelsTreeNodes ( DrawableModel [ ] models , string prefix , bool check )
2017-09-21 18:33:05 +08:00
{
if ( models = = null ) return ;
2020-03-14 19:23:40 +08:00
for ( int mi = 0 ; mi < models . Length ; mi + + )
2017-09-21 18:33:05 +08:00
{
2020-03-14 19:23:40 +08:00
var model = models [ mi ] ;
2017-09-21 18:33:05 +08:00
string mprefix = prefix + " " + ( mi + 1 ) . ToString ( ) ;
var mnode = SelDrawableModelsTreeView . Nodes . Add ( mprefix + " " + model . ToString ( ) ) ;
mnode . Tag = model ;
mnode . Checked = check ;
var tmnode = SelDrawableTexturesTreeView . Nodes . Add ( mprefix + " " + model . ToString ( ) ) ;
tmnode . Tag = model ;
if ( ! check )
{
2018-01-02 04:52:54 +08:00
Renderer . SelectionModelDrawFlags [ model ] = false ;
2017-09-21 18:33:05 +08:00
}
2020-03-13 22:30:56 +08:00
if ( model . Geometries = = null ) continue ;
2017-09-21 18:33:05 +08:00
2020-03-13 22:30:56 +08:00
foreach ( var geom in model . Geometries )
2017-09-21 18:33:05 +08:00
{
var gname = geom . ToString ( ) ;
var gnode = mnode . Nodes . Add ( gname ) ;
gnode . Tag = geom ;
gnode . Checked = true ; // check;
var tgnode = tmnode . Nodes . Add ( gname ) ;
tgnode . Tag = geom ;
if ( ( geom . Shader ! = null ) & & ( geom . Shader . ParametersList ! = null ) & & ( geom . Shader . ParametersList . Hashes ! = null ) )
{
var pl = geom . Shader . ParametersList ;
var h = pl . Hashes ;
var p = pl . Parameters ;
for ( int ip = 0 ; ip < h . Length ; ip + + )
{
var hash = pl . Hashes [ ip ] ;
var parm = pl . Parameters [ ip ] ;
var tex = parm . Data as TextureBase ;
if ( tex ! = null )
{
var t = tex as Texture ;
var tstr = tex . Name . Trim ( ) ;
if ( t ! = null )
{
tstr = string . Format ( "{0} ({1}x{2}, embedded)" , tex . Name , t . Width , t . Height ) ;
}
var tnode = tgnode . Nodes . Add ( hash . ToString ( ) . Trim ( ) + ": " + tstr ) ;
tnode . Tag = tex ;
}
}
tgnode . Expand ( ) ;
}
}
mnode . Expand ( ) ;
tmnode . Expand ( ) ;
}
}
private void UpdateSelectionDrawFlags ( TreeNode node )
{
//update the selection draw flags depending on tag and checked/unchecked
var model = node . Tag as DrawableModel ;
var geom = node . Tag as DrawableGeometry ;
bool rem = node . Checked ;
2018-01-02 04:52:54 +08:00
Renderer . UpdateSelectionDrawFlags ( model , geom , rem ) ;
2017-09-21 18:33:05 +08:00
}
public void SyncSelDrawableModelsTreeNode ( TreeNode node )
{
//called by the info form when a selection treeview node is checked/unchecked.
foreach ( TreeNode mnode in SelDrawableModelsTreeView . Nodes )
{
if ( mnode . Tag = = node . Tag )
{
if ( mnode . Checked ! = node . Checked )
{
mnode . Checked = node . Checked ;
}
}
foreach ( TreeNode gnode in mnode . Nodes )
{
if ( gnode . Tag = = node . Tag )
{
if ( gnode . Checked ! = node . Checked )
{
gnode . Checked = node . Checked ;
}
}
}
}
}
private void ShowInfoForm ( )
{
if ( InfoForm = = null )
{
InfoForm = new WorldInfoForm ( this ) ;
2020-01-08 21:44:35 +08:00
InfoForm . SetSelection ( SelectedItem ) ;
2017-09-21 18:33:05 +08:00
InfoForm . SetSelectionMode ( SelectionModeStr , MouseSelectEnabled ) ;
InfoForm . Show ( this ) ;
}
else
{
if ( InfoForm . WindowState = = FormWindowState . Minimized )
{
InfoForm . WindowState = FormWindowState . Normal ;
}
InfoForm . Focus ( ) ;
}
ToolbarInfoWindowButton . Checked = true ;
}
public void OnInfoFormSelectionModeChanged ( string mode , bool enableSelect )
{
//called by the WorldInfoForm
SetSelectionMode ( mode ) ;
SetMouseSelect ( enableSelect ) ;
}
public void OnInfoFormClosed ( )
{
//called by the WorldInfoForm when it's closed.
InfoForm = null ;
ToolbarInfoWindowButton . Checked = false ;
}
private void ShowProjectForm ( )
{
if ( ProjectForm = = null )
{
2018-03-03 21:09:31 +08:00
ProjectForm = new ProjectForm ( this ) ;
2017-09-21 18:33:05 +08:00
ProjectForm . Show ( this ) ;
2018-12-03 16:54:04 +08:00
ProjectForm . OnWorldSelectionChanged ( SelectedItem ) ; // so that the project form isn't stuck on the welcome window.
2017-09-21 18:33:05 +08:00
}
else
{
if ( ProjectForm . WindowState = = FormWindowState . Minimized )
{
ProjectForm . WindowState = FormWindowState . Normal ;
}
ProjectForm . Focus ( ) ;
}
ToolbarProjectWindowButton . Checked = true ;
}
public void OnProjectFormClosed ( )
{
ProjectForm = null ;
ToolbarProjectWindowButton . Checked = false ;
}
private void ShowSearchForm ( )
{
if ( SearchForm = = null )
{
SearchForm = new WorldSearchForm ( this ) ;
SearchForm . Show ( this ) ;
}
else
{
if ( SearchForm . WindowState = = FormWindowState . Minimized )
{
SearchForm . WindowState = FormWindowState . Normal ;
}
SearchForm . Focus ( ) ;
}
//ToolbarSearchWindowButton.Checked = true;
}
public void OnSearchFormClosed ( )
{
SearchForm = null ;
//ToolbarSearchWindowButton.Checked = false;
}
2019-11-25 17:44:16 +08:00
private void ShowCutsceneForm ( )
{
if ( CutsceneForm = = null )
{
CutsceneForm = new CutsceneForm ( this ) ;
CutsceneForm . Show ( this ) ;
}
else
{
if ( CutsceneForm . WindowState = = FormWindowState . Minimized )
{
CutsceneForm . WindowState = FormWindowState . Normal ;
}
CutsceneForm . Focus ( ) ;
}
//ToolbarCutsceneWindowButton.Checked = true;
}
public void OnCutsceneFormClosed ( )
{
CutsceneForm = null ;
//ToolbarCutsceneWindowButton.Checked = false;
}
2017-09-21 18:33:05 +08:00
public void ShowModel ( string name )
{
ViewModeComboBox . Text = "Model view" ;
ModelComboBox . Text = name ;
modelname = name ;
}
public void GoToEntity ( YmapEntityDef entity )
{
if ( entity = = null ) return ;
ViewModeComboBox . Text = "World view" ;
GoToPosition ( entity . Position ) ;
2020-01-15 14:48:27 +08:00
SelectObject ( entity ) ;
2017-09-21 18:33:05 +08:00
}
private void LoadWorld ( )
{
2024-07-12 12:55:53 +08:00
#if ! DEBUG
try
{
#endif
UpdateStatus ( "Loading timecycles..." ) ;
timecycle . Init ( gameFileCache , UpdateStatus ) ;
timecycle . SetTime ( Renderer . timeofday ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading timecycles: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading materials..." ) ;
BoundsMaterialTypes . Init ( gameFileCache ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading materials: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading weather..." ) ;
weather . Init ( gameFileCache , UpdateStatus , timecycle ) ;
UpdateWeatherTypesComboBox ( weather ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading weather files, ensure you do not have FiveMods installed or any Redux mod. Game may require reinstall.: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading clouds..." ) ;
clouds . Init ( gameFileCache , UpdateStatus , weather ) ;
UpdateCloudTypesComboBox ( clouds ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading clouds: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading water..." ) ;
water . Init ( gameFileCache , UpdateStatus ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading water: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading trains..." ) ;
trains . Init ( gameFileCache , UpdateStatus ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading trains: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading scenarios..." ) ;
scenarios . Init ( gameFileCache , UpdateStatus , timecycle ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading scenarios: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading popzones..." ) ;
popzones . Init ( gameFileCache , UpdateStatus ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading popzones: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading heightmaps..." ) ;
heightmaps . Init ( gameFileCache , UpdateStatus ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading heightmaps: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading watermaps..." ) ;
watermaps . Init ( gameFileCache , UpdateStatus ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading watermaps: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading audio zones..." ) ;
audiozones . Init ( gameFileCache , UpdateStatus ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading audio zones: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
try
{
#endif
UpdateStatus ( "Loading world..." ) ;
space . Init ( gameFileCache , UpdateStatus ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Error loading world: {ex.Message}" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
}
#endif
2017-09-21 18:33:05 +08:00
UpdateStatus ( "World loaded" ) ;
}
private void SetDlcLevel ( string dlc , bool enable )
{
if ( ! initialised ) return ;
Cursor = Cursors . WaitCursor ;
Task . Run ( ( ) = >
{
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
if ( gameFileCache . SetDlcLevel ( dlc , enable ) )
{
LoadWorld ( ) ;
}
}
Invoke ( new Action ( ( ) = > {
Cursor = Cursors . Default ;
} ) ) ;
} ) ;
}
private void SetModsEnabled ( bool enable )
{
if ( ! initialised ) return ;
Cursor = Cursors . WaitCursor ;
Task . Run ( ( ) = >
{
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
if ( gameFileCache . SetModsEnabled ( enable ) )
{
UpdateDlcListComboBox ( gameFileCache . DlcNameList ) ;
LoadWorld ( ) ;
}
}
Invoke ( new Action ( ( ) = > {
Cursor = Cursors . Default ;
} ) ) ;
} ) ;
}
private void ContentThread ( )
{
//main content loading thread.
running = true ;
UpdateStatus ( "Scanning..." ) ;
try
{
2018-02-24 21:57:47 +08:00
GTA5Keys . LoadFromPath ( GTAFolder . CurrentGTAFolder , Settings . Default . Key ) ;
2018-02-24 19:52:58 +08:00
//save the key for later if it's not saved already. not really ideal to have this in this thread
if ( string . IsNullOrEmpty ( Settings . Default . Key ) & & ( GTA5Keys . PC_AES_KEY ! = null ) )
{
Settings . Default . Key = Convert . ToBase64String ( GTA5Keys . PC_AES_KEY ) ;
Settings . Default . Save ( ) ;
}
2017-09-21 18:33:05 +08:00
}
catch
{
2024-07-12 12:55:53 +08:00
MessageBox . Show ( "Keys not found! This shouldn't happen, GTA5.exe outdated? CodeWalker outdated?" ) ;
2017-09-21 18:33:05 +08:00
Close ( ) ;
return ;
}
gameFileCache . Init ( UpdateStatus , LogError ) ;
UpdateDlcListComboBox ( gameFileCache . DlcNameList ) ;
EnableCacheDependentUI ( ) ;
2024-07-12 12:55:53 +08:00
#if ! DEBUG
try
{
#endif
LoadWorld ( ) ;
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( $"Failed to load world: {ex.Message}" ) ;
Close ( ) ;
return ;
}
#endif
2017-09-21 18:33:05 +08:00
initialised = true ;
EnableDLCModsUI ( ) ;
2019-01-09 10:25:23 +08:00
Task . Run ( ( ) = > {
while ( formopen & & ! IsDisposed ) //renderer content loop
{
2024-07-12 12:55:53 +08:00
#if ! DEBUG
try
2019-01-09 10:25:23 +08:00
{
2024-07-12 12:55:53 +08:00
#endif
bool rcItemsPending = Renderer . ContentThreadProc ( ) ;
if ( ! rcItemsPending )
{
Thread . Sleep ( 1 ) ; //sleep if there's nothing to do
}
#if ! DEBUG
2019-01-09 10:25:23 +08:00
}
2024-07-12 12:55:53 +08:00
catch ( Exception ex )
{
MessageBox . Show ( $"Renderer Failed: {ex.Message}" ) ;
Close ( ) ;
return ;
}
#endif
2019-01-09 10:25:23 +08:00
}
} ) ;
2017-09-21 18:33:05 +08:00
while ( formopen & & ! IsDisposed ) //main asset loop
{
2024-07-12 12:55:53 +08:00
#if ! DEBUG
try
{
#endif
bool fcItemsPending = gameFileCache . ContentThreadProc ( ) ;
if ( ! fcItemsPending )
{
Thread . Sleep ( 1 ) ; //sleep if there's nothing to do
}
#if ! DEBUG
}
catch ( Exception ex )
2017-09-21 18:33:05 +08:00
{
2024-07-12 12:55:53 +08:00
MessageBox . Show ( $"GameFileCache Failed: {ex.Message}" ) ;
Close ( ) ;
return ;
2017-09-21 18:33:05 +08:00
}
2024-07-12 12:55:53 +08:00
#endif
2017-09-21 18:33:05 +08:00
}
gameFileCache . Clear ( ) ;
running = false ;
}
private void UpdateStatus ( string text )
{
try
{
if ( InvokeRequired )
{
BeginInvoke ( new Action ( ( ) = > { UpdateStatus ( text ) ; } ) ) ;
}
else
{
StatusLabel . Text = text ;
}
}
catch { }
}
private void UpdateMousedLabel ( string text )
{
try
{
if ( InvokeRequired )
{
BeginInvoke ( new Action ( ( ) = > { UpdateMousedLabel ( text ) ; } ) ) ;
}
else
{
MousedLabel . Text = text ;
}
}
catch { }
}
private void UpdateWeatherTypesComboBox ( Weather weather )
{
try
{
if ( InvokeRequired )
{
BeginInvoke ( new Action ( ( ) = > { UpdateWeatherTypesComboBox ( weather ) ; } ) ) ;
}
else
{
//MessageBox.Show("sky_hdr: " + weather.GetDynamicValue("sky_hdr").ToString() + "\n" +
// "Timecycle index: " + weather.Timecycle.CurrentSampleIndex + "\n" +
// "Timecycle blend: " + weather.Timecycle.CurrentSampleBlend + "\n");
WeatherComboBox . Items . Clear ( ) ;
foreach ( string wt in weather . WeatherTypes . Keys )
{
WeatherComboBox . Items . Add ( wt ) ;
}
2020-05-25 00:03:15 +08:00
WeatherComboBox . SelectedIndex = Math . Max ( WeatherComboBox . FindString ( Settings . Default . Weather ) , 0 ) ;
WeatherRegionComboBox . SelectedIndex = Math . Max ( WeatherRegionComboBox . FindString ( Settings . Default . Region ) , 0 ) ;
2017-09-21 18:33:05 +08:00
}
}
catch { }
}
private void UpdateCloudTypesComboBox ( Clouds clouds )
{
try
{
if ( InvokeRequired )
{
BeginInvoke ( new Action ( ( ) = > { UpdateCloudTypesComboBox ( clouds ) ; } ) ) ;
}
else
{
CloudsComboBox . Items . Clear ( ) ;
foreach ( var frag in clouds . HatManager . CloudHatFrags )
{
CloudsComboBox . Items . Add ( frag . Name ) ;
}
2018-01-02 04:52:54 +08:00
CloudsComboBox . SelectedIndex = Math . Max ( CloudsComboBox . FindString ( Renderer . individualcloudfrag ) , 0 ) ;
2017-09-21 18:33:05 +08:00
CloudParamComboBox . Items . Clear ( ) ;
foreach ( var setting in clouds . AnimSettings . Values )
{
CloudParamComboBox . Items . Add ( setting ) ;
}
CloudParamComboBox . SelectedIndex = 0 ;
}
}
catch { }
}
private void UpdateDlcListComboBox ( List < string > dlcnames )
{
try
{
if ( InvokeRequired )
{
BeginInvoke ( new Action ( ( ) = > { UpdateDlcListComboBox ( dlcnames ) ; } ) ) ;
}
else
{
DlcLevelComboBox . Items . Clear ( ) ;
foreach ( var dlcname in dlcnames )
{
DlcLevelComboBox . Items . Add ( dlcname ) ;
}
if ( string . IsNullOrEmpty ( gameFileCache . SelectedDlc ) )
{
DlcLevelComboBox . SelectedIndex = dlcnames . Count - 1 ;
}
else
{
int idx = DlcLevelComboBox . FindString ( gameFileCache . SelectedDlc ) ;
DlcLevelComboBox . SelectedIndex = ( idx > 0 ) ? idx : ( dlcnames . Count - 1 ) ;
}
}
}
catch { }
}
private void LogError ( string text )
{
try
{
if ( InvokeRequired )
{
Invoke ( new Action ( ( ) = > { LogError ( text ) ; } ) ) ;
}
else
{
ConsoleTextBox . AppendText ( text + "\r\n" ) ;
//MessageBox.Show(text);
}
}
catch { }
}
private void UpdateMarkerSelectionPanelInvoke ( )
{
try
{
if ( InvokeRequired )
{
BeginInvoke ( new Action ( ( ) = > { UpdateMarkerSelectionPanel ( ) ; } ) ) ;
}
else
{
UpdateMarkerSelectionPanel ( ) ;
}
}
catch { }
}
private void UpdateMarkerSelectionPanel ( )
{
if ( ! SelectedMarkerPanel . Visible ) return ;
if ( SelectedMarker = = null )
{
SelectedMarkerPanel . Visible = false ;
return ;
}
int ox = - 90 ; //screen offset from actual marker world pos
int oy = - 76 ;
float spx = ( ( SelectedMarker . ScreenPos . X * 0.5f ) + 0.5f ) * camera . Width ;
float spy = ( ( SelectedMarker . ScreenPos . Y * - 0.5f ) + 0.5f ) * camera . Height ;
int px = ( int ) Math . Round ( spx , MidpointRounding . AwayFromZero ) + ox ;
int py = ( int ) Math . Round ( spy , MidpointRounding . AwayFromZero ) + oy ;
int sx = SelectedMarkerPanel . Width ;
int sy = SelectedMarkerPanel . Height ;
SelectedMarkerPanel . SetBounds ( px , py , sx , sy ) ;
}
private void ShowMarkerSelectionInfo ( MapMarker marker )
{
SelectedMarkerNameTextBox . Text = SelectedMarker . Name ;
SelectedMarkerPositionTextBox . Text = SelectedMarker . Get3DWorldPosString ( ) ;
UpdateMarkerSelectionPanel ( ) ;
SelectedMarkerPanel . Visible = true ;
}
private void HideMarkerSelectionInfo ( )
{
SelectedMarkerPanel . Visible = false ;
}
private MapMarker FindMousedMarker ( )
{
lock ( markersortedsyncroot )
{
float mx = MouseLastPoint . X ;
float my = MouseLastPoint . Y ;
if ( ShowLocatorCheckBox . Checked )
{
if ( IsMarkerUnderPoint ( LocatorMarker , mx , my ) )
{
return LocatorMarker ;
}
}
//search backwards through the render markers (front to back)
for ( int i = SortedMarkers . Count - 1 ; i > = 0 ; i - - )
{
MapMarker m = SortedMarkers [ i ] ;
if ( IsMarkerUnderPoint ( m , mx , my ) )
{
return m ;
}
}
}
return null ;
}
private bool IsMarkerUnderPoint ( MapMarker marker , float x , float y )
{
if ( marker . ScreenPos . Z < = 0.0f ) return false ; //behind the camera...
float dx = x - ( ( marker . ScreenPos . X * 0.5f ) + 0.5f ) * camera . Width ;
float dy = y - ( ( marker . ScreenPos . Y * - 0.5f ) + 0.5f ) * camera . Height ;
float mcx = marker . Icon . Center . X ;
float mcy = marker . Icon . Center . Y ;
bool bx = ( ( dx > = - mcx ) & & ( dx < = mcx ) ) ;
bool by = ( ( dy < = 0.0f ) & & ( dy > = - mcy ) ) ;
return ( bx & & by ) ;
}
private void GoToMarker ( MapMarker m )
{
//////adjust the target to account for the main panel...
////Vector3 view = m.TexturePos;
////view.X += ((float)(MainPanel.Width + 4) * 0.5f) / CurrentZoom;
////TargetViewCenter = view;
camera . FollowEntity . Position = m . WorldPos ;
}
public void GoToPosition ( Vector3 p )
{
camera . FollowEntity . Position = p ;
}
2018-06-08 00:42:41 +08:00
public void GoToPosition ( Vector3 p , Vector3 bound )
{
camera . FollowEntity . Position = p ;
2018-06-10 21:36:50 +08:00
var bl = bound . Length ( ) ;
camera . TargetDistance = bl > 1f ? bl : 1f ;
2018-06-08 00:42:41 +08:00
}
2017-09-21 18:33:05 +08:00
2021-10-22 10:24:24 +08:00
public MapMarker AddMarker ( Vector3 pos , string name , bool addtotxtbox = false )
2017-09-21 18:33:05 +08:00
{
string str = pos . X . ToString ( ) + ", " + pos . Y . ToString ( ) + ", " + pos . Z . ToString ( ) ;
if ( ! string . IsNullOrEmpty ( name ) )
{
str + = ", " + name ;
}
if ( addtotxtbox )
{
StringBuilder sb = new StringBuilder ( ) ;
sb . Append ( MultiFindTextBox . Text ) ;
if ( ( sb . Length > 0 ) & & ( ! MultiFindTextBox . Text . EndsWith ( "\n" ) ) )
{
sb . AppendLine ( ) ;
}
sb . AppendLine ( str ) ;
MultiFindTextBox . Text = sb . ToString ( ) ;
}
return AddMarker ( str ) ;
}
private MapMarker AddMarker ( string markerstr )
{
lock ( markersyncroot )
{
MapMarker m = new MapMarker ( ) ;
m . Parse ( markerstr . Trim ( ) ) ;
m . Icon = MarkerIcon ;
Markers . Add ( m ) ;
//ListViewItem lvi = new ListViewItem(new string[] { m.Name, m.WorldPos.X.ToString(), m.WorldPos.Y.ToString(), m.WorldPos.Z.ToString() });
//lvi.Tag = m;
//MarkersListView.Items.Add(lvi);
return m ;
}
}
private void AddDefaultMarkers ( )
{
StringBuilder sb = new StringBuilder ( ) ;
//sb.AppendLine("1972.606, 3817.044, 0.0, Trevor Bed");
//sb.AppendLine("94.5723, -1290.082, 0.0, Strip Club Bed");
//sb.AppendLine("-1151.746, -1518.136, 0.0, Trevor City Bed");
//sb.AppendLine("-1154.11, -2715.203, 0.0, Flight School");
//sb.AppendLine("-1370.625, 56.1227, 52.82404, Golf");
//sb.AppendLine("-1109.213, 4914.744, 0.0, Altruist Cult");
//sb.AppendLine("-1633.087, 4736.784, 0.0, Deal Gone Wrong");
sb . AppendLine ( "-2052, 3237, 1449.036, Zancudo UFO" ) ;
sb . AppendLine ( "2490, 3777, 2400, Hippy UFO" ) ;
sb . AppendLine ( "2577.396, 3301.573, 52.52076, Sand glyph" ) ;
sb . AppendLine ( "-804.8452, 176.4936, 75.40561, bh1_48_michaels" ) ;
sb . AppendLine ( "-5.757423, 529.674, 171.1747, ch2_05c_b1" ) ;
sb . AppendLine ( "1971.208, 3818.237, 33.46632, cs4_10_trailer003b" ) ;
sb . AppendLine ( "760.4618, 7392.803, -126.0774, cs1_09_sea_ufo" ) ;
sb . AppendLine ( "501.4398, 5603.96, 795.9738, cs1_10_redeye" ) ;
sb . AppendLine ( "51.3909, 5957.7568, 209.614, cs1_10_clue_moon02" ) ;
sb . AppendLine ( "400.7087, 5714.5645, 605.0978, cs1_10_clue_rain01" ) ;
sb . AppendLine ( "703.442, 6329.8936, 76.4973, cs1_10_clue_rain02" ) ;
sb . AppendLine ( "228.7844, 5370.585, 577.2613, cs1_10_clue_moon01" ) ;
sb . AppendLine ( "366.4871, 5518.0742, 704.3185, cs1_10_clue_mountain01" ) ;
sb . AppendLine ( "41.64376, -779.9391, 832.4024, hw1_22_shipint" ) ;
sb . AppendLine ( "-1255.392, 6795.764, -181.9927, cs1_08_sea_base" ) ;
sb . AppendLine ( "4285.036, 2967.639, -184.1908, cs5_1_sea_hatch" ) ;
sb . AppendLine ( "3041.498, 5584.321, 196.4748, cs2_08_generic02" ) ;
sb . AppendLine ( "3406.483, 5498.655, 23.50577, cs2_08_generic01a" ) ;
sb . AppendLine ( "1507.081, 6565.075, 8.681923, cs1_09_props_elec_spider1" ) ;
sb . AppendLine ( "455.7852, 5586.104, 779.4382, cs1_10_elec_spider_spline052b" ) ;
sb . AppendLine ( "3861.661, -4959.252, 91.49448, plg_01_nico_new" ) ;
sb . AppendLine ( "-1689.308, 2174.457, 107.2592, ch1_09b_vinesleaf_28" ) ;
sb . AppendLine ( "440.8488, 5810.079, 563.4703, Cock face" ) ;
sb . AppendLine ( "-3955.667, -4675.212, -1274.563, Interesting..." ) ;
sb . AppendLine ( "4512.627, 2623.241, 2500, Interesting..." ) ;
sb . AppendLine ( "228.6058, -992.0537, -100, v_garagel" ) ;
MultiFindTextBox . Text = sb . ToString ( ) ;
string [ ] lines = MultiFindTextBox . Text . Split ( new [ ] { '\n' } , StringSplitOptions . RemoveEmptyEntries ) ;
foreach ( string line in lines )
{
AddMarker ( line ) ;
}
}
private void LoadSettings ( )
{
var s = Settings . Default ;
WindowState = s . WindowMaximized ? FormWindowState . Maximized : WindowState ;
FullScreenCheckBox . Checked = s . FullScreen ;
WireframeCheckBox . Checked = s . Wireframe ;
2019-12-03 21:52:22 +08:00
DeferredShadingCheckBox . Checked = s . Deferred ;
2017-09-21 18:33:05 +08:00
HDRRenderingCheckBox . Checked = s . HDR ;
ShadowsCheckBox . Checked = s . Shadows ;
SkydomeCheckBox . Checked = s . Skydome ;
2017-10-01 15:07:45 +08:00
GrassCheckBox . Checked = s . Grass ;
2017-09-21 18:33:05 +08:00
TimedEntitiesCheckBox . Checked = s . ShowTimedEntities ;
CollisionMeshesCheckBox . Checked = s . ShowCollisionMeshes ;
CollisionMeshRangeTrackBar . Value = s . CollisionMeshRange ;
DynamicLODCheckBox . Checked = s . DynamicLOD ;
DetailTrackBar . Value = s . DetailDist ;
WaitForChildrenCheckBox . Checked = s . WaitForChildren ;
RenderModeComboBox . SelectedIndex = Math . Max ( RenderModeComboBox . FindString ( s . RenderMode ) , 0 ) ;
TextureSamplerComboBox . SelectedIndex = Math . Max ( TextureSamplerComboBox . FindString ( s . RenderTextureSampler ) , 0 ) ;
TextureCoordsComboBox . SelectedIndex = Math . Max ( TextureCoordsComboBox . FindString ( s . RenderTextureSamplerCoord ) , 0 ) ;
MarkerStyleComboBox . SelectedIndex = Math . Max ( MarkerStyleComboBox . FindString ( s . MarkerStyle ) , 0 ) ;
LocatorStyleComboBox . SelectedIndex = Math . Max ( LocatorStyleComboBox . FindString ( s . LocatorStyle ) , 0 ) ;
MarkerDepthClipCheckBox . Checked = s . MarkerDepthClip ;
AnisotropicFilteringCheckBox . Checked = s . AnisotropicFiltering ;
BoundsStyleComboBox . SelectedIndex = Math . Max ( BoundsStyleComboBox . FindString ( s . BoundsStyle ) , 0 ) ;
BoundsDepthClipCheckBox . Checked = s . BoundsDepthClip ;
BoundsRangeTrackBar . Value = s . BoundsRange ;
ErrorConsoleCheckBox . Checked = s . ShowErrorConsole ;
StatusBarCheckBox . Checked = s . ShowStatusBar ;
2020-01-27 21:20:04 +08:00
SnapGridSizeUpDown . Value = ( decimal ) s . SnapGridSize ;
SetRotationSnapping ( s . SnapRotationDegrees ) ;
2020-05-25 00:03:15 +08:00
TimeOfDayTrackBar . Value = s . TimeOfDay ;
LODLightsCheckBox . Checked = s . LODLights ;
WeatherComboBox . SelectedIndex = Math . Max ( WeatherComboBox . FindString ( s . Weather ) , 0 ) ;
WeatherRegionComboBox . SelectedIndex = Math . Max ( WeatherRegionComboBox . FindString ( s . Region ) , 0 ) ;
Renderer . individualcloudfrag = s . Clouds ;
2024-08-05 18:24:59 +08:00
NaturalAmbientLightCheckBox . Checked = s . NaturalAmbientLight ;
2020-05-25 00:03:15 +08:00
ArtificialAmbientLightCheckBox . Checked = s . ArtificialAmbientLight ;
2024-08-05 18:24:59 +08:00
SavePositionCheckBox . Checked = s . SavePosition ;
SaveTimeOfDayCheckBox . Checked = s . SaveTimeOfDay ;
2020-01-27 21:20:04 +08:00
2021-11-07 22:13:52 +08:00
SetTimeOfDay ( s . TimeOfDay ) ;
Renderer . SetWeatherType ( s . Weather ) ;
2017-09-21 18:33:05 +08:00
EnableModsCheckBox . Checked = s . EnableMods ;
DlcLevelComboBox . Text = s . DLC ;
gameFileCache . SelectedDlc = s . DLC ;
EnableDlcCheckBox . Checked = ! string . IsNullOrEmpty ( s . DLC ) ;
}
private void SaveSettings ( )
{
var s = Settings . Default ;
s . WindowMaximized = ( WindowState = = FormWindowState . Maximized ) ;
s . FullScreen = FullScreenCheckBox . Checked ;
s . Wireframe = WireframeCheckBox . Checked ;
2019-12-03 21:52:22 +08:00
s . Deferred = DeferredShadingCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
s . HDR = HDRRenderingCheckBox . Checked ;
s . Shadows = ShadowsCheckBox . Checked ;
s . Skydome = SkydomeCheckBox . Checked ;
2017-10-01 15:07:45 +08:00
s . Grass = GrassCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
s . ShowTimedEntities = TimedEntitiesCheckBox . Checked ;
s . ShowCollisionMeshes = CollisionMeshesCheckBox . Checked ;
s . CollisionMeshRange = CollisionMeshRangeTrackBar . Value ;
s . DynamicLOD = DynamicLODCheckBox . Checked ;
s . DetailDist = DetailTrackBar . Value ;
s . WaitForChildren = WaitForChildrenCheckBox . Checked ;
s . RenderMode = RenderModeComboBox . Text ;
s . RenderTextureSampler = TextureSamplerComboBox . Text ;
s . RenderTextureSamplerCoord = TextureCoordsComboBox . Text ;
s . MarkerStyle = MarkerStyleComboBox . Text ;
s . LocatorStyle = LocatorStyleComboBox . Text ;
s . MarkerDepthClip = MarkerDepthClipCheckBox . Checked ;
s . AnisotropicFiltering = AnisotropicFilteringCheckBox . Checked ;
s . BoundsStyle = BoundsStyleComboBox . Text ;
s . BoundsDepthClip = BoundsDepthClipCheckBox . Checked ;
s . BoundsRange = BoundsRangeTrackBar . Value ;
s . ShowErrorConsole = ErrorConsoleCheckBox . Checked ;
s . ShowStatusBar = StatusBarCheckBox . Checked ;
2020-01-27 21:20:04 +08:00
s . SnapRotationDegrees = ( float ) SnapAngleUpDown . Value ;
s . SnapGridSize = ( float ) SnapGridSizeUpDown . Value ;
2020-05-25 00:03:15 +08:00
s . LODLights = LODLightsCheckBox . Checked ;
2024-08-05 18:24:59 +08:00
s . NaturalAmbientLight = NaturalAmbientLightCheckBox . Checked ;
2020-05-25 00:03:15 +08:00
s . ArtificialAmbientLight = ArtificialAmbientLightCheckBox . Checked ;
2024-08-05 18:24:59 +08:00
s . SavePosition = SavePositionCheckBox . Checked ;
s . SaveTimeOfDay = SaveTimeOfDayCheckBox . Checked ;
if ( s . SavePosition )
{
s . StartPosition = FloatUtil . GetVector3String ( camEntity ? . Position ? ? camera . Position ) ;
}
if ( s . SaveTimeOfDay )
{
s . TimeOfDay = TimeOfDayTrackBar . Value ;
s . Weather = WeatherComboBox . Text ;
s . Region = WeatherRegionComboBox . Text ;
s . Clouds = CloudsComboBox . Text ;
}
2017-09-21 18:33:05 +08:00
//additional settings from gamefilecache...
s . EnableMods = gameFileCache . EnableMods ;
s . DLC = gameFileCache . EnableDlc ? gameFileCache . SelectedDlc : "" ;
s . Save ( ) ;
}
2024-08-05 18:24:59 +08:00
private void ResetSettings ( )
{
if ( MessageBox . Show ( "Are you sure you want to reset all settings to their default values?" , "Reset All Settings" , MessageBoxButtons . YesNo ) ! = DialogResult . Yes ) return ;
Settings . Default . Reset ( ) ;
LoadSettings ( ) ;
if ( camEntity ! = null )
{
camEntity . Position = FloatUtil . ParseVector3String ( Settings . Default . StartPosition ) ;
camEntity . Orientation = Quaternion . LookAtLH ( Vector3 . Zero , Vector3 . Up , Vector3 . ForwardLH ) ;
camera . CurrentRotation = Vector3 . Zero ;
camera . TargetRotation = Vector3 . Zero ;
}
MessageBox . Show ( "All settings have been reset to their default values. Please restart CodeWalker." ) ;
}
2017-09-21 18:33:05 +08:00
private void ShowSettingsForm ( string tab = "" )
{
if ( SettingsForm = = null )
{
SettingsForm = new SettingsForm ( this ) ;
SettingsForm . Show ( this ) ;
}
else
{
if ( SettingsForm . WindowState = = FormWindowState . Minimized )
{
SettingsForm . WindowState = FormWindowState . Normal ;
}
SettingsForm . Focus ( ) ;
}
if ( ! string . IsNullOrEmpty ( tab ) )
{
SettingsForm . SelectTab ( tab ) ;
}
}
public void OnSettingsFormClosed ( )
{
//called by the SettingsForm when it's closed.
SettingsForm = null ;
}
private void MarkUndoStart ( Widget w )
{
2020-01-08 21:44:35 +08:00
if ( ! SelectedItem . CanMarkUndo ( ) ) return ;
2017-09-21 18:33:05 +08:00
if ( Widget is TransformWidget )
{
UndoStartPosition = Widget . Position ;
UndoStartRotation = Widget . Rotation ;
UndoStartScale = Widget . Scale ;
}
}
private void MarkUndoEnd ( Widget w )
{
2020-01-08 21:44:35 +08:00
if ( ! SelectedItem . CanMarkUndo ( ) ) return ;
2017-09-21 18:33:05 +08:00
TransformWidget tw = Widget as TransformWidget ;
UndoStep s = null ;
if ( tw ! = null )
{
2020-01-08 21:44:35 +08:00
s = SelectedItem . CreateUndoStep ( tw . Mode , UndoStartPosition , UndoStartRotation , UndoStartScale , this , EditEntityPivot ) ;
2017-09-21 18:33:05 +08:00
}
if ( s ! = null )
{
RedoSteps . Clear ( ) ;
UndoSteps . Push ( s ) ;
UpdateUndoUI ( ) ;
}
}
private void Undo ( )
{
if ( UndoSteps . Count = = 0 ) return ;
var s = UndoSteps . Pop ( ) ;
RedoSteps . Push ( s ) ;
2017-09-26 08:27:18 +08:00
s . Undo ( this , ref SelectedItem ) ;
if ( ProjectForm ! = null )
{
2020-01-08 21:44:35 +08:00
ProjectForm . OnWorldSelectionModified ( SelectedItem ) ;
2017-09-26 08:27:18 +08:00
}
2017-09-21 18:33:05 +08:00
UpdateUndoUI ( ) ;
}
private void Redo ( )
{
if ( RedoSteps . Count = = 0 ) return ;
var s = RedoSteps . Pop ( ) ;
UndoSteps . Push ( s ) ;
2017-09-26 08:27:18 +08:00
s . Redo ( this , ref SelectedItem ) ;
if ( ProjectForm ! = null )
{
2020-01-08 21:44:35 +08:00
ProjectForm . OnWorldSelectionModified ( SelectedItem ) ;
2017-09-26 08:27:18 +08:00
}
2017-09-21 18:33:05 +08:00
UpdateUndoUI ( ) ;
}
private void UpdateUndoUI ( )
{
ToolbarUndoButton . DropDownItems . Clear ( ) ;
ToolbarRedoButton . DropDownItems . Clear ( ) ;
int i = 0 ;
foreach ( var step in UndoSteps )
{
var button = ToolbarUndoButton . DropDownItems . Add ( step . ToString ( ) ) ;
button . Tag = step ;
button . Click + = ToolbarUndoListButton_Click ;
i + + ;
if ( i > = 10 ) break ;
}
i = 0 ;
foreach ( var step in RedoSteps )
{
var button = ToolbarRedoButton . DropDownItems . Add ( step . ToString ( ) ) ;
button . Tag = step ;
button . Click + = ToolbarRedoListButton_Click ;
i + + ;
if ( i > = 10 ) break ;
}
ToolbarUndoButton . Enabled = ( UndoSteps . Count > 0 ) ;
ToolbarRedoButton . Enabled = ( RedoSteps . Count > 0 ) ;
}
private void EnableCacheDependentUI ( )
{
try
{
if ( InvokeRequired )
{
BeginInvoke ( new Action ( ( ) = > { EnableCacheDependentUI ( ) ; } ) ) ;
}
else
{
ToolbarNewButton . Enabled = true ;
ToolbarOpenButton . Enabled = true ;
ToolbarProjectWindowButton . Enabled = true ;
ToolsMenuProjectWindow . Enabled = true ;
2019-11-25 17:44:16 +08:00
ToolsMenuCutsceneViewer . Enabled = true ;
2022-01-13 02:07:07 +08:00
ToolsMenuAudioExplorer . Enabled = true ;
2017-12-24 19:49:04 +08:00
ToolsMenuBinarySearch . Enabled = true ;
2017-09-21 18:33:05 +08:00
ToolsMenuJenkInd . Enabled = true ;
}
}
catch { }
}
private void EnableDLCModsUI ( )
{
try
{
if ( InvokeRequired )
{
BeginInvoke ( new Action ( ( ) = > { EnableDLCModsUI ( ) ; } ) ) ;
}
else
{
EnableDlcCheckBox . Enabled = true ;
EnableModsCheckBox . Enabled = true ;
DlcLevelComboBox . Enabled = true ;
}
}
catch { }
}
public void SetCurrentSaveItem ( string filename )
{
bool enable = ! string . IsNullOrEmpty ( filename ) ;
ToolbarSaveButton . ToolTipText = enable ? ( "Save " + filename ) : "Save" ;
ToolbarSaveButton . Enabled = enable ;
ToolbarSaveAllButton . Enabled = enable ;
}
public void EnableYmapUI ( bool enable , string filename )
{
string type = "entity" ;
switch ( SelectionMode )
{
case MapSelectionMode . CarGenerator : type = "car generator" ; break ;
}
ToolbarAddItemButton . ToolTipText = "Add " + type + ( enable ? ( " to " + filename ) : "" ) ;
ToolbarAddItemButton . Enabled = enable ;
}
2020-01-07 22:02:51 +08:00
public void EnableYbnUI ( bool enable , string filename )
{
if ( enable ) //only do something if a ybn is selected - EnableYmapUI will handle the no selection case..
{
//ToolbarAddItemButton.ToolTipText = "Add " + type + (enable ? (" to " + filename) : "");
//ToolbarAddItemButton.Enabled = enable;
}
}
2017-09-21 18:33:05 +08:00
public void EnableYndUI ( bool enable , string filename )
{
string type = "node" ;
switch ( SelectionMode )
{
case MapSelectionMode . Path : type = "node" ; break ;
}
if ( enable ) //only do something if a ynd is selected - EnableYmapUI will handle the no selection case..
{
ToolbarAddItemButton . ToolTipText = "Add " + type + ( enable ? ( " to " + filename ) : "" ) ;
ToolbarAddItemButton . Enabled = enable ;
}
}
public void EnableYnvUI ( bool enable , string filename )
{
string type = "polygon" ;
switch ( SelectionMode )
{
case MapSelectionMode . NavMesh : type = "polygon" ; break ;
}
if ( enable ) //only do something if a ynv is selected - EnableYmapUI will handle the no selection case..
{
ToolbarAddItemButton . ToolTipText = "Add " + type + ( enable ? ( " to " + filename ) : "" ) ;
ToolbarAddItemButton . Enabled = enable ;
}
}
public void EnableTrainsUI ( bool enable , string filename )
{
string type = "node" ;
switch ( SelectionMode )
{
case MapSelectionMode . TrainTrack : type = "node" ; break ;
}
if ( enable ) //only do something if a track is selected - EnableYmapUI will handle the no selection case..
{
ToolbarAddItemButton . ToolTipText = "Add " + type + ( enable ? ( " to " + filename ) : "" ) ;
ToolbarAddItemButton . Enabled = enable ;
}
}
public void EnableScenarioUI ( bool enable , string filename )
{
string type = "scenario point" ;
switch ( SelectionMode )
{
case MapSelectionMode . Scenario : type = "scenario point" ; break ;
}
if ( enable ) //only do something if a scenario is selected - EnableYmapUI will handle the no selection case..
{
ToolbarAddItemButton . ToolTipText = "Add " + type + ( enable ? ( " to " + filename ) : "" ) ;
ToolbarAddItemButton . Enabled = enable ;
}
}
2018-03-16 21:16:57 +08:00
public void EnableAudioUI ( bool enable , string filename ) //TODO
{
}
2017-09-21 18:33:05 +08:00
private void New ( )
{
ShowProjectForm ( ) ;
if ( ProjectForm . IsProjectLoaded )
{
ProjectForm . NewYmap ( ) ;
}
else
{
ProjectForm . NewProject ( ) ;
}
}
private void NewProject ( )
{
ShowProjectForm ( ) ;
ProjectForm . NewProject ( ) ;
}
private void NewYmap ( )
{
ShowProjectForm ( ) ;
ProjectForm . NewYmap ( ) ;
}
2020-01-08 21:44:35 +08:00
private void NewYtyp ( )
{
ShowProjectForm ( ) ;
ProjectForm . NewYtyp ( ) ;
}
private void NewYbn ( )
{
ShowProjectForm ( ) ;
ProjectForm . NewYbn ( ) ;
}
2017-09-21 18:33:05 +08:00
private void NewYnd ( )
{
ShowProjectForm ( ) ;
ProjectForm . NewYnd ( ) ;
}
private void NewTrainTrack ( )
{
ShowProjectForm ( ) ;
ProjectForm . NewTrainTrack ( ) ;
}
private void NewScenario ( )
{
ShowProjectForm ( ) ;
ProjectForm . NewScenario ( ) ;
}
private void Open ( )
{
ShowProjectForm ( ) ;
if ( ProjectForm . IsProjectLoaded )
{
2022-01-09 17:59:10 +08:00
ProjectForm . OpenFiles ( ) ;
2017-09-21 18:33:05 +08:00
}
else
{
ProjectForm . OpenProject ( ) ;
}
}
private void OpenProject ( )
{
ShowProjectForm ( ) ;
ProjectForm . OpenProject ( ) ;
}
2022-01-09 17:59:10 +08:00
private void OpenFiles ( )
2017-09-21 18:33:05 +08:00
{
ShowProjectForm ( ) ;
2022-01-09 17:59:10 +08:00
ProjectForm . OpenFiles ( ) ;
2017-09-21 18:33:05 +08:00
}
2022-01-09 17:59:10 +08:00
private void OpenFolder ( )
2017-09-21 18:33:05 +08:00
{
ShowProjectForm ( ) ;
2022-01-09 17:59:10 +08:00
ProjectForm . OpenFolder ( ) ;
2018-03-16 21:16:57 +08:00
}
2017-09-21 18:33:05 +08:00
private void Save ( )
{
if ( ProjectForm = = null ) return ;
ProjectForm . Save ( ) ;
}
private void SaveAll ( )
{
if ( ProjectForm = = null ) return ;
ProjectForm . SaveAll ( ) ;
}
private void AddItem ( )
{
2020-01-12 16:25:41 +08:00
if ( ProjectForm = = null ) return ;
2017-09-21 18:33:05 +08:00
switch ( SelectionMode )
{
2020-01-12 16:25:41 +08:00
case MapSelectionMode . Entity : ProjectForm . NewEntity ( ) ; break ;
case MapSelectionMode . CarGenerator : ProjectForm . NewCarGen ( ) ; break ;
case MapSelectionMode . Path : ProjectForm . NewPathNode ( ) ; break ;
case MapSelectionMode . NavMesh : ProjectForm . NewNavPoly ( ) ; break ; //.NewNavPoint/.NewNavPortal//how to add points/portals? project window
case MapSelectionMode . TrainTrack : ProjectForm . NewTrainNode ( ) ; break ;
case MapSelectionMode . Scenario : ProjectForm . NewScenarioNode ( ) ; break ; //how to add different node types? project window
2024-07-17 16:00:55 +08:00
case MapSelectionMode . Audio : ProjectForm . NewAudioAmbientZone ( ) ; break ; //.NewAudioEmitter // how to add emitters as well? project window
2017-09-21 18:33:05 +08:00
}
}
private void CopyItem ( )
{
2020-01-08 21:44:35 +08:00
CopiedItem = SelectedItem ;
2020-01-12 16:25:41 +08:00
ToolbarPasteButton . Enabled = CopiedItem . CanCopyPaste & & ( ProjectForm ! = null ) ; //ToolbarAddItemButton.Enabled;
2017-09-21 18:33:05 +08:00
}
private void PasteItem ( )
{
2020-01-12 16:25:41 +08:00
if ( ( ProjectForm ! = null ) & & CopiedItem . CanCopyPaste )
{
2020-01-15 14:48:27 +08:00
SelectObject ( ProjectForm . NewObject ( CopiedItem , ( CopiedItem . MultipleSelectionItems ! = null ) ) ) ;
2020-01-12 16:25:41 +08:00
}
2017-09-21 18:33:05 +08:00
}
private void CloneItem ( )
{
2020-01-12 16:25:41 +08:00
if ( ( ProjectForm ! = null ) & & SelectedItem . CanCopyPaste )
{
2020-01-15 14:48:27 +08:00
SelectObject ( ProjectForm . NewObject ( SelectedItem , true ) ) ;
2020-01-12 16:25:41 +08:00
}
2017-09-21 18:33:05 +08:00
}
2020-01-12 16:25:41 +08:00
private void DeleteItem ( )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
if ( ProjectForm ! = null )
{
ProjectForm . DeleteObject ( SelectedItem ) ;
SelectItem ( null ) ;
}
else
{
2020-01-13 20:31:27 +08:00
DeleteItem ( SelectedItem ) ;
2020-01-12 16:25:41 +08:00
SelectItem ( null ) ;
}
2017-09-21 18:33:05 +08:00
}
2020-01-13 20:31:27 +08:00
private void DeleteItem ( MapSelection item )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
if ( item . MultipleSelectionItems ! = null )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
for ( int i = 0 ; i < item . MultipleSelectionItems . Length ; i + + )
2017-09-21 18:33:05 +08:00
{
2020-01-13 20:31:27 +08:00
DeleteItem ( item . MultipleSelectionItems [ i ] ) ;
2017-09-21 18:33:05 +08:00
}
}
2020-01-13 20:31:27 +08:00
else if ( item . CollisionVertex ! = null ) DeleteCollisionVertex ( item . CollisionVertex ) ;
else if ( item . CollisionPoly ! = null ) DeleteCollisionPoly ( item . CollisionPoly ) ;
else if ( item . CollisionBounds ! = null ) DeleteCollisionBounds ( item . CollisionBounds ) ;
2020-01-12 16:25:41 +08:00
else if ( item . EntityDef ! = null ) DeleteEntity ( item . EntityDef ) ;
else if ( item . CarGenerator ! = null ) DeleteCarGen ( item . CarGenerator ) ;
2021-04-30 00:15:23 +08:00
else if ( item . LodLight ! = null ) DeleteLodLight ( item . LodLight ) ;
else if ( item . BoxOccluder ! = null ) DeleteBoxOccluder ( item . BoxOccluder ) ;
else if ( item . OccludeModelTri ! = null ) DeleteOccludeModelTriangle ( item . OccludeModelTri ) ;
2020-01-12 16:25:41 +08:00
else if ( item . PathNode ! = null ) DeletePathNode ( item . PathNode ) ;
else if ( item . NavPoly ! = null ) DeleteNavPoly ( item . NavPoly ) ;
else if ( item . NavPoint ! = null ) DeleteNavPoint ( item . NavPoint ) ;
else if ( item . NavPortal ! = null ) DeleteNavPortal ( item . NavPortal ) ;
else if ( item . TrainTrackNode ! = null ) DeleteTrainNode ( item . TrainTrackNode ) ;
else if ( item . ScenarioNode ! = null ) DeleteScenarioNode ( item . ScenarioNode ) ;
2024-07-17 16:00:55 +08:00
else if ( item . Audio ? . AmbientZone ! = null ) DeleteAudioAmbientZone ( item . Audio ) ;
else if ( item . Audio ? . AmbientRule ! = null ) DeleteAudioAmbientRule ( item . Audio ) ;
else if ( item . Audio ? . StaticEmitter ! = null ) DeleteAudioStaticEmitter ( item . Audio ) ;
2020-01-12 16:25:41 +08:00
}
private void DeleteEntity ( YmapEntityDef ent )
{
if ( ent = = null ) return ;
//project not open, or entity not selected there, just remove the entity from the ymap/mlo...
var ymap = ent . Ymap ;
var instance = ent . MloParent ? . MloInstance ;
if ( ymap = = null )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
if ( instance ! = null )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
try
2018-12-03 16:54:04 +08:00
{
2020-01-12 16:25:41 +08:00
if ( ! instance . DeleteEntity ( ent ) )
2018-12-03 16:54:04 +08:00
{
2020-01-12 16:25:41 +08:00
SelectItem ( null ) ;
2018-12-03 16:54:04 +08:00
}
}
2020-01-12 16:25:41 +08:00
catch ( Exception e ) // various failures can happen here.
{
MessageBox . Show ( "Unable to remove entity..." + Environment . NewLine + e . Message ) ;
}
2017-09-21 18:33:05 +08:00
}
}
2020-01-12 16:25:41 +08:00
else if ( ! ymap . RemoveEntity ( ent ) )
2018-12-03 16:54:04 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove entity." ) ;
2018-12-03 16:54:04 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
SelectItem ( null ) ;
2018-12-03 16:54:04 +08:00
}
2017-09-21 18:33:05 +08:00
}
2020-01-12 16:25:41 +08:00
private void DeleteCarGen ( YmapCarGen cargen )
2017-09-21 18:33:05 +08:00
{
if ( cargen = = null ) return ;
2020-01-12 16:25:41 +08:00
//project not open, or cargen not selected there, just remove the cargen from the ymap...
var ymap = cargen . Ymap ;
if ( ! ymap . RemoveCarGen ( cargen ) )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove car generator." ) ;
2017-09-21 18:33:05 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
SelectItem ( null ) ;
2017-09-21 18:33:05 +08:00
}
}
2021-04-30 00:15:23 +08:00
private void DeleteLodLight ( YmapLODLight lodlight )
{
if ( lodlight = = null ) return ;
//project not open, or lodlight not selected there, just remove the lodlight from the ymap...
var ymap = lodlight . Ymap ;
if ( ! ymap . RemoveLodLight ( lodlight ) )
{
MessageBox . Show ( "Unable to remove LOD light." ) ;
}
else
{
SelectItem ( null ) ;
}
}
private void DeleteBoxOccluder ( YmapBoxOccluder box )
{
if ( box = = null ) return ;
//project not open, or box not selected there, just remove the box from the ymap...
var ymap = box . Ymap ;
if ( ! ymap . RemoveBoxOccluder ( box ) )
{
MessageBox . Show ( "Unable to remove box occluder." ) ;
}
else
{
SelectItem ( null ) ;
}
}
private void DeleteOccludeModelTriangle ( YmapOccludeModelTriangle tri )
{
if ( tri = = null ) return ;
//project not open, or tri not selected there, just remove the tri from the ymap...
var ymap = tri . Ymap ;
if ( ! ymap . RemoveOccludeModelTriangle ( tri ) )
{
MessageBox . Show ( "Unable to remove occlude model triangle." ) ;
}
else
{
UpdateOccludeModelGraphics ( tri . Model ) ;
SelectItem ( null ) ;
}
}
2020-01-12 16:25:41 +08:00
private void DeletePathNode ( YndNode pathnode )
2017-09-21 18:33:05 +08:00
{
if ( pathnode = = null ) return ;
2023-09-04 18:48:50 +08:00
if ( pathnode . Ynd = = null ) return ;
2017-09-21 18:33:05 +08:00
2023-09-04 18:48:50 +08:00
//project not open, or node not selected there, just remove the node from the ynd...
2020-01-12 16:25:41 +08:00
var ynd = pathnode . Ynd ;
2023-09-04 18:48:50 +08:00
if ( ! ynd . RemoveYndNode ( Space , pathnode , true , out var affectedFiles ) )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove path node." ) ;
2017-09-21 18:33:05 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
UpdatePathNodeGraphics ( pathnode , false ) ;
2023-09-04 18:48:50 +08:00
ProjectForm ? . AddYndToProject ( ynd ) ;
foreach ( var affectedFile in affectedFiles )
{
UpdatePathYndGraphics ( affectedFile , false ) ;
ProjectForm ? . AddYndToProject ( affectedFile ) ;
affectedFile . HasChanged = true ;
}
2020-01-12 16:25:41 +08:00
SelectItem ( null ) ;
2017-09-21 18:33:05 +08:00
}
}
2020-01-12 16:25:41 +08:00
private void DeleteNavPoly ( YnvPoly navpoly )
2017-09-21 18:33:05 +08:00
{
if ( navpoly = = null ) return ;
2020-01-12 16:25:41 +08:00
//project not open, or nav poly not selected there, just remove the poly from the ynv...
var ynv = navpoly . Ynv ;
if ( ! ynv . RemovePoly ( navpoly ) )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove nav poly. NavMesh editing TODO!" ) ;
2017-09-21 18:33:05 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
UpdateNavPolyGraphics ( navpoly , false ) ;
SelectItem ( null ) ;
2017-09-21 18:33:05 +08:00
}
}
2020-01-12 16:25:41 +08:00
private void DeleteNavPoint ( YnvPoint navpoint )
2017-09-21 18:33:05 +08:00
{
2018-03-14 09:36:43 +08:00
if ( navpoint = = null ) return ;
2020-01-12 16:25:41 +08:00
//project not open, or nav point not selected there, just remove the point from the ynv...
var ynv = navpoint . Ynv ;
if ( ! ynv . RemovePoint ( navpoint ) )
2018-03-14 09:36:43 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove nav point. NavMesh editing TODO!" ) ;
2018-03-14 09:36:43 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
UpdateNavPointGraphics ( navpoint , false ) ;
SelectItem ( null ) ;
2018-03-14 09:36:43 +08:00
}
}
2020-01-12 16:25:41 +08:00
private void DeleteNavPortal ( YnvPortal navportal )
2018-03-14 09:36:43 +08:00
{
if ( navportal = = null ) return ;
2020-01-12 16:25:41 +08:00
//project not open, or nav portal not selected there, just remove the portal from the ynv...
var ynv = navportal . Ynv ;
if ( ! ynv . RemovePortal ( navportal ) )
2018-03-14 09:36:43 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove nav portal. NavMesh editing TODO!" ) ;
2018-03-14 09:36:43 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
UpdateNavPortalGraphics ( navportal , false ) ;
SelectItem ( null ) ;
2018-03-14 09:36:43 +08:00
}
}
2020-01-12 16:25:41 +08:00
private void DeleteTrainNode ( TrainTrackNode trainnode )
2017-09-21 18:33:05 +08:00
{
if ( trainnode = = null ) return ;
2020-01-12 16:25:41 +08:00
//project not open, or train node not selected there, just remove the node from the train track...
var track = trainnode . Track ;
if ( ! track . RemoveNode ( trainnode ) )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove train track node." ) ;
2017-09-21 18:33:05 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
UpdateTrainTrackNodeGraphics ( trainnode , false ) ;
SelectItem ( null ) ;
2017-09-21 18:33:05 +08:00
}
}
2020-01-12 16:25:41 +08:00
private void DeleteScenarioNode ( ScenarioNode scenariopt )
2017-09-21 18:33:05 +08:00
{
if ( scenariopt = = null ) return ;
2020-01-12 16:25:41 +08:00
//project not open, or scenario point not selected there, just remove the point from the region...
var region = scenariopt . Region . Ymt . ScenarioRegion ;
if ( ! region . RemoveNode ( scenariopt ) )
2017-09-21 18:33:05 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove scenario point." ) ;
2017-09-21 18:33:05 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
UpdateScenarioGraphics ( scenariopt . Ymt , false ) ;
SelectItem ( null ) ;
2017-09-21 18:33:05 +08:00
}
}
2024-07-17 16:00:55 +08:00
private void DeleteAudioAmbientZone ( AudioPlacement audio )
2017-09-21 18:33:05 +08:00
{
2018-03-16 21:16:57 +08:00
if ( audio = = null ) return ;
2020-01-12 16:25:41 +08:00
//project not open, or zone not selected there, just remove the zone from the rel...
var rel = audio . RelFile ;
2024-07-17 16:00:55 +08:00
if ( ! rel . RemoveRelData ( audio . AmbientZone ) )
2018-03-16 21:16:57 +08:00
{
2024-07-17 16:00:55 +08:00
MessageBox . Show ( "Unable to remove audio ambient zone." ) ;
2018-03-16 21:16:57 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
SelectItem ( null ) ;
2018-03-16 21:16:57 +08:00
}
}
2024-07-17 16:00:55 +08:00
private void DeleteAudioAmbientRule ( AudioPlacement audio )
2018-03-16 21:16:57 +08:00
{
if ( audio = = null ) return ;
2024-07-17 16:00:55 +08:00
//project not open, or rule not selected there, just remove the rule from the rel...
var rel = audio . RelFile ;
if ( ! rel . RemoveRelData ( audio . AmbientRule ) )
{
MessageBox . Show ( "Unable to remove audio ambient rule." ) ;
}
else
{
SelectItem ( null ) ;
}
}
private void DeleteAudioStaticEmitter ( AudioPlacement audio )
{
if ( audio = = null ) return ;
//project not open, or emitter not selected there, just remove the emitter from the rel...
2020-01-12 16:25:41 +08:00
var rel = audio . RelFile ;
2024-07-17 16:00:55 +08:00
if ( ! rel . RemoveRelData ( audio . StaticEmitter ) )
2018-03-16 21:16:57 +08:00
{
2024-07-17 16:00:55 +08:00
MessageBox . Show ( "Unable to remove audio static emitter." ) ;
2018-03-16 21:16:57 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
SelectItem ( null ) ;
2018-03-16 21:16:57 +08:00
}
}
2020-01-12 16:25:41 +08:00
private void DeleteCollisionVertex ( BoundVertex vertex )
2018-03-16 21:16:57 +08:00
{
2020-01-11 16:20:14 +08:00
if ( vertex = = null ) return ;
2020-01-12 16:25:41 +08:00
//project not open, or vertex not selected there, just remove the vertex from the geometry...
var bgeom = vertex . Owner ;
if ( ( bgeom = = null ) | | ( ! bgeom . DeleteVertex ( vertex . Index ) ) )
2020-01-11 16:20:14 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove vertex." ) ;
2020-01-11 16:20:14 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
UpdateCollisionBoundsGraphics ( bgeom ) ;
SelectItem ( null ) ;
2020-01-11 16:20:14 +08:00
}
}
2020-01-12 16:25:41 +08:00
private void DeleteCollisionPoly ( BoundPolygon poly )
2020-01-11 16:20:14 +08:00
{
2020-01-12 16:25:41 +08:00
if ( poly = = null ) return ;
2020-01-11 16:20:14 +08:00
2020-01-12 16:25:41 +08:00
//project not open, or polygon not selected there, just remove the vertex from the geometry...
var bgeom = poly . Owner ;
if ( ( bgeom = = null ) | | ( ! bgeom . DeletePolygon ( poly ) ) )
2020-01-11 16:20:14 +08:00
{
2020-01-12 16:25:41 +08:00
MessageBox . Show ( "Unable to remove polygon." ) ;
2020-01-11 16:20:14 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
UpdateCollisionBoundsGraphics ( bgeom ) ;
2020-01-11 16:20:14 +08:00
SelectItem ( null ) ;
}
}
2020-01-12 16:25:41 +08:00
private void DeleteCollisionBounds ( Bounds bounds )
2020-01-11 16:20:14 +08:00
{
2020-01-12 16:25:41 +08:00
if ( bounds = = null ) return ;
2020-01-11 16:20:14 +08:00
2020-01-12 16:25:41 +08:00
var parent = bounds . Parent ;
if ( parent ! = null )
2020-01-11 16:20:14 +08:00
{
2020-01-12 16:25:41 +08:00
parent . DeleteChild ( bounds ) ;
UpdateCollisionBoundsGraphics ( parent ) ;
2020-01-11 16:20:14 +08:00
}
else
{
2020-01-12 16:25:41 +08:00
var ybn = bounds . GetRootYbn ( ) ;
ybn . RemoveBounds ( bounds ) ;
2020-01-11 16:20:14 +08:00
}
2020-01-12 16:25:41 +08:00
SelectItem ( null ) ;
2020-01-11 16:20:14 +08:00
}
2018-03-16 21:16:57 +08:00
2017-09-21 18:33:05 +08:00
private void SetMouseSelect ( bool enable )
{
MouseSelectEnabled = enable ;
MouseSelectCheckBox . Checked = enable ;
ToolbarSelectButton . Checked = enable ;
if ( InfoForm ! = null )
{
InfoForm . SetSelectionMode ( SelectionModeStr , MouseSelectEnabled ) ;
}
}
private void SetWidgetMode ( string mode )
{
ToolbarMoveButton . Checked = false ;
ToolbarRotateButton . Checked = false ;
ToolbarScaleButton . Checked = false ;
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
switch ( mode )
{
case "Default" :
Widget . Mode = WidgetMode . Default ;
iseditmode = false ;
break ;
case "Position" :
Widget . Mode = WidgetMode . Position ;
iseditmode = true ;
ToolbarMoveButton . Checked = true ;
break ;
case "Rotation" :
Widget . Mode = WidgetMode . Rotation ;
iseditmode = true ;
ToolbarRotateButton . Checked = true ;
break ;
case "Scale" :
Widget . Mode = WidgetMode . Scale ;
iseditmode = true ;
ToolbarScaleButton . Checked = true ;
break ;
}
}
}
private void SetWidgetSpace ( string space )
{
foreach ( var child in ToolbarTransformSpaceButton . DropDownItems )
{
var childi = child as ToolStripMenuItem ;
if ( childi ! = null )
{
childi . Checked = false ;
}
}
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
switch ( space )
{
case "World space" :
Widget . ObjectSpace = false ;
ToolbarTransformSpaceButton . Image = ToolbarWorldSpaceButton . Image ;
ToolbarWorldSpaceButton . Checked = true ;
break ;
case "Object space" :
Widget . ObjectSpace = true ;
ToolbarTransformSpaceButton . Image = ToolbarObjectSpaceButton . Image ;
ToolbarObjectSpaceButton . Checked = true ;
break ;
}
}
}
private void ToggleWidgetSpace ( )
{
SetWidgetSpace ( Widget . ObjectSpace ? "World space" : "Object space" ) ;
}
private void SetFullscreen ( bool fullscreen )
{
if ( fullscreen )
{
FormBorderStyle = FormBorderStyle . None ;
WindowState = FormWindowState . Maximized ;
}
else
{
WindowState = FormWindowState . Normal ;
FormBorderStyle = FormBorderStyle . Sizable ;
}
}
private void SetBoundsMode ( string modestr )
{
BoundsShaderMode mode = BoundsShaderMode . None ;
switch ( modestr )
{
case "Boxes" :
mode = BoundsShaderMode . Box ;
break ;
case "Spheres" :
mode = BoundsShaderMode . Sphere ;
break ;
}
2018-01-02 04:52:54 +08:00
Renderer . boundsmode = mode ;
2017-09-21 18:33:05 +08:00
}
private void SetSelectionMode ( string modestr )
{
foreach ( var child in ToolbarSelectButton . DropDownItems )
{
var childi = child as ToolStripMenuItem ;
if ( childi ! = null )
{
childi . Checked = false ;
}
}
MapSelectionMode mode = MapSelectionMode . Entity ;
switch ( modestr )
{
default :
case "Entity" :
mode = MapSelectionMode . Entity ;
ToolbarSelectEntityButton . Checked = true ;
break ;
case "Entity Extension" :
mode = MapSelectionMode . EntityExtension ;
ToolbarSelectEntityExtensionButton . Checked = true ;
break ;
case "Archetype Extension" :
mode = MapSelectionMode . ArchetypeExtension ;
ToolbarSelectArchetypeExtensionButton . Checked = true ;
break ;
case "Time Cycle Modifier" :
mode = MapSelectionMode . TimeCycleModifier ;
ToolbarSelectTimeCycleModifierButton . Checked = true ;
break ;
case "Car Generator" :
mode = MapSelectionMode . CarGenerator ;
ToolbarSelectCarGeneratorButton . Checked = true ;
break ;
case "Grass" :
mode = MapSelectionMode . Grass ;
ToolbarSelectGrassButton . Checked = true ;
break ;
case "Water Quad" :
mode = MapSelectionMode . WaterQuad ;
ToolbarSelectWaterQuadButton . Checked = true ;
break ;
2021-12-02 16:15:12 +08:00
case "Water Calming Quad" :
mode = MapSelectionMode . CalmingQuad ;
ToolbarSelectCalmingQuadButton . Checked = true ;
break ;
case "Water Wave Quad" :
mode = MapSelectionMode . WaveQuad ;
ToolbarSelectWaveQuadButton . Checked = true ;
break ;
2017-09-21 18:33:05 +08:00
case "Collision" :
mode = MapSelectionMode . Collision ;
ToolbarSelectCollisionButton . Checked = true ;
break ;
case "Nav Mesh" :
mode = MapSelectionMode . NavMesh ;
ToolbarSelectNavMeshButton . Checked = true ;
break ;
case "Path" :
mode = MapSelectionMode . Path ;
ToolbarSelectPathButton . Checked = true ;
break ;
case "Train Track" :
mode = MapSelectionMode . TrainTrack ;
ToolbarSelectTrainTrackButton . Checked = true ;
break ;
2021-04-22 13:16:11 +08:00
case "Lod Lights" :
mode = MapSelectionMode . LodLights ;
ToolbarSelectLodLightsButton . Checked = true ;
2017-09-21 18:33:05 +08:00
break ;
case "Mlo Instance" :
mode = MapSelectionMode . MloInstance ;
ToolbarSelectMloInstanceButton . Checked = true ;
break ;
case "Scenario" :
mode = MapSelectionMode . Scenario ;
ToolbarSelectScenarioButton . Checked = true ;
break ;
2017-12-22 04:26:04 +08:00
case "Audio" :
mode = MapSelectionMode . Audio ;
ToolbarSelectAudioButton . Checked = true ;
break ;
2018-12-14 22:46:48 +08:00
case "Occlusion" :
mode = MapSelectionMode . Occlusion ;
ToolbarSelectOcclusionButton . Checked = true ;
break ;
2017-09-21 18:33:05 +08:00
}
SelectionMode = mode ;
SelectionModeStr = modestr ;
2018-12-16 14:20:00 +08:00
Renderer . SelectionMode = mode ;
2017-09-21 18:33:05 +08:00
if ( SelectionModeComboBox . Text ! = modestr )
{
SelectionModeComboBox . Text = modestr ;
}
if ( InfoForm ! = null )
{
InfoForm . SetSelectionMode ( modestr , MouseSelectEnabled ) ;
}
}
2018-02-25 20:30:29 +08:00
private void SetSnapMode ( WorldSnapMode mode )
{
foreach ( var child in ToolbarSnapButton . DropDownItems )
{
var childi = child as ToolStripMenuItem ;
if ( childi ! = null )
{
childi . Checked = false ;
}
}
ToolbarSnapButton . Checked = ( mode ! = WorldSnapMode . None ) ;
ToolStripMenuItem selItem = null ;
switch ( mode )
{
case WorldSnapMode . Ground :
selItem = ToolbarSnapToGroundButton ;
break ;
case WorldSnapMode . Grid :
selItem = ToolbarSnapToGridButton ;
break ;
case WorldSnapMode . Hybrid :
selItem = ToolbarSnapToGroundGridButton ;
break ;
}
if ( selItem ! = null )
{
selItem . Checked = true ;
ToolbarSnapButton . Image = selItem . Image ;
ToolbarSnapButton . Text = selItem . Text ;
ToolbarSnapButton . ToolTipText = selItem . ToolTipText ;
}
if ( mode ! = WorldSnapMode . None )
{
SnapModePrev = mode ;
}
SnapMode = mode ;
}
2020-01-15 12:26:35 +08:00
private void SetRotationSnapping ( float degrees )
{
Widget . SnapAngleDegrees = degrees ;
foreach ( var child in ToolbarRotationSnappingButton . DropDownItems )
{
var childi = child as ToolStripMenuItem ;
if ( childi ! = null )
{
childi . Checked = false ;
}
}
var selItem = ToolbarRotationSnappingCustomButton ;
switch ( degrees )
{
case 0.0f :
selItem = ToolbarRotationSnappingOffButton ;
break ;
case 1.0f :
selItem = ToolbarRotationSnapping1Button ;
break ;
case 2.0f :
selItem = ToolbarRotationSnapping2Button ;
break ;
case 5.0f :
selItem = ToolbarRotationSnapping5Button ;
break ;
case 10.0f :
selItem = ToolbarRotationSnapping10Button ;
break ;
case 45.0f :
selItem = ToolbarRotationSnapping45Button ;
break ;
case 90.0f :
selItem = ToolbarRotationSnapping90Button ;
break ;
}
if ( selItem ! = null )
{
selItem . Checked = true ;
}
var cval = ( float ) SnapAngleUpDown . Value ;
if ( cval ! = degrees )
{
SnapAngleUpDown . Value = ( decimal ) degrees ;
}
}
2017-09-21 18:33:05 +08:00
private void SetCameraMode ( string modestr )
{
foreach ( var child in ToolbarCameraModeButton . DropDownItems )
{
var childi = child as ToolStripMenuItem ;
if ( childi ! = null )
{
childi . Checked = false ;
}
}
2018-01-02 04:52:54 +08:00
Renderer . SetCameraMode ( modestr ) ;
switch ( modestr )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
case "Perspective" :
MapViewEnabled = false ;
ToolbarCameraModeButton . Image = ToolbarCameraPerspectiveButton . Image ;
ToolbarCameraPerspectiveButton . Checked = true ;
break ;
case "Orthographic" :
MapViewEnabled = false ;
ToolbarCameraModeButton . Image = ToolbarCameraOrthographicButton . Image ;
ToolbarCameraOrthographicButton . Checked = true ;
break ;
case "2D Map" :
MapViewEnabled = true ;
ToolbarCameraModeButton . Image = ToolbarCameraMapViewButton . Image ;
ToolbarCameraMapViewButton . Checked = true ;
break ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
2017-09-21 18:33:05 +08:00
FieldOfViewTrackBar . Enabled = ! MapViewEnabled ;
MapViewDetailTrackBar . Enabled = MapViewEnabled ;
if ( CameraModeComboBox . Text ! = modestr )
{
CameraModeComboBox . Text = modestr ;
}
}
private void ToggleCameraMode ( )
{
SetCameraMode ( MapViewEnabled ? "Perspective" : "2D Map" ) ;
}
private void ToggleToolbar ( )
{
ToolbarPanel . Visible = ! ToolbarPanel . Visible ;
ShowToolbarCheckBox . Checked = ToolbarPanel . Visible ;
}
2019-11-25 18:35:15 +08:00
public void ShowSubtitle ( string text , float duration )
{
if ( InvokeRequired )
{
try
{
BeginInvoke ( new Action ( ( ) = > { ShowSubtitle ( text , duration ) ; } ) ) ;
}
catch { }
return ;
}
SubtitleLabel . Text = text ;
SubtitleLabel . Visible = true ;
SubtitleTimer . Interval = ( int ) ( duration * 1000.0f ) ;
SubtitleTimer . Enabled = true ;
}
2021-11-07 22:13:52 +08:00
private void SetTimeOfDay ( int minute )
{
float hour = minute / 60.0f ;
UpdateTimeOfDayLabel ( ) ;
lock ( Renderer . RenderSyncRoot )
{
Renderer . SetTimeOfDay ( hour ) ;
}
}
2019-11-25 18:35:15 +08:00
2023-09-04 18:48:50 +08:00
private void TryCreateNodeLink ( ) //TODO: move this to project window
{
if ( SelectionMode ! = MapSelectionMode . Path )
{
return ;
}
var selection = SelectedItem . MultipleSelectionItems ;
if ( selection ? . Length ! = 2 )
{
MessageBox . Show ( "Please select 2 nodes to perform this action" ,
"Join Failed." ,
MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
return ;
}
var n1 = selection [ 0 ] . PathNode ;
var n2 = selection [ 1 ] . PathNode ;
if ( n1 ! = null & & n2 ! = null )
{
var link = n1 . AddLink ( n2 ) ;
if ( link = = null )
{
MessageBox . Show ( "Failed to join nodes. The nodes are likely too far away!" , "Join Failed." , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
return ;
}
var copy = n1 . Links . FirstOrDefault ( ) ;
link . SetForwardLanesBidirectionally ( copy ? . LaneCountBackward ? ? 1 ) ;
link . SetBackwardLanesBidirectionally ( copy ? . LaneCountForward ? ? 1 ) ;
UpdatePathYndGraphics ( n1 . Ynd , false ) ;
UpdatePathYndGraphics ( n2 . Ynd , false ) ;
}
}
private void TryCreateNodeShortcut ( ) //TODO: move this to project window
{
if ( SelectionMode ! = MapSelectionMode . Path )
{
return ;
}
var selection = SelectedItem . MultipleSelectionItems ;
if ( selection ? . Length ! = 2 )
{
MessageBox . Show ( "Please select 2 nodes to perform this action" ,
"Join Failed." ,
MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
return ;
}
var n1 = selection [ 0 ] . PathNode ;
var n2 = selection [ 1 ] . PathNode ;
if ( n1 ! = null & & n2 ! = null )
{
var link = n1 . AddLink ( n2 ) ;
if ( link = = null )
{
MessageBox . Show ( "Failed to join nodes. The nodes are likely too far away!" , "Join Failed." , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
return ;
}
link . SetForwardLanesBidirectionally ( 1 ) ;
link . Shortcut = true ;
if ( n2 . TryGetLinkForNode ( n1 , out var backLink ) )
{
backLink . Shortcut = true ;
}
UpdatePathYndGraphics ( n1 . Ynd , false ) ;
UpdatePathYndGraphics ( n2 . Ynd , false ) ;
}
}
2019-11-25 18:35:15 +08:00
2017-09-21 18:33:05 +08:00
private void StatsUpdateTimer_Tick ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
StatsLabel . Text = Renderer . GetStatusText ( ) ;
if ( Renderer . timerunning )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
float fv = Renderer . timeofday * 60.0f ;
2017-09-21 18:33:05 +08:00
TimeOfDayTrackBar . Value = ( int ) fv ;
UpdateTimeOfDayLabel ( ) ;
}
2020-01-19 23:08:04 +08:00
CameraPositionTextBox . Text = FloatUtil . GetVector3StringFormat ( camera . Position , "0.##" ) ;
2017-09-21 18:33:05 +08:00
}
private void WorldForm_Load ( object sender , EventArgs e )
{
Init ( ) ;
}
private void WorldForm_FormClosing ( object sender , FormClosingEventArgs e )
{
}
2024-07-12 07:14:56 +08:00
private void WorldForm_FormClosed ( object sender , FormClosedEventArgs e )
{
SaveSettings ( ) ;
}
2017-09-21 18:33:05 +08:00
private void WorldForm_MouseDown ( object sender , MouseEventArgs e )
{
switch ( e . Button )
{
case MouseButtons . Left : MouseLButtonDown = true ; break ;
case MouseButtons . Right : MouseRButtonDown = true ; break ;
}
2018-03-04 18:35:33 +08:00
if ( ! ToolsPanelShowButton . Focused )
{
ToolsPanelShowButton . Focus ( ) ; //make sure no textboxes etc are focused!
}
2017-09-21 18:33:05 +08:00
MouseDownPoint = e . Location ;
MouseLastPoint = MouseDownPoint ;
2020-01-14 14:56:11 +08:00
Input . CtrlPressed = ( ModifierKeys & Keys . Control ) > 0 ;
Input . ShiftPressed = ( ModifierKeys & Keys . Shift ) > 0 ;
2017-09-21 18:33:05 +08:00
2018-06-08 00:42:41 +08:00
if ( ControlMode = = WorldControlMode . Free & & ! ControlBrushEnabled )
2017-09-21 18:33:05 +08:00
{
if ( MouseLButtonDown )
{
if ( MousedMarker ! = null )
{
if ( MousedMarker . IsMovable )
{
GrabbedMarker = MousedMarker ;
}
else
{
SelectedMarker = MousedMarker ;
ShowMarkerSelectionInfo ( SelectedMarker ) ;
}
if ( GrabbedWidget ! = null )
{
GrabbedWidget . IsDragging = false ;
GrabbedWidget = null ;
}
}
else
{
2021-11-12 18:07:06 +08:00
if ( ShowWidget & & Widget . IsUnderMouse & & ! Input . kbmoving )
2017-09-21 18:33:05 +08:00
{
GrabbedWidget = Widget ;
GrabbedWidget . IsDragging = true ;
2018-01-02 04:52:54 +08:00
if ( Input . ShiftPressed )
2017-09-21 18:33:05 +08:00
{
2021-11-28 14:55:55 +08:00
var ms = CurrentMapSelection . MultipleSelectionItems ;
if ( ms ? . Length > 0 & & ms [ 0 ] . PathNode ! = null )
{
MessageBox . Show ( "You cannot clone multiple path nodes at once" , "Error" , MessageBoxButtons . OK , MessageBoxIcon . Error ) ;
GrabbedWidget . IsDragging = false ;
GrabbedWidget = null ;
} else
{
CloneItem ( ) ;
}
2017-09-21 18:33:05 +08:00
}
MarkUndoStart ( GrabbedWidget ) ;
}
else
{
if ( GrabbedWidget ! = null )
{
GrabbedWidget . IsDragging = false ;
GrabbedWidget = null ;
}
2018-01-02 04:52:54 +08:00
if ( Input . CtrlPressed )
2017-09-21 18:33:05 +08:00
{
SpawnTestEntity ( ) ;
}
}
GrabbedMarker = null ;
}
}
if ( MouseRButtonDown )
{
SelectMousedItem ( ) ;
}
}
else
{
lock ( MouseControlSyncRoot )
{
MouseControlButtons | = e . Button ;
}
}
MouseX = e . X ; //to stop jumps happening on mousedown, sometimes the last MouseMove event was somewhere else... (eg after clicked a menu)
MouseY = e . Y ;
}
private void WorldForm_MouseUp ( object sender , MouseEventArgs e )
{
switch ( e . Button )
{
case MouseButtons . Left : MouseLButtonDown = false ; break ;
case MouseButtons . Right : MouseRButtonDown = false ; break ;
}
2020-01-14 14:56:11 +08:00
Input . CtrlPressed = ( ModifierKeys & Keys . Control ) > 0 ;
Input . ShiftPressed = ( ModifierKeys & Keys . Shift ) > 0 ;
2017-09-21 18:33:05 +08:00
lock ( MouseControlSyncRoot )
{
MouseControlButtons & = ~ e . Button ;
}
if ( e . Button = = MouseButtons . Left )
{
GrabbedMarker = null ;
if ( GrabbedWidget ! = null )
{
MarkUndoEnd ( GrabbedWidget ) ;
GrabbedWidget . IsDragging = false ;
2018-02-25 20:30:29 +08:00
GrabbedWidget . Position = SelectedItem . WidgetPosition ; //in case of any snapping, make sure widget is in correct position at the end
2017-09-21 18:33:05 +08:00
GrabbedWidget = null ;
}
if ( ( e . Location = = MouseDownPoint ) & & ( MousedMarker = = null ) )
{
//was clicked. but not on a marker... deselect and hide the panel
SelectedMarker = null ;
HideMarkerSelectionInfo ( ) ;
}
2018-06-08 00:42:41 +08:00
ControlBrushTimer = 0 ;
2017-09-21 18:33:05 +08:00
}
}
private void WorldForm_MouseMove ( object sender , MouseEventArgs e )
{
int dx = e . X - MouseX ;
int dy = e . Y - MouseY ;
2020-01-14 14:56:11 +08:00
Input . CtrlPressed = ( ModifierKeys & Keys . Control ) > 0 ;
Input . ShiftPressed = ( ModifierKeys & Keys . Shift ) > 0 ;
2018-01-02 08:07:24 +08:00
if ( MouseInvert )
{
dy = - dy ;
}
2018-06-08 00:42:41 +08:00
if ( ControlMode = = WorldControlMode . Free & & ! ControlBrushEnabled )
2017-09-21 18:33:05 +08:00
{
if ( MouseLButtonDown )
{
2018-06-08 00:42:41 +08:00
RotateCam ( dx , dy ) ;
2017-09-21 18:33:05 +08:00
}
if ( MouseRButtonDown )
{
2018-01-02 04:52:54 +08:00
if ( Renderer . controllightdir )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . lightdirx + = ( dx * camera . Sensitivity ) ;
Renderer . lightdiry + = ( dy * camera . Sensitivity ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
else if ( Renderer . controltimeofday )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
float tod = Renderer . timeofday ;
tod + = ( dx - dy ) / 30.0f ;
while ( tod > = 24.0f ) tod - = 24.0f ;
while ( tod < 0.0f ) tod + = 24.0f ;
timecycle . SetTime ( tod ) ;
Renderer . timeofday = tod ;
float fv = tod * 60.0f ;
2017-09-21 18:33:05 +08:00
TimeOfDayTrackBar . Value = ( int ) fv ;
UpdateTimeOfDayLabel ( ) ;
}
}
2018-06-08 00:42:41 +08:00
UpdateMousePosition ( e ) ;
2017-09-21 18:33:05 +08:00
}
2018-06-08 00:42:41 +08:00
else if ( ControlBrushEnabled )
{
if ( MouseRButtonDown )
{
RotateCam ( dx , dy ) ;
}
UpdateMousePosition ( e ) ;
ControlBrushTimer + + ;
if ( ControlBrushTimer > ( Input . ShiftPressed ? 5 : 10 ) )
{
2018-12-05 15:26:28 +08:00
//lock (Renderer.RenderSyncRoot)
2018-06-08 00:42:41 +08:00
{
if ( ProjectForm ! = null & & MouseLButtonDown )
{
2022-07-29 21:16:13 +08:00
ProjectForm . PaintGrass ( MouseRayCollision , Input ) ;
2018-06-08 00:42:41 +08:00
}
ControlBrushTimer = 0 ;
}
}
}
2017-09-21 18:33:05 +08:00
else
{
lock ( MouseControlSyncRoot )
{
MouseControlX + = dx ;
MouseControlY + = dy ;
//MouseControlButtons = e.Button;
}
var newpos = PointToScreen ( MouseLastPoint ) ;
if ( Cursor . Position ! = newpos )
{
Cursor . Position = newpos ;
return ;
}
}
MousedMarker = FindMousedMarker ( ) ;
if ( Cursor ! = Cursors . WaitCursor )
{
if ( MousedMarker ! = null )
{
if ( MousedMarker . IsMovable )
{
Cursor = Cursors . SizeAll ;
}
else
{
Cursor = Cursors . Hand ;
}
}
else
{
Cursor = Cursors . Default ;
}
}
}
2018-06-08 00:42:41 +08:00
private void UpdateMousePosition ( MouseEventArgs e )
{
MouseX = e . X ;
MouseY = e . Y ;
MouseLastPoint = e . Location ;
}
private void RotateCam ( int dx , int dy )
{
if ( GrabbedMarker = = null )
{
if ( GrabbedWidget = = null )
{
if ( MapViewEnabled = = false )
{
camera . MouseRotate ( dx , dy ) ;
}
else
{
//need to move the camera entity XY with mouse in mapview mode...
MapViewDragX + = dx ;
MapViewDragY + = dy ;
}
}
else
{
//grabbed widget will move itself in Update() when IsDragging==true
}
}
else
{
//move the grabbed marker...
//float uptx = (CurrentMap != null) ? CurrentMap.UnitsPerTexelX : 1.0f;
//float upty = (CurrentMap != null) ? CurrentMap.UnitsPerTexelY : 1.0f;
//Vector3 wpos = GrabbedMarker.WorldPos;
//wpos.X += dx * uptx;
//wpos.Y += dy * upty;
//GrabbedMarker.WorldPos = wpos;
//UpdateMarkerTexturePos(GrabbedMarker);
//if (GrabbedMarker == LocatorMarker)
//{
// LocateTextBox.Text = LocatorMarker.ToString();
// WorldCoordTextBox.Text = LocatorMarker.Get2DWorldPosString();
// TextureCoordTextBox.Text = LocatorMarker.Get2DTexturePosString();
//}
}
}
2017-09-21 18:33:05 +08:00
private void WorldForm_MouseWheel ( object sender , MouseEventArgs e )
{
if ( e . Delta ! = 0 )
{
2018-06-08 00:42:41 +08:00
if ( ControlMode = = WorldControlMode . Free | | ControlBrushEnabled )
2017-09-21 18:33:05 +08:00
{
camera . MouseZoom ( e . Delta ) ;
}
else
{
lock ( MouseControlSyncRoot )
{
MouseControlWheel + = e . Delta ;
}
}
}
}
private void WorldForm_KeyDown ( object sender , KeyEventArgs e )
{
if ( ActiveControl is TextBox )
{
var tb = ActiveControl as TextBox ;
if ( ! tb . ReadOnly ) return ; //don't move the camera when typing!
}
if ( ActiveControl is ComboBox )
{
var cb = ActiveControl as ComboBox ;
if ( cb . DropDownStyle ! = ComboBoxStyle . DropDownList ) return ; //nontypable combobox
}
bool enablemove = ( ! iseditmode ) | | ( MouseLButtonDown & & ( GrabbedMarker = = null ) & & ( GrabbedWidget = = null ) ) ;
2018-01-02 04:52:54 +08:00
Input . KeyDown ( e , enablemove ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
var k = e . KeyCode ;
var kb = Input . keyBindings ;
bool ctrl = Input . CtrlPressed ;
bool shift = Input . ShiftPressed ;
2017-09-21 18:33:05 +08:00
if ( ! ctrl )
{
2018-01-02 04:52:54 +08:00
if ( k = = kb . MoveSlowerZoomIn )
2017-09-21 18:33:05 +08:00
{
camera . MouseZoom ( 1 ) ;
}
2018-01-02 04:52:54 +08:00
if ( k = = kb . MoveFasterZoomOut )
2017-09-21 18:33:05 +08:00
{
camera . MouseZoom ( - 1 ) ;
}
}
2021-11-12 18:07:06 +08:00
if ( ! Input . kbmoving & & ! Widget . IsDragging ) //don't trigger further actions if camera moving or widget dragging
2017-09-21 18:33:05 +08:00
{
if ( ! ctrl )
{
//switch widget modes and spaces.
2018-01-02 04:52:54 +08:00
if ( ( k = = kb . ExitEditMode ) )
2017-09-21 18:33:05 +08:00
{
if ( Widget . Mode = = WidgetMode . Default ) ToggleWidgetSpace ( ) ;
else SetWidgetMode ( "Default" ) ;
}
2018-01-02 04:52:54 +08:00
if ( ( k = = kb . EditPosition ) ) // && !enablemove)
2017-09-21 18:33:05 +08:00
{
if ( Widget . Mode = = WidgetMode . Position ) ToggleWidgetSpace ( ) ;
else SetWidgetMode ( "Position" ) ;
}
2018-01-02 04:52:54 +08:00
if ( ( k = = kb . EditRotation ) ) // && !enablemove)
2017-09-21 18:33:05 +08:00
{
if ( Widget . Mode = = WidgetMode . Rotation ) ToggleWidgetSpace ( ) ;
else SetWidgetMode ( "Rotation" ) ;
}
2018-01-02 04:52:54 +08:00
if ( ( k = = kb . EditScale ) ) // && !enablemove)
2017-09-21 18:33:05 +08:00
{
if ( Widget . Mode = = WidgetMode . Scale ) ToggleWidgetSpace ( ) ;
else SetWidgetMode ( "Scale" ) ;
}
2018-01-02 04:52:54 +08:00
if ( k = = kb . ToggleMouseSelect )
2017-09-21 18:33:05 +08:00
{
SetMouseSelect ( ! MouseSelectEnabled ) ;
}
2018-01-02 04:52:54 +08:00
if ( k = = kb . ToggleToolbar )
2017-09-21 18:33:05 +08:00
{
ToggleToolbar ( ) ;
}
2018-01-02 04:52:54 +08:00
if ( k = = kb . FirstPerson )
2017-09-21 18:33:05 +08:00
{
SetControlMode ( ( ControlMode = = WorldControlMode . Free ) ? WorldControlMode . Ped : WorldControlMode . Free ) ;
}
2018-01-02 04:52:54 +08:00
if ( k = = Keys . Delete )
{
DeleteItem ( ) ;
}
2023-09-04 18:48:50 +08:00
if ( SelectionMode = = MapSelectionMode . Path )
{
if ( k = = Keys . J )
{
TryCreateNodeLink ( ) ;
}
if ( k = = Keys . K )
{
TryCreateNodeShortcut ( ) ;
}
}
2017-09-21 18:33:05 +08:00
}
else
{
switch ( k )
{
case Keys . N :
New ( ) ;
break ;
case Keys . O :
Open ( ) ;
break ;
case Keys . S :
if ( shift ) SaveAll ( ) ;
else Save ( ) ;
break ;
case Keys . Z :
Undo ( ) ;
break ;
case Keys . Y :
Redo ( ) ;
break ;
case Keys . C :
CopyItem ( ) ;
break ;
case Keys . V :
PasteItem ( ) ;
break ;
case Keys . U :
ToolsPanelShowButton . Visible = ! ToolsPanelShowButton . Visible ;
break ;
}
}
2021-11-12 18:07:06 +08:00
}
if ( k = = Keys . Escape ) //temporary? panic get cursor back when in first person mode
{
if ( ControlMode ! = WorldControlMode . Free ) SetControlMode ( WorldControlMode . Free ) ;
2017-09-21 18:33:05 +08:00
}
2018-06-08 00:42:41 +08:00
if ( ControlMode ! = WorldControlMode . Free | | ControlBrushEnabled )
2017-09-21 18:33:05 +08:00
{
e . Handled = true ;
}
}
private void WorldForm_KeyUp ( object sender , KeyEventArgs e )
{
2018-01-02 04:52:54 +08:00
Input . KeyUp ( e ) ;
2017-09-21 18:33:05 +08:00
if ( ActiveControl is TextBox )
{
var tb = ActiveControl as TextBox ;
if ( ! tb . ReadOnly ) return ; //don't move the camera when typing!
}
if ( ActiveControl is ComboBox )
{
var cb = ActiveControl as ComboBox ;
if ( cb . DropDownStyle ! = ComboBoxStyle . DropDownList ) return ; //non-typable combobox
}
if ( ControlMode ! = WorldControlMode . Free )
{
e . Handled = true ;
}
}
2017-09-26 08:27:18 +08:00
private void WorldForm_Deactivate ( object sender , EventArgs e )
{
//try not to lock keyboard movement if the form loses focus.
2018-01-02 04:52:54 +08:00
Input . KeyboardStop ( ) ;
2017-09-26 08:27:18 +08:00
}
2017-09-21 18:33:05 +08:00
private void ViewModeComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
bool prevmodel = ! ( rendermaps | | renderworld ) ;
string mode = ( string ) ViewModeComboBox . SelectedItem ;
switch ( mode )
{
case "World view" :
rendermaps = false ;
renderworld = true ;
ViewTabControl . SelectedTab = ViewWorldTabPage ;
break ;
case "Ymap view" :
rendermaps = true ;
renderworld = false ;
ViewTabControl . SelectedTab = ViewYmapsTabPage ;
break ;
case "Model view" :
rendermaps = false ;
renderworld = false ;
ViewTabControl . SelectedTab = ViewModelTabPage ;
2022-01-01 02:54:19 +08:00
if ( SelectionNameTextBox . Text ! = "" & & SelectionNameTextBox . Text ! = "Nothing selected" )
{
modelname = SelectionNameTextBox . Text ;
}
2017-09-21 18:33:05 +08:00
break ;
}
if ( ( camera = = null ) | | ( camera . FollowEntity = = null ) ) return ;
if ( rendermaps | | renderworld )
{
if ( prevmodel ) //only change location if the last mode was model mode
{
camera . FollowEntity . Position = prevworldpos ;
}
}
else
{
prevworldpos = camera . FollowEntity . Position ;
camera . FollowEntity . Position = new Vector3 ( 0.0f , 0.0f , 0.0f ) ;
}
}
private void ModelComboBox_TextUpdate ( object sender , EventArgs e )
{
modelname = ModelComboBox . Text ;
}
private void ModelComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
modelname = ModelComboBox . Text ;
}
private void YmapsTextBox_TextChanged ( object sender , EventArgs e )
{
ymaplist = YmapsTextBox . Text . Split ( new [ ] { "\r\n" } , StringSplitOptions . RemoveEmptyEntries ) ;
}
private void ToolsPanelHideButton_Click ( object sender , EventArgs e )
{
ToolsPanel . Visible = false ;
ToolsPanelShowButton . Focus ( ) ;
}
private void ToolsPanelShowButton_Click ( object sender , EventArgs e )
{
ToolsPanel . Visible = true ;
ToolsPanelHideButton . Focus ( ) ;
}
private void WireframeCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . shaders . wireframe = WireframeCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void GrassCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . rendergrass = GrassCheckBox . Checked ;
2018-12-23 12:29:35 +08:00
}
private void CarGeneratorsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
Renderer . rendercars = CarGeneratorsCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void TimedEntitiesCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . rendertimedents = TimedEntitiesCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void TimedEntitiesAlwaysOnCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . rendertimedentsalways = TimedEntitiesAlwaysOnCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void InteriorsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . renderinteriors = InteriorsCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void WaterQuadsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
renderwaterquads = WaterQuadsCheckBox . Checked ;
}
private void ProxiesCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . renderproxies = ProxiesCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
2019-01-06 02:04:33 +08:00
private void HDTexturesCheckBox_CheckedChanged ( object sender , EventArgs e )
{
Renderer . renderhdtextures = HDTexturesCheckBox . Checked ;
}
2019-11-01 19:51:39 +08:00
private void NearClipUpDown_ValueChanged ( object sender , EventArgs e )
{
camera . ZNear = ( float ) NearClipUpDown . Value ;
camera . UpdateProj = true ;
}
private void FarClipUpDown_ValueChanged ( object sender , EventArgs e )
{
camera . ZFar = ( float ) FarClipUpDown . Value ;
camera . UpdateProj = true ;
}
2017-09-21 18:33:05 +08:00
private void PathsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
renderpaths = PathsCheckBox . Checked ;
}
private void PathBoundsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
renderpathbounds = PathBoundsCheckBox . Checked ;
}
private void TrainPathsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
rendertraintracks = TrainPathsCheckBox . Checked ;
}
private void NavMeshesCheckBox_CheckedChanged ( object sender , EventArgs e )
{
rendernavmeshes = NavMeshesCheckBox . Checked ;
}
private void PathsDepthClipCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . shaders . PathsDepthClip = PathsDepthClipCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void ErrorConsoleCheckBox_CheckedChanged ( object sender , EventArgs e )
{
ConsolePanel . Visible = ErrorConsoleCheckBox . Checked ;
}
private void DynamicLODCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . usedynamiclod = DynamicLODCheckBox . Checked ;
ShowYmapChildrenCheckBox . Enabled = ! Renderer . usedynamiclod ;
2017-09-21 18:33:05 +08:00
}
private void DetailTrackBar_Scroll ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . lodthreshold = 50.0f / ( 0.1f + ( float ) DetailTrackBar . Value ) ;
2017-09-21 18:33:05 +08:00
}
private void WaitForChildrenCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . waitforchildrentoload = WaitForChildrenCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void ReloadShadersButton_Click ( object sender , EventArgs e )
{
2024-08-05 18:24:59 +08:00
//### NO LONGER USED
2018-01-02 04:52:54 +08:00
if ( Renderer . Device = = null ) return ; //can't do this with no device
2017-09-21 18:33:05 +08:00
Cursor = Cursors . WaitCursor ;
pauserendering = true ;
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
try
{
2018-01-02 04:52:54 +08:00
Renderer . ReloadShaders ( ) ;
2017-09-21 18:33:05 +08:00
}
catch ( Exception ex )
{
MessageBox . Show ( "Error loading shaders!\n" + ex . ToString ( ) ) ;
return ;
}
}
pauserendering = false ;
Cursor = Cursors . Default ;
}
private void MarkerStyleComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
MapIcon icon = MarkerStyleComboBox . SelectedItem as MapIcon ;
if ( icon ! = MarkerIcon )
{
MarkerIcon = icon ;
foreach ( MapMarker m in Markers )
{
m . Icon = icon ;
}
}
}
private void LocatorStyleComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
MapIcon icon = LocatorStyleComboBox . SelectedItem as MapIcon ;
if ( icon ! = LocatorIcon )
{
LocatorIcon = icon ;
LocatorMarker . Icon = icon ;
}
}
private void ShowLocatorCheckBox_CheckedChanged ( object sender , EventArgs e )
{
RenderLocator = ShowLocatorCheckBox . Checked ;
}
private void LocateTextBox_TextChanged ( object sender , EventArgs e )
{
if ( GrabbedMarker = = LocatorMarker ) return ; //don't try to update the marker if it's being dragged
if ( LocatorMarker = = null ) return ; //this shouldn't happen, but anyway
LocatorMarker . Parse ( LocateTextBox . Text ) ;
//UpdateMarkerTexturePos(LocatorMarker);
}
private void GoToButton_Click ( object sender , EventArgs e )
{
GoToMarker ( LocatorMarker ) ;
}
private void AddMarkersButton_Click ( object sender , EventArgs e )
{
string [ ] lines = MultiFindTextBox . Text . Split ( '\n' ) ;
foreach ( string line in lines )
{
AddMarker ( line ) ;
}
}
private void ClearMarkersButton_Click ( object sender , EventArgs e )
{
MultiFindTextBox . Text = string . Empty ;
Markers . Clear ( ) ;
}
private void ResetMarkersButton_Click ( object sender , EventArgs e )
{
Markers . Clear ( ) ;
AddDefaultMarkers ( ) ;
}
private void AddCurrentPositonMarkerButton_Click ( object sender , EventArgs e )
{
AddMarker ( camera . Position , "Marker" , true ) ;
}
private void AddSelectionMarkerButton_Click ( object sender , EventArgs e )
{
if ( SelectedItem . EntityDef = = null )
{ return ; }
Vector3 pos = SelectedItem . EntityDef . Position ;
string name = SelectedItem . EntityDef . CEntityDef . archetypeName . ToString ( ) ;
var marker = AddMarker ( pos , name , true ) ;
SelectedMarker = marker ;
ShowMarkerSelectionInfo ( SelectedMarker ) ;
}
private void MarkerDepthClipCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . markerdepthclip = MarkerDepthClipCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void ShadowsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . shaders . shadows = ShadowsCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
}
private void SkydomeCheckbox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . renderskydome = SkydomeCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void BoundsStyleComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
var val = BoundsStyleComboBox . SelectedItem ;
var strval = val as string ;
SetBoundsMode ( strval ) ;
}
private void BoundsDepthClipCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . renderboundsclip = BoundsDepthClipCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void BoundsRangeTrackBar_Scroll ( object sender , EventArgs e )
{
float fv = BoundsRangeTrackBar . Value ;
2018-01-02 04:52:54 +08:00
Renderer . renderboundsmaxdist = fv * fv ;
2017-09-21 18:33:05 +08:00
}
private void MouseSelectCheckBox_CheckedChanged ( object sender , EventArgs e )
{
SetMouseSelect ( MouseSelectCheckBox . Checked ) ;
}
private void SelectionBoundsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
ShowSelectionBounds = SelectionBoundsCheckBox . Checked ;
}
2017-09-22 15:31:02 +08:00
private void PopZonesCheckBox_CheckedChanged ( object sender , EventArgs e )
{
renderpopzones = PopZonesCheckBox . Checked ;
}
2018-01-02 04:52:54 +08:00
private void SkeletonsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
Renderer . renderskeletons = SkeletonsCheckBox . Checked ;
}
2017-12-24 19:49:04 +08:00
private void AudioOuterBoundsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
renderaudioouterbounds = AudioOuterBoundsCheckBox . Checked ;
}
2017-09-21 18:33:05 +08:00
private void ToolsPanelExpandButton_Click ( object sender , EventArgs e )
{
toolspanelexpanded = ! toolspanelexpanded ;
int oldwidth = ToolsPanel . Width ;
if ( toolspanelexpanded )
{
ToolsPanelExpandButton . Text = ">>" ;
}
else
{
ToolsPanelExpandButton . Text = "<<" ;
}
ToolsPanel . Width = toolspanellastwidth ; //or extended width
ToolsPanel . Left - = ( toolspanellastwidth - oldwidth ) ;
toolspanellastwidth = oldwidth ;
}
private void ToolsDragPanel_MouseDown ( object sender , MouseEventArgs e )
{
if ( e . Button = = MouseButtons . Left )
{
toolsPanelResizing = true ;
toolsPanelResizeStartX = e . X + ToolsPanel . Left ;
toolsPanelResizeStartLeft = ToolsPanel . Left ;
toolsPanelResizeStartRight = ToolsPanel . Right ;
}
}
private void ToolsDragPanel_MouseUp ( object sender , MouseEventArgs e )
{
toolsPanelResizing = false ;
}
private void ToolsDragPanel_MouseMove ( object sender , MouseEventArgs e )
{
if ( toolsPanelResizing )
{
int rx = e . X + ToolsPanel . Left ;
int dx = rx - toolsPanelResizeStartX ;
ToolsPanel . Left = toolsPanelResizeStartLeft + dx ;
ToolsPanel . Width = toolsPanelResizeStartRight - toolsPanelResizeStartLeft - dx ;
}
}
private void FullScreenCheckBox_CheckedChanged ( object sender , EventArgs e )
{
SetFullscreen ( FullScreenCheckBox . Checked ) ;
}
private void ControlSettingsButton_Click ( object sender , EventArgs e )
{
ShowSettingsForm ( "Controls" ) ;
}
private void AdvancedSettingsButton_Click ( object sender , EventArgs e )
{
ShowSettingsForm ( "Advanced" ) ;
}
2024-08-05 18:24:59 +08:00
private void ResetSettingsButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2024-08-05 18:24:59 +08:00
ResetSettings ( ) ;
2017-09-21 18:33:05 +08:00
}
private void SaveSettingsButton_Click ( object sender , EventArgs e )
{
SaveSettings ( ) ;
}
private void AboutButton_Click ( object sender , EventArgs e )
{
AboutForm f = new AboutForm ( ) ;
f . Show ( this ) ;
}
private void ToolsButton_Click ( object sender , EventArgs e )
{
ToolsMenu . Show ( ToolsButton , 0 , ToolsButton . Height ) ;
}
private void ToolsMenuRPFBrowser_Click ( object sender , EventArgs e )
{
BrowseForm f = new BrowseForm ( ) ;
f . Show ( this ) ;
}
private void ToolsMenuRPFExplorer_Click ( object sender , EventArgs e )
{
ExploreForm f = new ExploreForm ( ) ;
f . Show ( this ) ;
}
private void ToolsMenuSelectionInfo_Click ( object sender , EventArgs e )
{
ShowInfoForm ( ) ;
}
private void ToolsMenuProjectWindow_Click ( object sender , EventArgs e )
{
ShowProjectForm ( ) ;
}
2019-11-25 17:44:16 +08:00
private void ToolsMenuCutsceneViewer_Click ( object sender , EventArgs e )
{
ShowCutsceneForm ( ) ;
}
2022-01-13 02:07:07 +08:00
private void ToolsMenuAudioExplorer_Click ( object sender , EventArgs e )
{
AudioExplorerForm f = new AudioExplorerForm ( gameFileCache ) ;
f . Show ( this ) ;
}
2017-09-21 18:33:05 +08:00
private void ToolsMenuWorldSearch_Click ( object sender , EventArgs e )
{
ShowSearchForm ( ) ;
}
private void ToolsMenuBinarySearch_Click ( object sender , EventArgs e )
{
2017-12-24 19:49:04 +08:00
BinarySearchForm f = new BinarySearchForm ( gameFileCache ) ;
2017-09-21 18:33:05 +08:00
f . Show ( this ) ;
}
private void ToolsMenuJenkGen_Click ( object sender , EventArgs e )
{
JenkGenForm f = new JenkGenForm ( ) ;
f . Show ( this ) ;
}
private void ToolsMenuJenkInd_Click ( object sender , EventArgs e )
{
JenkIndForm f = new JenkIndForm ( gameFileCache ) ;
f . Show ( this ) ;
}
private void ToolsMenuExtractScripts_Click ( object sender , EventArgs e )
{
ExtractScriptsForm f = new ExtractScriptsForm ( ) ;
f . Show ( this ) ;
}
private void ToolsMenuExtractTextures_Click ( object sender , EventArgs e )
{
ExtractTexForm f = new ExtractTexForm ( ) ;
f . Show ( this ) ;
}
private void ToolsMenuExtractRawFiles_Click ( object sender , EventArgs e )
{
ExtractRawForm f = new ExtractRawForm ( ) ;
f . Show ( this ) ;
}
private void ToolsMenuExtractShaders_Click ( object sender , EventArgs e )
{
ExtractShadersForm f = new ExtractShadersForm ( ) ;
f . Show ( this ) ;
}
private void ToolsMenuOptions_Click ( object sender , EventArgs e )
{
ShowSettingsForm ( ) ;
}
private void StatusBarCheckBox_CheckedChanged ( object sender , EventArgs e )
{
StatusStrip . Visible = StatusBarCheckBox . Checked ;
}
private void RenderModeComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
TextureSamplerComboBox . Enabled = false ;
TextureCoordsComboBox . Enabled = false ;
switch ( RenderModeComboBox . Text )
{
default :
case "Default" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . Default ;
2017-09-21 18:33:05 +08:00
break ;
case "Single texture" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . SingleTexture ;
2017-09-21 18:33:05 +08:00
TextureSamplerComboBox . Enabled = true ;
TextureCoordsComboBox . Enabled = true ;
break ;
case "Vertex normals" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . VertexNormals ;
2017-09-21 18:33:05 +08:00
break ;
case "Vertex tangents" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . VertexTangents ;
2017-09-21 18:33:05 +08:00
break ;
case "Vertex colour 1" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . VertexColour ;
Renderer . shaders . RenderVertexColourIndex = 1 ;
2017-09-21 18:33:05 +08:00
break ;
case "Vertex colour 2" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . VertexColour ;
Renderer . shaders . RenderVertexColourIndex = 2 ;
2017-09-21 18:33:05 +08:00
break ;
case "Vertex colour 3" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . VertexColour ;
Renderer . shaders . RenderVertexColourIndex = 3 ;
2017-09-21 18:33:05 +08:00
break ;
case "Texture coord 1" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . TextureCoord ;
Renderer . shaders . RenderTextureCoordIndex = 1 ;
2017-09-21 18:33:05 +08:00
break ;
case "Texture coord 2" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . TextureCoord ;
Renderer . shaders . RenderTextureCoordIndex = 2 ;
2017-09-21 18:33:05 +08:00
break ;
case "Texture coord 3" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderMode = WorldRenderMode . TextureCoord ;
Renderer . shaders . RenderTextureCoordIndex = 3 ;
2017-09-21 18:33:05 +08:00
break ;
}
}
private void TextureSamplerComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
2019-10-31 14:11:12 +08:00
if ( TextureSamplerComboBox . SelectedItem is ShaderParamNames )
2017-09-21 18:33:05 +08:00
{
2019-10-31 14:11:12 +08:00
Renderer . shaders . RenderTextureSampler = ( ShaderParamNames ) TextureSamplerComboBox . SelectedItem ;
2017-09-21 18:33:05 +08:00
}
}
private void TextureCoordsComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
switch ( TextureCoordsComboBox . Text )
{
default :
case "Texture coord 1" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderTextureSamplerCoord = 1 ;
2017-09-21 18:33:05 +08:00
break ;
case "Texture coord 2" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderTextureSamplerCoord = 2 ;
2017-09-21 18:33:05 +08:00
break ;
case "Texture coord 3" :
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderTextureSamplerCoord = 3 ;
2017-09-21 18:33:05 +08:00
break ;
}
}
private void CollisionMeshesCheckBox_CheckedChanged ( object sender , EventArgs e )
{
rendercollisionmeshes = CollisionMeshesCheckBox . Checked ;
2018-01-02 04:52:54 +08:00
Renderer . rendercollisionmeshes = rendercollisionmeshes ;
2017-09-21 18:33:05 +08:00
}
private void CollisionMeshRangeTrackBar_Scroll ( object sender , EventArgs e )
{
collisionmeshrange = CollisionMeshRangeTrackBar . Value ;
}
private void CollisionMeshLayer0CheckBox_CheckedChanged ( object sender , EventArgs e )
{
collisionmeshlayers [ 0 ] = CollisionMeshLayer0CheckBox . Checked ;
}
private void CollisionMeshLayer1CheckBox_CheckedChanged ( object sender , EventArgs e )
{
collisionmeshlayers [ 1 ] = CollisionMeshLayer1CheckBox . Checked ;
}
private void CollisionMeshLayer2CheckBox_CheckedChanged ( object sender , EventArgs e )
{
collisionmeshlayers [ 2 ] = CollisionMeshLayer2CheckBox . Checked ;
}
private void CollisionMeshLayerDrawableCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . rendercollisionmeshlayerdrawable = CollisionMeshLayerDrawableCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void ControlLightDirectionCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . controllightdir = ControlLightDirectionCheckBox . Checked ;
if ( Renderer . controllightdir )
2017-09-21 18:33:05 +08:00
{
ControlTimeOfDayCheckBox . Checked = false ;
}
}
private void ControlTimeOfDayCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . controltimeofday = ControlTimeOfDayCheckBox . Checked ;
if ( Renderer . controltimeofday )
2017-09-21 18:33:05 +08:00
{
ControlLightDirectionCheckBox . Checked = false ;
}
}
private void ShowYmapChildrenCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . renderchildents = ShowYmapChildrenCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
2019-12-03 21:52:22 +08:00
private void DeferredShadingCheckBox_CheckedChanged ( object sender , EventArgs e )
{
lock ( Renderer . RenderSyncRoot )
{
Renderer . shaders . deferred = DeferredShadingCheckBox . Checked ;
}
}
2017-09-21 18:33:05 +08:00
private void HDRRenderingCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . shaders . hdr = HDRRenderingCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
}
private void AnisotropicFilteringCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . shaders . AnisotropicFiltering = AnisotropicFilteringCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void WorldMaxLodComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
switch ( WorldMaxLodComboBox . Text )
{
default :
case "ORPHANHD" :
2019-01-13 16:51:49 +08:00
Renderer . renderworldMaxLOD = rage__eLodType . LODTYPES_DEPTH_ORPHANHD ;
2017-09-21 18:33:05 +08:00
break ;
case "HD" :
2019-01-13 16:51:49 +08:00
Renderer . renderworldMaxLOD = rage__eLodType . LODTYPES_DEPTH_HD ;
2017-09-21 18:33:05 +08:00
break ;
case "LOD" :
2019-01-13 16:51:49 +08:00
Renderer . renderworldMaxLOD = rage__eLodType . LODTYPES_DEPTH_LOD ;
2017-09-21 18:33:05 +08:00
break ;
case "SLOD1" :
2019-01-13 16:51:49 +08:00
Renderer . renderworldMaxLOD = rage__eLodType . LODTYPES_DEPTH_SLOD1 ;
2017-09-21 18:33:05 +08:00
break ;
case "SLOD2" :
2019-01-13 16:51:49 +08:00
Renderer . renderworldMaxLOD = rage__eLodType . LODTYPES_DEPTH_SLOD2 ;
2017-09-21 18:33:05 +08:00
break ;
case "SLOD3" :
2019-01-13 16:51:49 +08:00
Renderer . renderworldMaxLOD = rage__eLodType . LODTYPES_DEPTH_SLOD3 ;
2017-09-21 18:33:05 +08:00
break ;
case "SLOD4" :
2019-01-13 16:51:49 +08:00
Renderer . renderworldMaxLOD = rage__eLodType . LODTYPES_DEPTH_SLOD4 ;
2017-09-21 18:33:05 +08:00
break ;
}
}
private void WorldLodDistTrackBar_Scroll ( object sender , EventArgs e )
{
float loddist = ( ( float ) WorldLodDistTrackBar . Value ) * 0.1f ;
2018-01-02 04:52:54 +08:00
Renderer . renderworldLodDistMult = loddist ;
2017-09-21 18:33:05 +08:00
WorldLodDistLabel . Text = loddist . ToString ( "0.0" ) ;
}
private void WorldDetailDistTrackBar_Scroll ( object sender , EventArgs e )
{
float detdist = ( ( float ) WorldDetailDistTrackBar . Value ) * 0.1f ;
2018-01-02 04:52:54 +08:00
Renderer . renderworldDetailDistMult = detdist ;
2017-09-21 18:33:05 +08:00
WorldDetailDistLabel . Text = detdist . ToString ( "0.0" ) ;
}
private void WorldScriptedYmapsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . ShowScriptedYmaps = WorldScriptedYmapsCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void WorldYmapTimeFilterCheckBox_CheckedChanged ( object sender , EventArgs e )
{
worldymaptimefilter = WorldYmapTimeFilterCheckBox . Checked ;
}
private void WorldYmapWeatherFilterCheckBox_CheckedChanged ( object sender , EventArgs e )
{
worldymapweatherfilter = WorldYmapWeatherFilterCheckBox . Checked ;
}
private void EnableModsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
if ( ! initialised ) return ;
if ( ProjectForm ! = null )
{
MessageBox . Show ( "Please close the Project Window before enabling or disabling mods." ) ;
return ;
}
SetModsEnabled ( EnableModsCheckBox . Checked ) ;
}
private void EnableDlcCheckBox_CheckedChanged ( object sender , EventArgs e )
{
if ( ! initialised ) return ;
if ( ProjectForm ! = null )
{
MessageBox . Show ( "Please close the Project Window before enabling or disabling DLC." ) ;
return ;
}
SetDlcLevel ( DlcLevelComboBox . Text , EnableDlcCheckBox . Checked ) ;
}
private void DlcLevelComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
if ( ! initialised ) return ;
if ( ProjectForm ! = null )
{
MessageBox . Show ( "Please close the Project Window before changing the DLC level." ) ;
return ;
}
SetDlcLevel ( DlcLevelComboBox . Text , EnableDlcCheckBox . Checked ) ;
}
private void TimeOfDayTrackBar_Scroll ( object sender , EventArgs e )
{
2021-11-07 22:13:52 +08:00
SetTimeOfDay ( TimeOfDayTrackBar . Value ) ;
2017-09-21 18:33:05 +08:00
}
private void WeatherComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . SetWeatherType ( WeatherComboBox . Text ) ;
2017-09-21 18:33:05 +08:00
}
private void WeatherRegionComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
weather . Region = WeatherRegionComboBox . Text ;
}
private void CloudsComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
//if (!Monitor.TryEnter(rendersyncroot, 50))
//{ return; } //couldn't get a lock...
2018-01-02 04:52:54 +08:00
Renderer . individualcloudfrag = CloudsComboBox . Text ;
2017-09-21 18:33:05 +08:00
//Monitor.Exit(rendersyncroot);
}
2021-05-03 20:59:31 +08:00
private void HDLightsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
Renderer . renderlights = HDLightsCheckBox . Checked ;
}
2019-12-11 21:35:00 +08:00
private void LODLightsCheckBox_CheckedChanged ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2019-12-11 21:35:00 +08:00
Renderer . renderdistlodlights = LODLightsCheckBox . Checked ;
Renderer . renderlodlights = LODLightsCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void NaturalAmbientLightCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . rendernaturalambientlight = NaturalAmbientLightCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void ArtificialAmbientLightCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . renderartificialambientlight = ArtificialAmbientLightCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void TimeStartStopButton_Click ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . timerunning = ! Renderer . timerunning ;
TimeStartStopButton . Text = Renderer . timerunning ? "Stop" : "Start" ;
2017-09-21 18:33:05 +08:00
}
private void TimeSpeedTrackBar_Scroll ( object sender , EventArgs e )
{
float tv = TimeSpeedTrackBar . Value * 0.01f ;
//when tv=0, speed=0 min/sec
//when tv=0.5, speed=0.5 min/sec
//when tv=1, speed=128 min/sec
2018-01-02 04:52:54 +08:00
Renderer . timespeed = 128.0f * tv * tv * tv * tv * tv * tv * tv * tv ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
TimeSpeedLabel . Text = Renderer . timespeed . ToString ( "0.###" ) + " min/sec" ;
2017-09-21 18:33:05 +08:00
}
private void CameraModeComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
SetCameraMode ( CameraModeComboBox . Text ) ;
}
private void MapViewDetailTrackBar_Scroll ( object sender , EventArgs e )
{
float det = ( ( float ) MapViewDetailTrackBar . Value ) * 0.1f ;
MapViewDetailLabel . Text = det . ToString ( "0.0#" ) ;
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . MapViewDetail = det ;
2017-09-21 18:33:05 +08:00
}
}
private void FieldOfViewTrackBar_Scroll ( object sender , EventArgs e )
{
float fov = FieldOfViewTrackBar . Value * 0.01f ;
FieldOfViewLabel . Text = fov . ToString ( "0.0#" ) ;
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
camera . FieldOfView = fov ;
camera . UpdateProj = true ;
}
}
private void CloudParamComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
CloudAnimSetting setting = CloudParamComboBox . SelectedItem as CloudAnimSetting ;
if ( setting ! = null )
{
float rng = setting . MaxValue - setting . MinValue ;
float cval = ( setting . CurrentValue - setting . MinValue ) / rng ;
int ival = ( int ) ( cval * 200.0f ) ;
ival = Math . Min ( Math . Max ( ival , 0 ) , 200 ) ;
CloudParamTrackBar . Value = ival ;
}
}
private void CloudParamTrackBar_Scroll ( object sender , EventArgs e )
{
CloudAnimSetting setting = CloudParamComboBox . SelectedItem as CloudAnimSetting ;
if ( setting ! = null )
{
float rng = setting . MaxValue - setting . MinValue ;
float fval = CloudParamTrackBar . Value / 200.0f ;
float cval = ( fval * rng ) + setting . MinValue ;
setting . CurrentValue = cval ;
}
}
private void SelDrawableModelsTreeView_AfterCheck ( object sender , TreeViewEventArgs e )
{
if ( e . Node ! = null )
{
UpdateSelectionDrawFlags ( e . Node ) ;
if ( InfoForm ! = null )
{
InfoForm . SyncSelDrawableModelsTreeNode ( e . Node ) ;
}
}
}
private void SelDrawableModelsTreeView_NodeMouseDoubleClick ( object sender , TreeNodeMouseClickEventArgs e )
{
if ( e . Node ! = null )
{
e . Node . Checked = ! e . Node . Checked ;
//UpdateSelectionDrawFlags(e.Node);
}
}
private void SelDrawableModelsTreeView_KeyPress ( object sender , KeyPressEventArgs e )
{
e . Handled = true ; //stops annoying ding sound...
}
private void SelectionWidgetCheckBox_CheckedChanged ( object sender , EventArgs e )
{
ShowWidget = SelectionWidgetCheckBox . Checked ;
}
private void ShowToolbarCheckBox_CheckedChanged ( object sender , EventArgs e )
{
ToolbarPanel . Visible = ShowToolbarCheckBox . Checked ;
}
private void ToolbarNewButton_ButtonClick ( object sender , EventArgs e )
{
New ( ) ;
}
private void ToolbarNewProjectButton_Click ( object sender , EventArgs e )
{
NewProject ( ) ;
}
private void ToolbarNewYmapButton_Click ( object sender , EventArgs e )
{
NewYmap ( ) ;
}
2020-01-08 21:44:35 +08:00
private void ToolbarNewYtypButton_Click ( object sender , EventArgs e )
{
NewYtyp ( ) ;
}
private void ToolbarNewYbnButton_Click ( object sender , EventArgs e )
{
NewYbn ( ) ;
}
2017-09-21 18:33:05 +08:00
private void ToolbarNewYndButton_Click ( object sender , EventArgs e )
{
NewYnd ( ) ;
}
2018-01-02 04:52:54 +08:00
private void ToolbarNewTrainsButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
NewTrainTrack ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarNewScenarioButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
NewScenario ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarOpenButton_ButtonClick ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Open ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarOpenProjectButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
OpenProject ( ) ;
2017-09-21 18:33:05 +08:00
}
2022-01-09 17:59:10 +08:00
private void ToolbarOpenFilesButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2022-01-09 17:59:10 +08:00
OpenFiles ( ) ;
2017-09-21 18:33:05 +08:00
}
2022-01-09 17:59:10 +08:00
private void ToolbarOpenFolderButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2022-01-09 17:59:10 +08:00
OpenFolder ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSaveButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Save ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSaveAllButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SaveAll ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectButton_ButtonClick ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetMouseSelect ( ! ToolbarSelectButton . Checked ) ;
SetWidgetMode ( "Default" ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectEntityButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Entity" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectEntityExtensionButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Entity Extension" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectArchetypeExtensionButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Archetype Extension" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectTimeCycleModifierButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Time Cycle Modifier" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectCarGeneratorButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Car Generator" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectGrassButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Grass" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectWaterQuadButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Water Quad" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2021-12-02 16:15:12 +08:00
private void ToolbarSelectCalmingQuadButton_Click ( object sender , EventArgs e )
{
SetSelectionMode ( "Water Calming Quad" ) ;
SetMouseSelect ( true ) ;
}
private void ToolbarSelectWaveQuadButton_Click ( object sender , EventArgs e )
{
SetSelectionMode ( "Water Wave Quad" ) ;
SetMouseSelect ( true ) ;
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectCollisionButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Collision" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectNavMeshButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Nav Mesh" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectPathButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Path" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectTrainTrackButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Train Track" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2021-04-22 13:16:11 +08:00
private void ToolbarSelectLodLightsButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2021-04-22 13:16:11 +08:00
SetSelectionMode ( "Lod Lights" ) ;
2018-01-02 04:52:54 +08:00
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectMloInstanceButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Mlo Instance" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectScenarioButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Scenario" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarSelectAudioButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( "Audio" ) ;
SetMouseSelect ( true ) ;
2017-09-21 18:33:05 +08:00
}
2018-12-14 22:46:48 +08:00
private void ToolbarSelectOcclusionButton_Click ( object sender , EventArgs e )
{
SetSelectionMode ( "Occlusion" ) ;
SetMouseSelect ( true ) ;
}
2018-01-02 04:52:54 +08:00
private void ToolbarMoveButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetWidgetMode ( ToolbarMoveButton . Checked ? "Default" : "Position" ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarRotateButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetWidgetMode ( ToolbarRotateButton . Checked ? "Default" : "Rotation" ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarScaleButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetWidgetMode ( ToolbarScaleButton . Checked ? "Default" : "Scale" ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarTransformSpaceButton_ButtonClick ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetWidgetSpace ( Widget . ObjectSpace ? "World space" : "Object space" ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarObjectSpaceButton_Click ( object sender , EventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
SetWidgetSpace ( "Object space" ) ;
2017-09-26 08:27:18 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarWorldSpaceButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
SetWidgetSpace ( "World space" ) ;
2017-09-21 18:33:05 +08:00
}
2018-02-25 20:30:29 +08:00
private void ToolbarSnapButton_ButtonClick ( object sender , EventArgs e )
{
if ( SnapMode = = WorldSnapMode . None )
{
SetSnapMode ( SnapModePrev ) ;
}
else
{
SetSnapMode ( WorldSnapMode . None ) ;
}
}
private void ToolbarSnapToGroundButton_Click ( object sender , EventArgs e )
{
SetSnapMode ( WorldSnapMode . Ground ) ;
}
private void ToolbarSnapToGridButton_Click ( object sender , EventArgs e )
{
SetSnapMode ( WorldSnapMode . Grid ) ;
}
private void ToolbarSnapToGroundGridButton_Click ( object sender , EventArgs e )
{
SetSnapMode ( WorldSnapMode . Hybrid ) ;
}
2020-01-15 12:26:35 +08:00
private void ToolbarRotationSnappingOffButton_Click ( object sender , EventArgs e )
{
SetRotationSnapping ( 0 ) ;
}
private void ToolbarRotationSnapping1Button_Click ( object sender , EventArgs e )
{
SetRotationSnapping ( 1 ) ;
}
private void ToolbarRotationSnapping2Button_Click ( object sender , EventArgs e )
{
SetRotationSnapping ( 2 ) ;
}
private void ToolbarRotationSnapping5Button_Click ( object sender , EventArgs e )
{
SetRotationSnapping ( 5 ) ;
}
private void ToolbarRotationSnapping10Button_Click ( object sender , EventArgs e )
{
SetRotationSnapping ( 10 ) ;
}
private void ToolbarRotationSnapping45Button_Click ( object sender , EventArgs e )
{
SetRotationSnapping ( 45 ) ;
}
private void ToolbarRotationSnapping90Button_Click ( object sender , EventArgs e )
{
SetRotationSnapping ( 90 ) ;
}
private void ToolbarRotationSnappingCustomButton_Click ( object sender , EventArgs e )
{
ToolsPanel . Visible = true ;
ToolsTabControl . SelectedTab = OptionsTabPage ;
OptionsTabControl . SelectedTab = OptionsHelpersTabPage ;
SnapAngleUpDown . Focus ( ) ;
}
private void ToolbarSnapGridSizeButton_Click ( object sender , EventArgs e )
{
ToolsPanel . Visible = true ;
ToolsTabControl . SelectedTab = OptionsTabPage ;
OptionsTabControl . SelectedTab = OptionsHelpersTabPage ;
SnapGridSizeUpDown . Focus ( ) ;
}
2018-01-02 04:52:54 +08:00
private void ToolbarUndoButton_ButtonClick ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Undo ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarUndoListButton_Click ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
var tsi = sender as ToolStripItem ;
if ( tsi = = null ) return ;
var step = tsi . Tag as UndoStep ;
if ( step = = null ) return ;
if ( UndoSteps . Count = = 0 ) return ;
var cstep = UndoSteps . Peek ( ) ;
while ( cstep ! = null )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Undo ( ) ;
if ( cstep = = step ) break ;
if ( UndoSteps . Count = = 0 ) break ;
cstep = UndoSteps . Peek ( ) ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
}
private void ToolbarRedoButton_ButtonClick ( object sender , EventArgs e )
{
Redo ( ) ;
}
private void ToolbarRedoListButton_Click ( object sender , EventArgs e )
{
var tsi = sender as ToolStripItem ;
if ( tsi = = null ) return ;
var step = tsi . Tag as UndoStep ;
if ( step = = null ) return ;
if ( RedoSteps . Count = = 0 ) return ;
var cstep = RedoSteps . Peek ( ) ;
while ( cstep ! = null )
2017-12-22 04:26:04 +08:00
{
2018-01-02 04:52:54 +08:00
Redo ( ) ;
if ( cstep = = step ) break ;
if ( RedoSteps . Count = = 0 ) break ;
cstep = RedoSteps . Peek ( ) ;
2017-12-22 04:26:04 +08:00
}
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarInfoWindowButton_Click ( object sender , EventArgs e )
{
ShowInfoForm ( ) ;
}
2017-09-26 08:27:18 +08:00
2018-01-02 04:52:54 +08:00
private void ToolbarProjectWindowButton_Click ( object sender , EventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
ShowProjectForm ( ) ;
}
2017-09-26 08:27:18 +08:00
2018-01-02 04:52:54 +08:00
private void ToolbarAddItemButton_Click ( object sender , EventArgs e )
{
AddItem ( ) ;
2017-09-26 08:27:18 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarDeleteItemButton_Click ( object sender , EventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
DeleteItem ( ) ;
2017-09-26 08:27:18 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarCopyButton_Click ( object sender , EventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
CopyItem ( ) ;
2017-09-26 08:27:18 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarPasteButton_Click ( object sender , EventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
PasteItem ( ) ;
2017-09-26 08:27:18 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarCameraModeButton_ButtonClick ( object sender , EventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
ToggleCameraMode ( ) ;
2017-09-26 08:27:18 +08:00
}
2018-01-02 04:52:54 +08:00
private void ToolbarCameraPerspectiveButton_Click ( object sender , EventArgs e )
{
SetCameraMode ( "Perspective" ) ;
}
2017-09-26 08:27:18 +08:00
2018-01-02 04:52:54 +08:00
private void ToolbarCameraMapViewButton_Click ( object sender , EventArgs e )
{
SetCameraMode ( "2D Map" ) ;
}
2017-09-26 08:27:18 +08:00
2018-01-02 04:52:54 +08:00
private void ToolbarCameraOrthographicButton_Click ( object sender , EventArgs e )
{
SetCameraMode ( "Orthographic" ) ;
}
2017-09-26 08:27:18 +08:00
2018-01-02 04:52:54 +08:00
private void SelectionModeComboBox_SelectedIndexChanged ( object sender , EventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
SetSelectionMode ( SelectionModeComboBox . Text ) ;
}
2017-09-26 08:27:18 +08:00
2018-01-02 04:52:54 +08:00
private void SelectionModeComboBox_KeyPress ( object sender , KeyPressEventArgs e )
{
e . Handled = true ;
}
2017-09-26 08:27:18 +08:00
2018-01-02 04:52:54 +08:00
private void ViewModeComboBox_KeyPress ( object sender , KeyPressEventArgs e )
{
e . Handled = true ;
2017-09-26 08:27:18 +08:00
}
2018-01-02 04:52:54 +08:00
private void WorldMaxLodComboBox_KeyPress ( object sender , KeyPressEventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
e . Handled = true ;
2017-09-26 08:27:18 +08:00
}
2018-01-02 04:52:54 +08:00
private void DlcLevelComboBox_KeyPress ( object sender , KeyPressEventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
e . Handled = true ;
2017-09-26 08:27:18 +08:00
}
2018-01-02 04:52:54 +08:00
private void CameraModeComboBox_KeyPress ( object sender , KeyPressEventArgs e )
{
e . Handled = true ;
}
2017-09-26 08:27:18 +08:00
2018-01-02 04:52:54 +08:00
private void RenderModeComboBox_KeyPress ( object sender , KeyPressEventArgs e )
2017-09-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
e . Handled = true ;
2017-09-26 08:27:18 +08:00
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void TextureSamplerComboBox_KeyPress ( object sender , KeyPressEventArgs e )
{
e . Handled = true ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void TextureCoordsComboBox_KeyPress ( object sender , KeyPressEventArgs e )
{
e . Handled = true ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void MarkerStyleComboBox_KeyPress ( object sender , KeyPressEventArgs e )
{
e . Handled = true ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void LocatorStyleComboBox_KeyPress ( object sender , KeyPressEventArgs e )
{
e . Handled = true ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
private void BoundsStyleComboBox_KeyPress ( object sender , KeyPressEventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
e . Handled = true ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void WeatherComboBox_KeyPress ( object sender , KeyPressEventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
e . Handled = true ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void WeatherRegionComboBox_KeyPress ( object sender , KeyPressEventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
e . Handled = true ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void CloudsComboBox_KeyPress ( object sender , KeyPressEventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
e . Handled = true ;
2017-09-21 18:33:05 +08:00
}
2018-01-02 04:52:54 +08:00
private void CloudParamComboBox_KeyPress ( object sender , KeyPressEventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
e . Handled = true ;
2017-09-21 18:33:05 +08:00
}
2018-02-25 20:30:29 +08:00
private void SnapGridSizeUpDown_ValueChanged ( object sender , EventArgs e )
{
SnapGridSize = ( float ) SnapGridSizeUpDown . Value ;
}
2018-01-02 04:52:54 +08:00
2020-01-09 14:59:57 +08:00
private void SnapAngleUpDown_ValueChanged ( object sender , EventArgs e )
{
if ( Widget ! = null )
{
2020-01-15 12:26:35 +08:00
SetRotationSnapping ( ( float ) SnapAngleUpDown . Value ) ;
2020-01-09 14:59:57 +08:00
}
}
2018-08-11 23:58:52 +08:00
private void RenderEntitiesCheckBox_CheckedChanged ( object sender , EventArgs e )
{
Renderer . renderentities = RenderEntitiesCheckBox . Checked ;
}
2018-12-05 13:23:34 +08:00
private void StatsLabel_DoubleClick ( object sender , EventArgs e )
{
var statsForm = new StatisticsForm ( this ) ;
statsForm . Show ( this ) ;
}
2019-11-25 18:35:15 +08:00
private void SubtitleLabel_SizeChanged ( object sender , EventArgs e )
{
SubtitleLabel . Left = ( ClientSize . Width - SubtitleLabel . Size . Width ) / 2 ; //keep subtitle label centered
}
private void SubtitleTimer_Tick ( object sender , EventArgs e )
{
SubtitleTimer . Enabled = false ;
SubtitleLabel . Visible = false ;
}
2018-01-02 04:52:54 +08:00
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
public enum WorldControlMode
{
Free = 0 ,
Ped = 1 ,
Car = 2 ,
Heli = 3 ,
Plane = 4 ,
Jetpack = 10 ,
2017-09-21 18:33:05 +08:00
}
2018-02-25 20:30:29 +08:00
public enum WorldSnapMode
{
None = 0 ,
Grid = 1 ,
Ground = 2 ,
Hybrid = 3 ,
}
2017-09-21 18:33:05 +08:00
}