2017-09-21 18:33:05 +08:00
using CodeWalker.GameFiles ;
using CodeWalker.Properties ;
using CodeWalker.Rendering ;
using CodeWalker.World ;
using SharpDX ;
using SharpDX.Direct3D11 ;
using SharpDX.XInput ;
using System ;
using System.Collections.Generic ;
using System.ComponentModel ;
using System.Data ;
using System.Diagnostics ;
using System.IO ;
using System.Linq ;
using System.Text ;
using System.Threading ;
using System.Threading.Tasks ;
using System.Windows.Forms ;
namespace CodeWalker.Forms
{
public partial class ModelForm : Form , DXForm
{
public Form Form { get { return this ; } } //for DXForm/DXManager use
2018-01-02 04:52:54 +08:00
private Renderer Renderer = null ;
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 ( ) ;
2018-01-02 04:52:54 +08:00
Camera camera ;
Timecycle timecycle ;
Weather weather ;
Clouds clouds ;
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 ;
2018-01-02 08:07:24 +08:00
bool MouseInvert = Settings . Default . MouseInvert ;
2017-09-21 18:33:05 +08:00
Vector3 prevworldpos = new Vector3 ( 0 , 0 , 0 ) ; //also the start pos
Entity camEntity = new Entity ( ) ;
2018-01-02 04:52:54 +08:00
//bool iseditmode = false;
2017-09-21 18:33:05 +08:00
bool initedOk = false ;
private string fileName ;
public string FileName
{
get { return fileName ; }
set
{
fileName = value ;
UpdateFormTitle ( ) ;
}
}
public string FilePath { get ; set ; }
YdrFile Ydr = null ;
YddFile Ydd = null ;
YftFile Yft = null ;
YbnFile Ybn = null ;
YptFile Ypt = null ;
YnvFile Ynv = null ;
2017-09-24 18:14:41 +08:00
2018-01-02 04:52:54 +08:00
InputManager Input = new InputManager ( ) ;
2017-09-23 19:46:49 +08:00
2017-09-21 18:33:05 +08:00
bool toolsPanelResizing = false ;
int toolsPanelResizeStartX = 0 ;
int toolsPanelResizeStartLeft = 0 ;
int toolsPanelResizeStartRight = 0 ;
Dictionary < DrawableBase , bool > DrawableDrawFlags = new Dictionary < DrawableBase , bool > ( ) ;
2018-03-16 22:53:49 +08:00
bool enableGrid = false ;
2017-09-21 18:33:05 +08:00
float gridSize = 1.0f ;
int gridCount = 40 ;
List < VertexTypePC > gridVerts = new List < VertexTypePC > ( ) ;
object gridSyncRoot = new object ( ) ;
GameFileCache gameFileCache = null ;
Archetype currentArchetype = null ;
bool updateArchetypeStatus = true ;
2019-03-21 22:29:37 +08:00
ModelMatForm materialForm = null ;
2019-03-22 17:07:12 +08:00
private bool modelModified = false ;
2019-03-21 22:29:37 +08:00
2019-03-22 17:07:12 +08:00
ExploreForm exploreForm = null ;
RpfFileEntry rpfFileEntry = null ;
2019-03-21 22:29:37 +08:00
2017-09-21 18:33:05 +08:00
public ModelForm ( ExploreForm ExpForm = null )
{
InitializeComponent ( ) ;
2019-03-22 17:07:12 +08:00
exploreForm = ExpForm ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
gameFileCache = ExpForm ? . GetFileCache ( ) ;
Renderer = new Renderer ( this , gameFileCache ) ;
camera = Renderer . camera ;
timecycle = Renderer . timecycle ;
weather = Renderer . weather ;
clouds = Renderer . clouds ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
initedOk = Renderer . Init ( ) ;
Renderer . controllightdir = ! Settings . Default . Skydome ;
Renderer . rendercollisionmeshes = false ;
Renderer . renderclouds = false ;
Renderer . rendermoon = false ;
2018-03-16 22:53:49 +08:00
Renderer . renderskeletons = false ;
2018-01-02 04:52:54 +08:00
Renderer . SelectionFlagsTestAll = true ;
2018-03-16 22:53:49 +08:00
//var timeofday = 13.6f;
//Renderer.SetTimeOfDay(timeofday);
//TimeOfDayTrackBar.Value = (int)(timeofday * 60.0f);
//UpdateTimeOfDayLabel();
2017-09-21 18:33:05 +08:00
}
private void Init ( )
{
2018-01-02 04:52:54 +08:00
//called from ModelForm_Load
2017-09-21 18:33:05 +08:00
if ( ! initedOk )
{
Close ( ) ;
return ;
}
MouseWheel + = ModelForm_MouseWheel ;
2018-02-21 17:12:17 +08:00
if ( ! GTAFolder . UpdateGTAFolder ( true ) )
2017-09-21 18:33:05 +08:00
{
Close ( ) ;
return ;
}
MetaName [ ] texsamplers = RenderableGeometry . GetTextureSamplerList ( ) ;
foreach ( var texsampler in texsamplers )
{
TextureSamplerComboBox . Items . Add ( texsampler ) ;
}
//TextureSamplerComboBox.SelectedIndex = 0;//LoadSettings will do this..
UpdateGridVerts ( ) ;
GridSizeComboBox . SelectedIndex = 1 ;
GridCountComboBox . SelectedIndex = 1 ;
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
}
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 ;
}
//shaders.hdrLumBlendSpeed = 1000.0f;
camera . FollowEntity = camEntity ;
camera . FollowEntity . Position = prevworldpos ;
camera . FollowEntity . Orientation = Quaternion . LookAtLH ( Vector3 . Zero , Vector3 . Up , Vector3 . ForwardLH ) ;
camera . TargetDistance = 2.0f ;
camera . CurrentDistance = 2.0f ;
camera . TargetRotation . Y = 0.2f ;
camera . CurrentRotation . Y = 0.2f ;
2018-03-16 22:53:49 +08:00
camera . TargetRotation . X = 0.5f * ( float ) Math . PI ;
camera . CurrentRotation . X = 0.5f * ( float ) Math . PI ;
2017-09-21 18:33:05 +08:00
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
//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 ;
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
Renderer . Update ( elapsed , MouseLastPoint . X , MouseLastPoint . Y ) ;
2017-09-21 18:33:05 +08:00
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
RenderSingleItem ( ) ;
2018-01-02 04:52:54 +08:00
RenderGrid ( context ) ;
2017-09-21 18:33:05 +08:00
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 . RenderFinalPass ( ) ;
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
}
private void ContentThread ( )
{
//main content loading thread.
//running = true;
//UpdateStatus("Scanning...");
//try
//{
// GTA5Keys.LoadFromPath(Settings.Default.GTAFolder); //now loads from magic
//}
//catch
//{
// MessageBox.Show("Keys not found! This shouldn't happen.");
// Close();
// return;
//}
//gameFileCache.Init(UpdateStatus, LogError);
////UpdateDlcListComboBox(gameFileCache.DlcNameList);
////EnableCacheDependentUI();
////LoadWorld();
//initialised = true;
////EnableDLCModsUI();
UpdateStatus ( "Ready" ) ;
while ( formopen & & ! IsDisposed ) //main asset loop
{
if ( ( gameFileCache ! = null ) & & ( gameFileCache . IsInited ) )
{
if ( ! timecycle . Inited )
{
//UpdateStatus("Loading timecycles...");
timecycle . Init ( gameFileCache , UpdateStatus ) ;
2018-01-02 04:52:54 +08:00
timecycle . SetTime ( Renderer . timeofday ) ;
2017-09-21 18:33:05 +08:00
//UpdateStatus("Timecycles loaded.");
}
2018-01-02 04:52:54 +08:00
if ( Renderer . renderskydome )
2017-09-21 18:33:05 +08:00
{
if ( ! weather . Inited )
{
//UpdateStatus("Loading weather...");
weather . Init ( gameFileCache , UpdateStatus , timecycle ) ;
//UpdateStatus("Weather loaded.");
}
//if (!clouds.Inited)
//{
// UpdateStatus("Loading clouds...");
// clouds.Init(gameFileCache, UpdateStatus, weather);
// UpdateStatus("Clouds loaded.");
//}
}
}
//if ((gameFileCache != null) && (gameFileCache.IsInited))
//{
// gameFileCache.ContentThreadProc();
//}
2018-01-02 04:52:54 +08:00
bool rcItemsPending = Renderer . ContentThreadProc ( ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( ! ( rcItemsPending ) ) //gameFileCache.ItemsStillPending ||
2017-09-21 18:33:05 +08:00
{
Thread . Sleep ( 1 ) ; //sleep if there's nothing to do
}
}
//gameFileCache.Clear();
//running = false;
}
private void LoadSettings ( )
{
var s = Settings . Default ;
//WindowState = s.WindowMaximized ? FormWindowState.Maximized : WindowState;
//FullScreenCheckBox.Checked = s.FullScreen;
WireframeCheckBox . Checked = s . Wireframe ;
HDRRenderingCheckBox . Checked = s . HDR ;
ShadowsCheckBox . Checked = s . Shadows ;
SkydomeCheckBox . Checked = s . Skydome ;
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 ) ;
AnisotropicFilteringCheckBox . Checked = s . AnisotropicFiltering ;
//ErrorConsoleCheckBox.Checked = s.ShowErrorConsole;
//StatusBarCheckBox.Checked = s.ShowStatusBar;
}
2018-03-16 22:53:49 +08:00
private void MoveCameraToView ( Vector3 pos , float rad )
{
//move the camera to a default place where the given sphere is fully visible.
rad = Math . Max ( 0.5f , rad ) ;
camera . FollowEntity . Position = pos ;
camera . TargetDistance = rad * 1.6f ;
camera . CurrentDistance = rad * 1.6f ;
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
private Archetype TryGetArchetype ( uint hash )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
if ( ( gameFileCache = = null ) | | ( ! gameFileCache . IsInited ) ) return null ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
var arch = gameFileCache . GetArchetype ( hash ) ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
if ( ( arch ! = null ) & & ( arch ! = currentArchetype ) & & ( updateArchetypeStatus ) )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
UpdateStatus ( "Archetype: " + arch . Name . ToString ( ) ) ;
currentArchetype = arch ;
updateArchetypeStatus = false ;
2017-09-21 18:33:05 +08:00
}
2017-09-23 19:46:49 +08:00
return arch ;
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
private void UpdateGridVerts ( )
{
lock ( gridSyncRoot )
{
gridVerts . Clear ( ) ;
float s = gridSize * gridCount * 0.5f ;
2018-03-10 22:27:13 +08:00
uint cblack = ( uint ) Color . Black . ToRgba ( ) ;
uint cgray = ( uint ) Color . DimGray . ToRgba ( ) ;
uint cred = ( uint ) Color . DarkRed . ToRgba ( ) ;
uint cgrn = ( uint ) Color . DarkGreen . ToRgba ( ) ;
2017-09-21 18:33:05 +08:00
int interval = 10 ;
for ( int i = 0 ; i < = gridCount ; i + + )
{
float o = ( gridSize * i ) - s ;
if ( ( i % interval ) ! = 0 )
{
gridVerts . Add ( new VertexTypePC ( ) { Position = new Vector3 ( o , - s , 0 ) , Colour = cgray } ) ;
gridVerts . Add ( new VertexTypePC ( ) { Position = new Vector3 ( o , s , 0 ) , Colour = cgray } ) ;
gridVerts . Add ( new VertexTypePC ( ) { Position = new Vector3 ( - s , o , 0 ) , Colour = cgray } ) ;
gridVerts . Add ( new VertexTypePC ( ) { Position = new Vector3 ( s , o , 0 ) , Colour = cgray } ) ;
}
}
for ( int i = 0 ; i < = gridCount ; i + + ) //draw main lines last, so they are on top
{
float o = ( gridSize * i ) - s ;
if ( ( i % interval ) = = 0 )
{
var cx = ( o = = 0 ) ? cred : cblack ;
var cy = ( o = = 0 ) ? cgrn : cblack ;
gridVerts . Add ( new VertexTypePC ( ) { Position = new Vector3 ( o , - s , 0 ) , Colour = cy } ) ;
gridVerts . Add ( new VertexTypePC ( ) { Position = new Vector3 ( o , s , 0 ) , Colour = cy } ) ;
gridVerts . Add ( new VertexTypePC ( ) { Position = new Vector3 ( - s , o , 0 ) , Colour = cx } ) ;
gridVerts . Add ( new VertexTypePC ( ) { Position = new Vector3 ( s , o , 0 ) , Colour = cx } ) ;
}
}
}
}
private void RenderGrid ( DeviceContext context )
{
if ( ! enableGrid ) return ;
lock ( gridSyncRoot )
{
if ( gridVerts . Count > 0 )
{
2018-01-02 04:52:54 +08:00
Renderer . RenderLines ( gridVerts ) ;
2017-09-21 18:33:05 +08:00
}
}
}
2017-09-23 19:46:49 +08:00
2017-09-21 18:33:05 +08:00
private void RenderSingleItem ( )
{
uint hash = 0 ;
Archetype arch = null ;
if ( Ydr ! = null )
{
if ( Ydr . Loaded )
{
hash = Ydr ? . RpfFileEntry ? . ShortNameHash ? ? 0 ;
arch = TryGetArchetype ( hash ) ;
2018-01-02 04:52:54 +08:00
Renderer . RenderDrawable ( Ydr . Drawable , arch , null , hash ) ;
2017-09-21 18:33:05 +08:00
}
}
else if ( Ydd ! = null )
{
//render selected drawable(s)...
if ( Ydd . Loaded )
{
foreach ( var kvp in Ydd . Dict )
{
if ( ! DrawableDrawFlags . ContainsKey ( kvp . Value ) ) //only render if it's checked...
{
arch = TryGetArchetype ( kvp . Key ) ;
2018-01-02 04:52:54 +08:00
Renderer . RenderDrawable ( kvp . Value , arch , null , Ydd . RpfFileEntry . ShortNameHash ) ;
2017-09-21 18:33:05 +08:00
}
}
}
}
else if ( Ypt ! = null )
{
if ( ( Ypt . Loaded ) & & ( Ypt . DrawableDict ! = null ) )
{
foreach ( var kvp in Ypt . DrawableDict )
{
if ( ! DrawableDrawFlags . ContainsKey ( kvp . Value ) ) //only render if it's checked...
{
arch = TryGetArchetype ( kvp . Key ) ;
2018-01-02 04:52:54 +08:00
Renderer . RenderDrawable ( kvp . Value , arch , null , kvp . Key ) ;
2017-09-21 18:33:05 +08:00
}
}
}
}
else if ( Yft ! = null )
{
if ( Yft . Loaded )
{
if ( Yft . Fragment ! = null )
{
var f = Yft . Fragment ;
2019-01-06 02:04:33 +08:00
hash = Yft . RpfFileEntry ? . ShortNameHash ? ? 0 ;
var namelower = Yft . RpfFileEntry ? . GetShortNameLower ( ) ;
if ( namelower ? . EndsWith ( "_hi" ) ? ? false )
{
hash = JenkHash . GenHash ( namelower . Substring ( 0 , namelower . Length - 3 ) ) ;
}
2017-09-21 18:33:05 +08:00
arch = TryGetArchetype ( hash ) ;
2018-01-02 04:52:54 +08:00
Renderer . RenderFragment ( arch , null , f , hash ) ;
2017-09-21 18:33:05 +08:00
}
}
}
else if ( Ybn ! = null )
{
if ( Ybn . Loaded )
{
2018-01-02 04:52:54 +08:00
Renderer . RenderCollisionMesh ( Ybn . Bounds , null ) ;
2017-09-21 18:33:05 +08:00
}
}
else if ( Ynv ! = null )
{
if ( Ynv . Loaded )
{
2018-01-02 04:52:54 +08:00
Renderer . RenderNavMesh ( Ynv ) ;
2017-09-21 18:33:05 +08:00
}
}
}
2017-09-23 19:46:49 +08:00
public void LoadModel ( YdrFile ydr )
{
if ( ydr = = null ) return ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
FileName = ydr . Name ;
Ydr = ydr ;
2019-03-22 17:07:12 +08:00
rpfFileEntry = Ydr . RpfFileEntry ;
2017-09-21 18:33:05 +08:00
2018-03-16 22:53:49 +08:00
if ( ydr . Drawable ! = null )
{
MoveCameraToView ( ydr . Drawable . BoundingCenter , ydr . Drawable . BoundingSphereRadius ) ;
}
2017-09-23 19:46:49 +08:00
UpdateModelsUI ( ydr . Drawable ) ;
}
public void LoadModels ( YddFile ydd )
{
if ( ydd = = null ) return ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
FileName = ydd . Name ;
Ydd = ydd ;
2019-03-22 17:07:12 +08:00
rpfFileEntry = Ydd . RpfFileEntry ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
UpdateModelsUI ( ydd . Dict ) ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
DetailsPropertyGrid . SelectedObject = ydd ;
}
public void LoadModel ( YftFile yft )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
if ( yft = = null ) return ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
FileName = yft . Name ;
Yft = yft ;
2019-03-22 17:07:12 +08:00
rpfFileEntry = Yft . RpfFileEntry ;
2017-09-21 18:33:05 +08:00
2018-03-16 22:53:49 +08:00
var dr = yft . Fragment ? . Drawable ;
if ( dr ! = null )
{
MoveCameraToView ( dr . BoundingCenter , dr . BoundingSphereRadius ) ;
}
2017-09-23 19:46:49 +08:00
UpdateModelsUI ( yft . Fragment . Drawable ) ;
2017-09-21 18:33:05 +08:00
}
2017-09-23 19:46:49 +08:00
public void LoadModel ( YbnFile ybn )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
if ( ybn = = null ) return ;
FileName = ybn . Name ;
Ybn = ybn ;
2019-03-22 17:07:12 +08:00
rpfFileEntry = Ybn . RpfFileEntry ;
2017-09-23 19:46:49 +08:00
2018-03-16 22:53:49 +08:00
if ( Ybn . Bounds ! = null )
{
MoveCameraToView ( Ybn . Bounds . BoundingBoxCenter , Ybn . Bounds . BoundingSphereRadius ) ;
}
2018-03-12 01:42:20 +08:00
UpdateBoundsUI ( ybn ) ;
2017-09-21 18:33:05 +08:00
}
2017-09-23 19:46:49 +08:00
public void LoadParticles ( YptFile ypt )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
if ( ypt = = null ) return ;
FileName = ypt . Name ;
Ypt = ypt ;
2019-03-22 17:07:12 +08:00
rpfFileEntry = Ypt . RpfFileEntry ;
2017-09-23 19:46:49 +08:00
UpdateModelsUI ( ypt . DrawableDict ) ;
DetailsPropertyGrid . SelectedObject = ypt ; //.PtfxList;
2017-09-21 18:33:05 +08:00
}
2017-09-23 19:46:49 +08:00
public void LoadNavmesh ( YnvFile ynv )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
if ( ynv = = null ) return ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
FileName = ynv . Name ;
Ynv = ynv ;
2019-03-22 17:07:12 +08:00
rpfFileEntry = Ynv . RpfFileEntry ;
2017-09-21 18:33:05 +08:00
2018-03-16 22:53:49 +08:00
if ( ynv . Nav . SectorTree ! = null )
{
var st = ynv . Nav . SectorTree ;
var cen = ( st . AABBMin + st . AABBMax ) . XYZ ( ) * 0.5f ;
var rad = ( st . AABBMax - st . AABBMin ) . XYZ ( ) . Length ( ) * 0.5f ;
MoveCameraToView ( cen , rad ) ;
}
2018-03-10 01:58:44 +08:00
UpdateNavmeshUI ( ynv ) ;
2017-09-23 19:46:49 +08:00
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
private void UpdateFormTitle ( )
2017-09-21 18:33:05 +08:00
{
2019-03-22 17:07:12 +08:00
Text = fileName + ( modelModified ? "*" : "" ) + " - CodeWalker by dexyfex" ;
2017-09-23 19:46:49 +08:00
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
private void UpdateStatus ( string text )
{
try
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
if ( InvokeRequired )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
BeginInvoke ( new Action ( ( ) = > { UpdateStatus ( text ) ; } ) ) ;
}
else
{
StatusLabel . Text = text ;
2017-09-21 18:33:05 +08:00
}
}
2017-09-23 19:46:49 +08:00
catch { }
2017-09-21 18:33:05 +08:00
}
2017-09-23 19:46:49 +08:00
private void LogError ( string text )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
try
{
if ( InvokeRequired )
{
Invoke ( new Action ( ( ) = > { LogError ( text ) ; } ) ) ;
}
else
{
ConsoleTextBox . AppendText ( text + "\r\n" ) ;
}
}
catch { }
2017-09-21 18:33:05 +08:00
}
2017-09-23 19:46:49 +08:00
private void UpdateTimeOfDayLabel ( )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
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 ) ;
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
private void UpdateControlInputs ( float elapsed )
{
2018-01-02 04:52:54 +08:00
if ( elapsed > 0.1f ) elapsed = 0.1f ;
2017-09-23 19:46:49 +08:00
var s = Settings . Default ;
2017-09-21 18:33:05 +08:00
2018-03-16 22:53:49 +08:00
float moveSpeed = 2.0f ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Input . Update ( elapsed ) ;
if ( Input . xbenable )
{
2017-09-23 19:46:49 +08:00
//if (ControllerButtonJustPressed(GamepadButtonFlags.Start))
2017-09-21 18:33:05 +08:00
//{
2017-09-23 19:46:49 +08:00
// SetControlMode(ControlMode == WorldControlMode.Free ? WorldControlMode.Ped : WorldControlMode.Free);
2017-09-21 18:33:05 +08:00
//}
2017-09-23 19:46:49 +08:00
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
2018-01-02 04:52:54 +08:00
if ( Input . ShiftPressed )
{
moveSpeed * = 5.0f ;
}
if ( Input . CtrlPressed )
{
moveSpeed * = 0.2f ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Vector3 movevec = Input . KeyboardMoveVec ( false ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
//if (MapViewEnabled == true)
//{
// movevec *= elapsed * 100.0f * Math.Min(camera.OrthographicTargetSize * 0.01f, 30.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 , 50.0f ) ;
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Vector3 movewvec = camera . ViewInvQuaternion . Multiply ( movevec ) ;
camEntity . Position + = movewvec ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
//MapViewDragX = 0;
//MapViewDragY = 0;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
if ( Input . xbenable )
{
camera . ControllerRotate ( Input . xblx + Input . xbrx , Input . xbly + Input . xbry ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
float zoom = 0.0f ;
float zoomspd = s . XInputZoomSpeed ;
float zoomamt = zoomspd * elapsed ;
if ( Input . ControllerButtonPressed ( GamepadButtonFlags . DPadUp ) ) zoom + = zoomamt ;
if ( Input . ControllerButtonPressed ( GamepadButtonFlags . DPadDown ) ) zoom - = zoomamt ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
camera . ControllerZoom ( zoom ) ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
float acc = 0.0f ;
float accspd = s . XInputMoveSpeed ; //actually accel speed...
acc + = Input . xbrt * accspd ;
acc - = Input . xblt * accspd ;
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
Vector3 newdir = camera . ViewDirection ; //maybe use the "vehicle" direction...?
Input . xbcontrolvelocity + = ( acc * elapsed ) ;
2017-09-23 19:46:49 +08:00
2018-01-02 04:52:54 +08:00
if ( Input . ControllerButtonPressed ( GamepadButtonFlags . A | GamepadButtonFlags . RightShoulder ) ) //handbrake...
{
Input . xbcontrolvelocity * = Math . Max ( 0.75f - elapsed , 0 ) ; //not ideal for low fps...
//xbcontrolvelocity = 0.0f;
if ( Math . Abs ( Input . xbcontrolvelocity ) < 0.001f ) Input . xbcontrolvelocity = 0.0f ;
2017-09-23 19:46:49 +08:00
}
2017-09-21 18:33:05 +08:00
2018-01-02 04:52:54 +08:00
camEntity . Velocity = newdir * Input . xbcontrolvelocity ;
camEntity . Position + = camEntity . Velocity * elapsed ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
2018-01-02 04:52:54 +08:00
//fire!
//if (ControllerButtonJustPressed(GamepadButtonFlags.LeftShoulder))
//{
// SpawnTestEntity(true);
//}
}
2017-09-23 19:46:49 +08:00
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
private void UpdateModelsUI ( DrawableBase drawable )
{
DetailsPropertyGrid . SelectedObject = drawable ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
DrawableDrawFlags . Clear ( ) ;
2018-01-02 04:52:54 +08:00
Renderer . SelectionModelDrawFlags . Clear ( ) ;
Renderer . SelectionGeometryDrawFlags . Clear ( ) ;
2017-09-23 19:46:49 +08:00
ModelsTreeView . Nodes . Clear ( ) ;
ModelsTreeView . ShowRootLines = false ;
TexturesTreeView . Nodes . Clear ( ) ;
if ( drawable ! = null )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
AddDrawableModelsTreeNodes ( drawable . DrawableModelsHigh , "High Detail" , true ) ;
AddDrawableModelsTreeNodes ( drawable . DrawableModelsMedium , "Medium Detail" , false ) ;
AddDrawableModelsTreeNodes ( drawable . DrawableModelsLow , "Low Detail" , false ) ;
AddDrawableModelsTreeNodes ( drawable . DrawableModelsVeryLow , "Very Low Detail" , false ) ;
//AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false);
2019-01-13 14:04:32 +08:00
var fdrawable = drawable as FragDrawable ;
if ( fdrawable ! = null )
{
var plod1 = fdrawable . OwnerFragment ? . PhysicsLODGroup ? . PhysicsLOD1 ;
if ( ( plod1 ! = null ) & & ( plod1 . Children ? . data_items ! = null ) )
{
foreach ( var child in plod1 . Children . data_items )
{
var cdrwbl = child . Drawable1 ;
if ( ( cdrwbl ! = null ) & & ( cdrwbl . AllModels ? . Length > 0 ) )
{
if ( cdrwbl . Owner is FragDrawable ) continue ; //it's a copied drawable... eg a wheel
var dname = child . GroupNameHash . ToString ( ) ;
AddDrawableModelsTreeNodes ( cdrwbl . DrawableModelsHigh , dname + " - High Detail" , true ) ;
AddDrawableModelsTreeNodes ( cdrwbl . DrawableModelsMedium , dname + " - Medium Detail" , false ) ;
AddDrawableModelsTreeNodes ( cdrwbl . DrawableModelsLow , dname + " - Low Detail" , false ) ;
AddDrawableModelsTreeNodes ( cdrwbl . DrawableModelsVeryLow , dname + " - Very Low Detail" , false ) ;
}
}
}
}
2017-09-21 18:33:05 +08:00
}
2017-09-23 19:46:49 +08:00
}
private void UpdateModelsUI ( FragType frag )
{
DetailsPropertyGrid . SelectedObject = frag ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
var drawable = frag . Drawable ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
DrawableDrawFlags . Clear ( ) ;
2018-01-02 04:52:54 +08:00
Renderer . SelectionModelDrawFlags . Clear ( ) ;
Renderer . SelectionGeometryDrawFlags . Clear ( ) ;
2017-09-23 19:46:49 +08:00
ModelsTreeView . Nodes . Clear ( ) ;
ModelsTreeView . ShowRootLines = false ;
TexturesTreeView . Nodes . Clear ( ) ;
if ( drawable ! = null )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
AddDrawableModelsTreeNodes ( drawable . DrawableModelsHigh , "High Detail" , true ) ;
AddDrawableModelsTreeNodes ( drawable . DrawableModelsMedium , "Medium Detail" , false ) ;
AddDrawableModelsTreeNodes ( drawable . DrawableModelsLow , "Low Detail" , false ) ;
AddDrawableModelsTreeNodes ( drawable . DrawableModelsVeryLow , "Very Low Detail" , false ) ;
//AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false);
2019-01-13 14:04:32 +08:00
var fdrawable = drawable as FragDrawable ;
if ( fdrawable ! = null )
{
var plod1 = fdrawable . OwnerFragment ? . PhysicsLODGroup ? . PhysicsLOD1 ;
if ( ( plod1 ! = null ) & & ( plod1 . Children ? . data_items ! = null ) )
{
foreach ( var child in plod1 . Children . data_items )
{
var cdrwbl = child . Drawable1 ;
if ( ( cdrwbl ! = null ) & & ( cdrwbl . AllModels ? . Length > 0 ) )
{
if ( cdrwbl . Owner is FragDrawable ) continue ; //it's a copied drawable... eg a wheel
var dname = child . GroupNameHash . ToString ( ) ;
AddDrawableModelsTreeNodes ( cdrwbl . DrawableModelsHigh , dname + " - High Detail" , true ) ;
AddDrawableModelsTreeNodes ( cdrwbl . DrawableModelsMedium , dname + " - Medium Detail" , false ) ;
AddDrawableModelsTreeNodes ( cdrwbl . DrawableModelsLow , dname + " - Low Detail" , false ) ;
AddDrawableModelsTreeNodes ( cdrwbl . DrawableModelsVeryLow , dname + " - Very Low Detail" , false ) ;
}
}
}
}
2017-09-23 19:46:49 +08:00
}
}
private void UpdateModelsUI ( Dictionary < uint , Drawable > dict )
{
//DetailsPropertyGrid.SelectedObject = dict; //this won't look good...
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
DrawableDrawFlags . Clear ( ) ;
2018-01-02 04:52:54 +08:00
Renderer . SelectionModelDrawFlags . Clear ( ) ;
Renderer . SelectionGeometryDrawFlags . Clear ( ) ;
2017-09-23 19:46:49 +08:00
ModelsTreeView . Nodes . Clear ( ) ;
ModelsTreeView . ShowRootLines = true ;
TexturesTreeView . Nodes . Clear ( ) ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
bool check = true ;
if ( dict ! = null )
{
foreach ( var kvp in dict )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
AddDrawableTreeNode ( kvp . Value , kvp . Key , check ) ;
check = false ;
}
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
ToolsPanel . Visible = true ; //show the panel by default for dictionaries...
}
2018-03-12 01:42:20 +08:00
private void UpdateBoundsUI ( YbnFile bounds )
2017-09-23 19:46:49 +08:00
{
DetailsPropertyGrid . SelectedObject = bounds ;
}
private void UpdateNavmeshUI ( YnvFile ynv )
{
2018-03-10 01:58:44 +08:00
DetailsPropertyGrid . SelectedObject = ynv ;
2017-09-23 19:46:49 +08:00
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
private void AddDrawableTreeNode ( DrawableBase drawable , uint hash , bool check )
{
MetaHash mhash = new MetaHash ( hash ) ;
var dnode = ModelsTreeView . Nodes . Add ( mhash . ToString ( ) ) ;
dnode . Tag = drawable ;
dnode . Checked = check ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
AddDrawableModelsTreeNodes ( drawable . DrawableModelsHigh , "High Detail" , true , dnode ) ;
AddDrawableModelsTreeNodes ( drawable . DrawableModelsMedium , "Medium Detail" , false , dnode ) ;
AddDrawableModelsTreeNodes ( drawable . DrawableModelsLow , "Low Detail" , false , dnode ) ;
AddDrawableModelsTreeNodes ( drawable . DrawableModelsVeryLow , "Very Low Detail" , false , dnode ) ;
//AddSelectionDrawableModelsTreeNodes(item.Drawable.DrawableModelsX, "X Detail", false, dnode);
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
}
private void AddDrawableModelsTreeNodes ( ResourcePointerList64 < DrawableModel > models , string prefix , bool check , TreeNode parentDrawableNode = null )
{
if ( models = = null ) return ;
if ( models . data_items = = null ) return ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
for ( int mi = 0 ; mi < models . data_items . Length ; mi + + )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
var tnc = ( parentDrawableNode ! = null ) ? parentDrawableNode . Nodes : ModelsTreeView . Nodes ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
var model = models . data_items [ mi ] ;
string mprefix = prefix + " " + ( mi + 1 ) . ToString ( ) ;
var mnode = tnc . Add ( mprefix + " " + model . ToString ( ) ) ;
mnode . Tag = model ;
mnode . Checked = check ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
var tmnode = TexturesTreeView . Nodes . Add ( mprefix + " " + model . ToString ( ) ) ;
tmnode . Tag = model ;
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
if ( ! check )
{
2018-01-02 04:52:54 +08:00
Renderer . SelectionModelDrawFlags [ model ] = false ;
2017-09-23 19:46:49 +08:00
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
if ( ( model . Geometries = = null ) | | ( model . Geometries . data_items = = null ) ) continue ;
foreach ( var geom in model . Geometries . data_items )
{
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 ) )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
var pl = geom . Shader . ParametersList ;
var h = pl . Hashes ;
var p = pl . Parameters ;
for ( int ip = 0 ; ip < h . Length ; ip + + )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
var hash = pl . Hashes [ ip ] ;
var parm = pl . Parameters [ ip ] ;
var tex = parm . Data as TextureBase ;
if ( tex ! = null )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
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 ;
2017-09-21 18:33:05 +08:00
}
}
2017-09-23 19:46:49 +08:00
tgnode . Expand ( ) ;
2017-09-21 18:33:05 +08:00
}
2017-09-23 19:46:49 +08:00
}
2017-09-21 18:33:05 +08:00
2017-09-23 19:46:49 +08:00
mnode . Expand ( ) ;
tmnode . Expand ( ) ;
2017-09-21 18:33:05 +08:00
}
}
2017-09-23 19:46:49 +08:00
private void UpdateSelectionDrawFlags ( TreeNode node )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
//update the selection draw flags depending on tag and checked/unchecked
var drwbl = node . Tag as DrawableBase ;
var model = node . Tag as DrawableModel ;
var geom = node . Tag as DrawableGeometry ;
bool rem = node . Checked ;
2018-01-02 04:52:54 +08:00
lock ( Renderer . RenderSyncRoot )
2017-09-21 18:33:05 +08:00
{
2017-09-23 19:46:49 +08:00
if ( drwbl ! = null )
{
if ( rem )
{
if ( DrawableDrawFlags . ContainsKey ( drwbl ) )
{
DrawableDrawFlags . Remove ( drwbl ) ;
}
}
else
{
DrawableDrawFlags [ drwbl ] = false ;
}
}
if ( model ! = null )
{
if ( rem )
{
2018-01-02 04:52:54 +08:00
if ( Renderer . SelectionModelDrawFlags . ContainsKey ( model ) )
2017-09-23 19:46:49 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . SelectionModelDrawFlags . Remove ( model ) ;
2017-09-23 19:46:49 +08:00
}
}
else
{
2018-01-02 04:52:54 +08:00
Renderer . SelectionModelDrawFlags [ model ] = false ;
2017-09-23 19:46:49 +08:00
}
}
if ( geom ! = null )
{
if ( rem )
{
2018-01-02 04:52:54 +08:00
if ( Renderer . SelectionGeometryDrawFlags . ContainsKey ( geom ) )
2017-09-23 19:46:49 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . SelectionGeometryDrawFlags . Remove ( geom ) ;
2017-09-23 19:46:49 +08:00
}
}
else
{
2018-01-02 04:52:54 +08:00
Renderer . SelectionGeometryDrawFlags [ geom ] = false ;
2017-09-23 19:46:49 +08:00
}
}
updateArchetypeStatus = true ;
2017-09-21 18:33:05 +08:00
}
}
2019-03-21 22:29:37 +08:00
public void OnMaterialFormClosed ( )
{
materialForm = null ;
}
2017-09-21 18:33:05 +08:00
2019-03-22 17:07:12 +08:00
public void OnModelModified ( )
{
modelModified = true ;
UpdateFormTitle ( ) ;
}
private void Save ( bool saveAs = false )
{
var editMode = exploreForm ? . EditMode ? ? false ;
if ( string . IsNullOrEmpty ( FilePath ) )
{
if ( ! editMode ) saveAs = true ;
if ( rpfFileEntry ? . Parent = = null ) saveAs = true ;
}
else
{
if ( ( FilePath . ToLowerInvariant ( ) . StartsWith ( GTAFolder . CurrentGTAFolder . ToLowerInvariant ( ) ) ) ) saveAs = true ;
if ( ! File . Exists ( FilePath ) ) saveAs = true ;
}
var fn = FilePath ;
if ( saveAs )
{
if ( ! string . IsNullOrEmpty ( fn ) )
{
var dir = new FileInfo ( fn ) . DirectoryName ;
if ( ! Directory . Exists ( dir ) ) dir = "" ;
SaveFileDialog . InitialDirectory = dir ;
}
SaveFileDialog . FileName = FileName ;
var fileExt = Path . GetExtension ( FileName ) ;
if ( ( fileExt . Length > 1 ) & & fileExt . StartsWith ( "." ) )
{
fileExt = fileExt . Substring ( 1 ) ;
}
SaveFileDialog . Filter = fileExt . ToUpperInvariant ( ) + " files|*." + fileExt + "|All files|*.*" ;
if ( SaveFileDialog . ShowDialog ( ) ! = DialogResult . OK ) return ;
fn = SaveFileDialog . FileName ;
}
byte [ ] fileBytes = null ;
#if ! DEBUG
try
{
#endif
if ( Ydr ! = null )
{
fileBytes = Ydr . Save ( ) ;
}
else if ( Ydd ! = null )
{
fileBytes = Ydd . Save ( ) ;
}
else if ( Yft ! = null )
{
fileBytes = Yft . Save ( ) ;
}
else if ( Ybn ! = null )
{
fileBytes = Ybn . Save ( ) ;
}
else if ( Ypt ! = null )
{
fileBytes = Ypt . Save ( ) ;
}
else if ( Ynv ! = null )
{
fileBytes = Ynv . Save ( ) ;
}
#if ! DEBUG
}
catch ( Exception ex )
{
MessageBox . Show ( "Error saving file!\n" + ex . ToString ( ) ) ;
return ;
}
#endif
if ( fileBytes = = null )
{
MessageBox . Show ( "Error saving file!\n fileBytes was null!" ) ;
return ;
}
var rpfSave = editMode & & ( rpfFileEntry ? . Parent ! = null ) & & ! saveAs ;
if ( rpfSave )
{
if ( ! rpfFileEntry . Path . ToLowerInvariant ( ) . StartsWith ( "mods" ) )
{
if ( MessageBox . Show ( "This file is NOT located in the mods folder - Are you SURE you want to save this file?\r\nWARNING: This could cause permanent damage to your game!!!" , "WARNING: Are you sure about this?" , MessageBoxButtons . YesNo ) ! = DialogResult . Yes )
{
return ; //that was a close one
}
}
try
{
if ( ! ( exploreForm ? . EnsureRpfValidEncryption ( rpfFileEntry . File ) ? ? false ) ) return ;
var newentry = RpfFile . CreateFile ( rpfFileEntry . Parent , rpfFileEntry . Name , fileBytes ) ;
if ( newentry ! = rpfFileEntry )
{ }
rpfFileEntry = newentry ;
exploreForm ? . RefreshMainListViewInvoke ( ) ; //update the file details in explorer...
StatusLabel . Text = rpfFileEntry . Name + " saved successfully at " + DateTime . Now . ToString ( ) ;
//victory!
}
catch ( Exception ex )
{
MessageBox . Show ( "Error saving file to RPF! The RPF archive may be corrupted...\r\n" + ex . ToString ( ) , "Really Bad Error" ) ;
}
}
else
{
try
{
File . WriteAllBytes ( fn , fileBytes ) ;
fileName = Path . GetFileName ( fn ) ;
FilePath = fn ;
StatusLabel . Text = fileName + " saved successfully at " + DateTime . Now . ToString ( ) ;
}
catch ( Exception ex )
{
MessageBox . Show ( "Error writing file to disk!\n" + ex . ToString ( ) ) ;
return ;
}
}
modelModified = false ;
UpdateFormTitle ( ) ;
}
2017-09-21 18:33:05 +08:00
private void ModelForm_Load ( object sender , EventArgs e )
{
Init ( ) ;
}
private void ModelForm_MouseDown ( object sender , MouseEventArgs e )
{
switch ( e . Button )
{
case MouseButtons . Left : MouseLButtonDown = true ; break ;
case MouseButtons . Right : MouseRButtonDown = true ; break ;
}
MouseDownPoint = e . Location ;
MouseLastPoint = MouseDownPoint ;
if ( MouseRButtonDown )
{
//SelectMousedItem();
}
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 ModelForm_MouseUp ( object sender , MouseEventArgs e )
{
switch ( e . Button )
{
case MouseButtons . Left : MouseLButtonDown = false ; break ;
case MouseButtons . Right : MouseRButtonDown = false ; break ;
}
//lock (MouseControlSyncRoot)
//{
// MouseControlButtons &= ~e.Button;
//}
}
private void ModelForm_MouseMove ( object sender , MouseEventArgs e )
{
int dx = e . X - MouseX ;
int dy = e . Y - MouseY ;
2018-01-02 08:07:24 +08:00
if ( MouseInvert )
{
dy = - dy ;
}
2017-09-21 18:33:05 +08:00
if ( MouseLButtonDown )
{
camera . MouseRotate ( dx , dy ) ;
}
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 ( ) ;
}
}
MouseX = e . X ;
MouseY = e . Y ;
MouseLastPoint = e . Location ;
}
private void ModelForm_MouseWheel ( object sender , MouseEventArgs e )
{
if ( e . Delta ! = 0 )
{
//if (ControlMode == WorldControlMode.Free)
//{
camera . MouseZoom ( e . Delta ) ;
//}
//else
//{
// lock (MouseControlSyncRoot)
// {
// MouseControlWheel += e.Delta;
// }
//}
}
}
private void ModelForm_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 = true ; // (!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 ) ;
}
}
2018-01-02 04:52:54 +08:00
if ( ! Input . kbmoving ) //don't trigger further actions if moving.
2017-09-21 18:33:05 +08:00
{
if ( ! ctrl )
{
//switch widget modes and spaces.
//if ((k == keyBindings.ExitEditMode))
//{
// if (Widget.Mode == WidgetMode.Default) ToggleWidgetSpace();
// else SetWidgetMode("Default");
//}
//if ((k == keyBindings.EditPosition))// && !enablemove)
//{
// if (Widget.Mode == WidgetMode.Position) ToggleWidgetSpace();
// else SetWidgetMode("Position");
//}
//if ((k == keyBindings.EditRotation))// && !enablemove)
//{
// if (Widget.Mode == WidgetMode.Rotation) ToggleWidgetSpace();
// else SetWidgetMode("Rotation");
//}
//if ((k == keyBindings.EditScale))// && !enablemove)
//{
// if (Widget.Mode == WidgetMode.Scale) ToggleWidgetSpace();
// else SetWidgetMode("Scale");
//}
//if (k == keyBindings.ToggleMouseSelect)
//{
// SetMouseSelect(!MouseSelectEnabled);
//}
//if (k == keyBindings.ToggleToolbar)
//{
// ToggleToolbar();
//}
//if (k == Keys.P)
//{
// //TEMPORARY!
// SetControlMode((ControlMode == WorldControlMode.Free) ? WorldControlMode.Ped : WorldControlMode.Free);
//}
}
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;
//}
}
//if (k == Keys.Escape) //temporary? panic get cursor back
//{
// if (ControlMode != WorldControlMode.Free) SetControlMode(WorldControlMode.Free);
//}
}
//if (ControlMode != WorldControlMode.Free)
//{
// e.Handled = true;
//}
}
private void ModelForm_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 ModelForm_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
}
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-26 08:27:18 +08:00
{
2018-01-02 04:52:54 +08:00
float fv = Renderer . timeofday * 60.0f ;
2017-09-26 08:27:18 +08:00
//TimeOfDayTrackBar.Value = (int)fv;
UpdateTimeOfDayLabel ( ) ;
}
//CameraPositionTextBox.Text = FloatUtil.GetVector3String(camera.Position, "0.##");
}
2017-09-21 18:33:05 +08:00
private void ToolsPanelShowButton_Click ( object sender , EventArgs e )
{
ToolsPanel . Visible = true ;
}
private void ToolsPanelHideButton_Click ( object sender , EventArgs e )
{
ToolsPanel . Visible = false ;
}
private void ToolsDragPanel_MouseDown ( object sender , MouseEventArgs e )
{
if ( e . Button = = MouseButtons . Left )
{
toolsPanelResizing = true ;
toolsPanelResizeStartX = e . X + ToolsPanel . Left + ToolsDragPanel . 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 + ToolsDragPanel . Left ;
int dx = rx - toolsPanelResizeStartX ;
ToolsPanel . Width = toolsPanelResizeStartRight - toolsPanelResizeStartLeft + dx ;
}
}
private void ModelsTreeView_AfterCheck ( object sender , TreeViewEventArgs e )
{
if ( e . Node ! = null )
{
UpdateSelectionDrawFlags ( e . Node ) ;
}
}
private void ModelsTreeView_NodeMouseDoubleClick ( object sender , TreeNodeMouseClickEventArgs e )
{
if ( e . Node ! = null )
{
e . Node . Checked = ! e . Node . Checked ;
//UpdateSelectionDrawFlags(e.Node);
}
}
private void ModelsTreeView_KeyPress ( object sender , KeyPressEventArgs e )
{
e . Handled = true ; //stops annoying ding sound...
}
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 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 ;
//Renderer.controllightdir = !Renderer.renderskydome;
2017-09-21 18:33:05 +08:00
}
private void ControlLightDirCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . controllightdir = ControlLightDirCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
private void TimeOfDayTrackBar_Scroll ( object sender , EventArgs e )
{
int v = TimeOfDayTrackBar . Value ;
float fh = v / 60.0f ;
UpdateTimeOfDayLabel ( ) ;
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 . timeofday = fh ;
timecycle . SetTime ( Renderer . timeofday ) ;
2017-09-21 18:33:05 +08:00
}
}
2018-01-02 04:52:54 +08:00
private void ShowCollisionMeshesCheckBox_CheckedChanged ( object sender , EventArgs e )
2017-09-21 18:33:05 +08:00
{
2018-01-02 04:52:54 +08:00
Renderer . rendercollisionmeshes = ShowCollisionMeshesCheckBox . Checked ;
Renderer . rendercollisionmeshlayerdrawable = ShowCollisionMeshesCheckBox . Checked ;
2017-09-21 18:33:05 +08:00
}
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 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
}
2019-01-09 09:15:38 +08:00
private void HDTexturesCheckBox_CheckedChanged ( object sender , EventArgs e )
{
Renderer . renderhdtextures = HDTexturesCheckBox . Checked ;
}
2017-09-21 18:33:05 +08:00
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 )
{
if ( TextureSamplerComboBox . SelectedItem is MetaName )
{
2018-01-02 04:52:54 +08:00
Renderer . shaders . RenderTextureSampler = ( MetaName ) 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 GridCheckBox_CheckedChanged ( object sender , EventArgs e )
{
enableGrid = GridCheckBox . Checked ;
}
private void GridSizeComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
float newgs ;
float . TryParse ( GridSizeComboBox . Text , out newgs ) ;
if ( newgs ! = gridSize )
{
gridSize = newgs ;
UpdateGridVerts ( ) ;
}
}
private void GridCountComboBox_SelectedIndexChanged ( object sender , EventArgs e )
{
int newgc ;
int . TryParse ( GridCountComboBox . Text , out newgc ) ;
if ( newgc ! = gridCount )
{
gridCount = newgc ;
UpdateGridVerts ( ) ;
}
}
2017-09-24 18:14:41 +08:00
private void SkeletonsCheckBox_CheckedChanged ( object sender , EventArgs e )
{
2018-01-02 04:52:54 +08:00
Renderer . renderskeletons = SkeletonsCheckBox . Checked ;
2017-09-24 18:14:41 +08:00
}
2017-09-21 18:33:05 +08:00
private void ErrorConsoleCheckBox_CheckedChanged ( object sender , EventArgs e )
{
ConsolePanel . Visible = ErrorConsoleCheckBox . Checked ;
}
private void StatusBarCheckBox_CheckedChanged ( object sender , EventArgs e )
{
StatusStrip . Visible = StatusBarCheckBox . Checked ;
}
2018-03-16 23:24:21 +08:00
private void TextureViewerButton_Click ( object sender , EventArgs e )
{
TextureDictionary td = null ;
if ( ( Ydr ! = null ) & & ( Ydr . Loaded ) )
{
td = Ydr . Drawable ? . ShaderGroup ? . TextureDictionary ;
}
else if ( ( Yft ! = null ) & & ( Yft . Loaded ) )
{
td = Yft . Fragment ? . Drawable ? . ShaderGroup ? . TextureDictionary ;
}
if ( td ! = null )
{
YtdForm f = new YtdForm ( ) ;
f . Show ( ) ;
f . LoadTexDict ( td , fileName ) ;
//f.LoadYtd(ytd);
}
else
{
MessageBox . Show ( "Couldn't find embedded texture dict." ) ;
}
}
2019-03-21 22:29:37 +08:00
private void MaterialEditorButton_Click ( object sender , EventArgs e )
{
DrawableBase drawable = null ;
Dictionary < uint , Drawable > dict = null ;
if ( ( Ydr ! = null ) & & ( Ydr . Loaded ) )
{
drawable = Ydr . Drawable ;
}
else if ( ( Ydd ! = null ) & & ( Ydd . Loaded ) )
{
dict = Ydd . Dict ;
}
else if ( ( Yft ! = null ) & & ( Yft . Loaded ) )
{
drawable = Yft . Fragment ? . Drawable ;
}
else if ( ( Ypt ! = null ) & & ( Ypt . Loaded ) )
{
dict = Ypt . DrawableDict ;
}
else
{
MessageBox . Show ( "Material editor not supported for the current file." ) ;
return ;
}
if ( materialForm = = null )
{
materialForm = new ModelMatForm ( this ) ;
if ( drawable ! = null )
{
materialForm . LoadModel ( drawable ) ;
}
else if ( dict ! = null )
{
materialForm . LoadModels ( dict ) ;
}
materialForm . Show ( this ) ;
}
else
{
if ( materialForm . WindowState = = FormWindowState . Minimized )
{
materialForm . WindowState = FormWindowState . Normal ;
}
materialForm . Focus ( ) ;
}
}
2019-03-22 17:07:12 +08:00
private void SaveButton_ButtonClick ( object sender , EventArgs e )
{
Save ( ) ;
}
private void SaveMenuButton_Click ( object sender , EventArgs e )
{
Save ( ) ;
}
private void SaveAsMenuButton_Click ( object sender , EventArgs e )
{
Save ( true ) ;
}
2017-09-21 18:33:05 +08:00
}
}