diff --git a/.gitignore b/.gitignore index e7ef7ad2..6f53fd7c 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,4 @@ DebuggerFrontend/DbgProtocol.cs WwiseTool UnpackGrid/Properties/launchSettings.json TerrainFixup/Properties/launchSettings.json +VTexTool/Properties/launchSettings.json diff --git a/ConverterApp/ConverterApp.csproj b/ConverterApp/ConverterApp.csproj index 64948aed..f590422b 100644 --- a/ConverterApp/ConverterApp.csproj +++ b/ConverterApp/ConverterApp.csproj @@ -1,16 +1,7 @@ - - - + - Debug - AnyCPU - {FAD67294-6223-47E0-8838-E4E7FBC53ED2} + net8.0-windows WinExe - Properties - ConverterApp - ConverterApp - v4.7.2 - 512 publish\ true Disk @@ -26,181 +17,54 @@ false false true - + false + true + true x64 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false x64 - pdbonly - true - bin\Release\ - prompt - 4 - false Always bin\Editor Debug\ - TRACE true - pdbonly - x86 - prompt MinimumRecommendedRules.ruleset - - ..\packages\AlphaFS.2.2.6\lib\net452\AlphaFS.dll - - - ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - - - - - - - - + UserControl - - DebugPane.cs - - + Component - - ExportItemSelection.cs - - + UserControl - - GR2Pane.cs - - + UserControl - - LocalizationPane.cs - - - Form - - - MainForm.cs - - + UserControl - - OsirisPane.cs - - + UserControl - - PackagePane.cs - - - - + UserControl - - ResourcePane.cs - - - + UserControl - - VirtualTexturesPane.cs - - - DebugPane.cs - - - ExportItemSelection.cs - - - GR2Pane.cs - - - LocalizationPane.cs - - - MainForm.cs - - - OsirisPane.cs - - - PackagePane.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - Designer - - - True - Resources.resx - True - - - ResourcePane.cs - - - VirtualTexturesPane.cs - - - - SettingsSingleFileGenerator - Settings.Designer.cs - - - True - Settings.settings - True - - - - - - {46372c50-4288-4b8e-af21-c934560600e0} - LSLib - - - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982} - OpenTK - + @@ -222,16 +86,9 @@ - - - - - - + + + + + \ No newline at end of file diff --git a/ConverterApp/ConverterAppSettings.cs b/ConverterApp/ConverterAppSettings.cs index b5bcae71..3dfb1464 100644 --- a/ConverterApp/ConverterAppSettings.cs +++ b/ConverterApp/ConverterAppSettings.cs @@ -76,7 +76,7 @@ public DebugPaneSettings Debugging set { debugSettings = value; } } - private Game selectedGame = Game.DivinityOriginalSin2DE; + private Game selectedGame = Game.BaldursGate3; public int SelectedGame { diff --git a/ConverterApp/MainForm.cs b/ConverterApp/MainForm.cs index 3117fd03..fd173ebd 100644 --- a/ConverterApp/MainForm.cs +++ b/ConverterApp/MainForm.cs @@ -1,10 +1,10 @@ using System; -using Alphaleonis.Win32.Filesystem; using System.Windows.Forms; using LSLib.LS; using LSLib.LS.Enums; using Newtonsoft.Json; using System.ComponentModel; +using System.IO; namespace ConverterApp { diff --git a/ConverterApp/PackagePane.cs b/ConverterApp/PackagePane.cs index defd2034..0db0ef7f 100644 --- a/ConverterApp/PackagePane.cs +++ b/ConverterApp/PackagePane.cs @@ -1,7 +1,7 @@ using System; using System.Diagnostics; +using System.IO; using System.Windows.Forms; -using Alphaleonis.Win32.Filesystem; using LSLib.LS; using LSLib.LS.Enums; diff --git a/ConverterApp/Program.cs b/ConverterApp/Program.cs index 00334a96..db9175b5 100644 --- a/ConverterApp/Program.cs +++ b/ConverterApp/Program.cs @@ -1,6 +1,8 @@ using System; +using System.Runtime.Versioning; using System.Windows.Forms; +[assembly: SupportedOSPlatform("windows")] namespace ConverterApp { static class Program diff --git a/ConverterApp/Properties/AssemblyInfo.cs b/ConverterApp/Properties/AssemblyInfo.cs deleted file mode 100644 index 7dfb1673..00000000 --- a/ConverterApp/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,35 +0,0 @@ -using System.Reflection; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("LSLib Toolkit - Main Application")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LSLib")] -[assembly: AssemblyCopyright("Copyright © Norbyte 2012-2023")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("565dd5e7-6720-469d-b9f4-a922a7014747")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.15.14.0")] -[assembly: AssemblyFileVersion("1.15.14.0")] diff --git a/ConverterApp/VirtualTexturesPane.Designer.cs b/ConverterApp/VirtualTexturesPane.Designer.cs index 69fa5488..ba424168 100644 --- a/ConverterApp/VirtualTexturesPane.Designer.cs +++ b/ConverterApp/VirtualTexturesPane.Designer.cs @@ -28,166 +28,312 @@ protected override void Dispose(bool disposing) /// private void InitializeComponent() { - this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.extractTileSetBtn = new System.Windows.Forms.Button(); - this.destinationPathBrowseBtn = new System.Windows.Forms.Button(); - this.gtsBrowseBtn = new System.Windows.Forms.Button(); - this.gtsPath = new System.Windows.Forms.TextBox(); - this.label4 = new System.Windows.Forms.Label(); - this.destinationPath = new System.Windows.Forms.TextBox(); - this.label3 = new System.Windows.Forms.Label(); - this.destinationPathDlg = new System.Windows.Forms.FolderBrowserDialog(); - this.gtsFileDlg = new System.Windows.Forms.OpenFileDialog(); - this.actionProgressLabel = new System.Windows.Forms.Label(); - this.actionProgress = new System.Windows.Forms.ProgressBar(); - this.label5 = new System.Windows.Forms.Label(); - this.groupBox1.SuspendLayout(); - this.SuspendLayout(); + groupBox1 = new System.Windows.Forms.GroupBox(); + extractTileSetBtn = new System.Windows.Forms.Button(); + destinationPathBrowseBtn = new System.Windows.Forms.Button(); + gtsBrowseBtn = new System.Windows.Forms.Button(); + gtsPath = new System.Windows.Forms.TextBox(); + label4 = new System.Windows.Forms.Label(); + destinationPath = new System.Windows.Forms.TextBox(); + label3 = new System.Windows.Forms.Label(); + destinationPathDlg = new System.Windows.Forms.FolderBrowserDialog(); + gtsFileDlg = new System.Windows.Forms.OpenFileDialog(); + actionProgressLabel = new System.Windows.Forms.Label(); + actionProgress = new System.Windows.Forms.ProgressBar(); + label5 = new System.Windows.Forms.Label(); + groupBox2 = new System.Windows.Forms.GroupBox(); + modRootPathBrowseBtn = new System.Windows.Forms.Button(); + tileSetBrowseBtn = new System.Windows.Forms.Button(); + tileSetBuildBtn = new System.Windows.Forms.Button(); + button1 = new System.Windows.Forms.Button(); + button2 = new System.Windows.Forms.Button(); + button3 = new System.Windows.Forms.Button(); + tileSetConfigPath = new System.Windows.Forms.TextBox(); + label1 = new System.Windows.Forms.Label(); + modRootPath = new System.Windows.Forms.TextBox(); + label2 = new System.Windows.Forms.Label(); + modRootPathDlg = new System.Windows.Forms.FolderBrowserDialog(); + tileSetConfigDlg = new System.Windows.Forms.OpenFileDialog(); + groupBox1.SuspendLayout(); + groupBox2.SuspendLayout(); + SuspendLayout(); // // groupBox1 // - this.groupBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.groupBox1.Controls.Add(this.extractTileSetBtn); - this.groupBox1.Controls.Add(this.destinationPathBrowseBtn); - this.groupBox1.Controls.Add(this.gtsBrowseBtn); - this.groupBox1.Controls.Add(this.gtsPath); - this.groupBox1.Controls.Add(this.label4); - this.groupBox1.Controls.Add(this.destinationPath); - this.groupBox1.Controls.Add(this.label3); - this.groupBox1.Location = new System.Drawing.Point(9, 16); - this.groupBox1.Margin = new System.Windows.Forms.Padding(4); - this.groupBox1.Name = "groupBox1"; - this.groupBox1.Padding = new System.Windows.Forms.Padding(4); - this.groupBox1.Size = new System.Drawing.Size(1167, 170); - this.groupBox1.TabIndex = 66; - this.groupBox1.TabStop = false; - this.groupBox1.Text = "Extract Virtual Textures"; + groupBox1.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + groupBox1.Controls.Add(extractTileSetBtn); + groupBox1.Controls.Add(destinationPathBrowseBtn); + groupBox1.Controls.Add(gtsBrowseBtn); + groupBox1.Controls.Add(gtsPath); + groupBox1.Controls.Add(label4); + groupBox1.Controls.Add(destinationPath); + groupBox1.Controls.Add(label3); + groupBox1.Location = new System.Drawing.Point(9, 20); + groupBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + groupBox1.Name = "groupBox1"; + groupBox1.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); + groupBox1.Size = new System.Drawing.Size(1167, 212); + groupBox1.TabIndex = 66; + groupBox1.TabStop = false; + groupBox1.Text = "Extract Virtual Textures"; // // extractTileSetBtn // - this.extractTileSetBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.extractTileSetBtn.Location = new System.Drawing.Point(945, 134); - this.extractTileSetBtn.Margin = new System.Windows.Forms.Padding(4); - this.extractTileSetBtn.Name = "extractTileSetBtn"; - this.extractTileSetBtn.Size = new System.Drawing.Size(213, 28); - this.extractTileSetBtn.TabIndex = 62; - this.extractTileSetBtn.Text = "Extract Textures"; - this.extractTileSetBtn.UseVisualStyleBackColor = true; - this.extractTileSetBtn.Click += new System.EventHandler(this.extractTileSetBtn_Click); + extractTileSetBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right; + extractTileSetBtn.Location = new System.Drawing.Point(945, 168); + extractTileSetBtn.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + extractTileSetBtn.Name = "extractTileSetBtn"; + extractTileSetBtn.Size = new System.Drawing.Size(213, 35); + extractTileSetBtn.TabIndex = 62; + extractTileSetBtn.Text = "Extract Textures"; + extractTileSetBtn.UseVisualStyleBackColor = true; + extractTileSetBtn.Click += extractTileSetBtn_Click; // // destinationPathBrowseBtn // - this.destinationPathBrowseBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.destinationPathBrowseBtn.Location = new System.Drawing.Point(1105, 94); - this.destinationPathBrowseBtn.Margin = new System.Windows.Forms.Padding(4); - this.destinationPathBrowseBtn.Name = "destinationPathBrowseBtn"; - this.destinationPathBrowseBtn.Size = new System.Drawing.Size(55, 28); - this.destinationPathBrowseBtn.TabIndex = 61; - this.destinationPathBrowseBtn.Text = "..."; - this.destinationPathBrowseBtn.UseVisualStyleBackColor = true; - this.destinationPathBrowseBtn.Click += new System.EventHandler(this.destinationPathBrowseBtn_Click); + destinationPathBrowseBtn.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + destinationPathBrowseBtn.Location = new System.Drawing.Point(1105, 118); + destinationPathBrowseBtn.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + destinationPathBrowseBtn.Name = "destinationPathBrowseBtn"; + destinationPathBrowseBtn.Size = new System.Drawing.Size(55, 35); + destinationPathBrowseBtn.TabIndex = 61; + destinationPathBrowseBtn.Text = "..."; + destinationPathBrowseBtn.UseVisualStyleBackColor = true; + destinationPathBrowseBtn.Click += destinationPathBrowseBtn_Click; // // gtsBrowseBtn // - this.gtsBrowseBtn.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.gtsBrowseBtn.Location = new System.Drawing.Point(1105, 37); - this.gtsBrowseBtn.Margin = new System.Windows.Forms.Padding(4); - this.gtsBrowseBtn.Name = "gtsBrowseBtn"; - this.gtsBrowseBtn.Size = new System.Drawing.Size(55, 28); - this.gtsBrowseBtn.TabIndex = 58; - this.gtsBrowseBtn.Text = "..."; - this.gtsBrowseBtn.UseVisualStyleBackColor = true; - this.gtsBrowseBtn.Click += new System.EventHandler(this.gtpBrowseBtn_Click); + gtsBrowseBtn.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + gtsBrowseBtn.Location = new System.Drawing.Point(1105, 46); + gtsBrowseBtn.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + gtsBrowseBtn.Name = "gtsBrowseBtn"; + gtsBrowseBtn.Size = new System.Drawing.Size(55, 35); + gtsBrowseBtn.TabIndex = 58; + gtsBrowseBtn.Text = "..."; + gtsBrowseBtn.UseVisualStyleBackColor = true; + gtsBrowseBtn.Click += gtpBrowseBtn_Click; // // gtsPath // - this.gtsPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.gtsPath.Location = new System.Drawing.Point(12, 39); - this.gtsPath.Margin = new System.Windows.Forms.Padding(4); - this.gtsPath.Name = "gtsPath"; - this.gtsPath.Size = new System.Drawing.Size(1093, 22); - this.gtsPath.TabIndex = 56; + gtsPath.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + gtsPath.Location = new System.Drawing.Point(12, 49); + gtsPath.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + gtsPath.Name = "gtsPath"; + gtsPath.Size = new System.Drawing.Size(1093, 27); + gtsPath.TabIndex = 56; // // label4 // - this.label4.AutoSize = true; - this.label4.Location = new System.Drawing.Point(8, 20); - this.label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label4.Name = "label4"; - this.label4.Size = new System.Drawing.Size(119, 16); - this.label4.TabIndex = 57; - this.label4.Text = "Tileset (GTS) path:"; + label4.AutoSize = true; + label4.Location = new System.Drawing.Point(8, 25); + label4.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + label4.Name = "label4"; + label4.Size = new System.Drawing.Size(129, 20); + label4.TabIndex = 57; + label4.Text = "Tileset (GTS) path:"; // // destinationPath // - this.destinationPath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.destinationPath.Location = new System.Drawing.Point(12, 96); - this.destinationPath.Margin = new System.Windows.Forms.Padding(4); - this.destinationPath.Name = "destinationPath"; - this.destinationPath.Size = new System.Drawing.Size(1093, 22); - this.destinationPath.TabIndex = 59; + destinationPath.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + destinationPath.Location = new System.Drawing.Point(12, 120); + destinationPath.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + destinationPath.Name = "destinationPath"; + destinationPath.Size = new System.Drawing.Size(1093, 27); + destinationPath.TabIndex = 59; // // label3 // - this.label3.AutoSize = true; - this.label3.Location = new System.Drawing.Point(8, 76); - this.label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label3.Name = "label3"; - this.label3.Size = new System.Drawing.Size(106, 16); - this.label3.TabIndex = 60; - this.label3.Text = "Destination path:"; + label3.AutoSize = true; + label3.Location = new System.Drawing.Point(8, 95); + label3.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + label3.Name = "label3"; + label3.Size = new System.Drawing.Size(122, 20); + label3.TabIndex = 60; + label3.Text = "Destination path:"; // // gtsFileDlg // - this.gtsFileDlg.Filter = "Virtual Texture Set (.gts)|*.gts"; + gtsFileDlg.Filter = "Virtual Texture Set (.gts)|*.gts"; // // actionProgressLabel // - this.actionProgressLabel.AutoSize = true; - this.actionProgressLabel.Location = new System.Drawing.Point(94, 195); - this.actionProgressLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.actionProgressLabel.Name = "actionProgressLabel"; - this.actionProgressLabel.Size = new System.Drawing.Size(0, 16); - this.actionProgressLabel.TabIndex = 67; + actionProgressLabel.AutoSize = true; + actionProgressLabel.Location = new System.Drawing.Point(88, 478); + actionProgressLabel.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + actionProgressLabel.Name = "actionProgressLabel"; + actionProgressLabel.Size = new System.Drawing.Size(0, 20); + actionProgressLabel.TabIndex = 67; // // actionProgress // - this.actionProgress.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.actionProgress.Location = new System.Drawing.Point(9, 212); - this.actionProgress.Margin = new System.Windows.Forms.Padding(4); - this.actionProgress.Name = "actionProgress"; - this.actionProgress.Size = new System.Drawing.Size(1168, 28); - this.actionProgress.TabIndex = 65; + actionProgress.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + actionProgress.Location = new System.Drawing.Point(9, 501); + actionProgress.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + actionProgress.Name = "actionProgress"; + actionProgress.Size = new System.Drawing.Size(1168, 35); + actionProgress.TabIndex = 65; // // label5 // - this.label5.AutoSize = true; - this.label5.Location = new System.Drawing.Point(5, 193); - this.label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); - this.label5.Name = "label5"; - this.label5.Size = new System.Drawing.Size(65, 16); - this.label5.TabIndex = 66; - this.label5.Text = "Progress:"; + label5.AutoSize = true; + label5.Location = new System.Drawing.Point(5, 477); + label5.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + label5.Name = "label5"; + label5.Size = new System.Drawing.Size(68, 20); + label5.TabIndex = 66; + label5.Text = "Progress:"; + // + // groupBox2 + // + groupBox2.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + groupBox2.Controls.Add(modRootPathBrowseBtn); + groupBox2.Controls.Add(tileSetBrowseBtn); + groupBox2.Controls.Add(tileSetBuildBtn); + groupBox2.Controls.Add(button1); + groupBox2.Controls.Add(button2); + groupBox2.Controls.Add(button3); + groupBox2.Controls.Add(tileSetConfigPath); + groupBox2.Controls.Add(label1); + groupBox2.Controls.Add(modRootPath); + groupBox2.Controls.Add(label2); + groupBox2.Location = new System.Drawing.Point(10, 252); + groupBox2.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + groupBox2.Name = "groupBox2"; + groupBox2.Padding = new System.Windows.Forms.Padding(4, 5, 4, 5); + groupBox2.Size = new System.Drawing.Size(1167, 212); + groupBox2.TabIndex = 68; + groupBox2.TabStop = false; + groupBox2.Text = "Build Tile Set"; + // + // modRootPathBrowseBtn + // + modRootPathBrowseBtn.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + modRootPathBrowseBtn.Location = new System.Drawing.Point(1104, 119); + modRootPathBrowseBtn.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + modRootPathBrowseBtn.Name = "modRootPathBrowseBtn"; + modRootPathBrowseBtn.Size = new System.Drawing.Size(55, 35); + modRootPathBrowseBtn.TabIndex = 64; + modRootPathBrowseBtn.Text = "..."; + modRootPathBrowseBtn.UseVisualStyleBackColor = true; + modRootPathBrowseBtn.Click += modRootPathBrowseBtn_Click; + // + // tileSetBrowseBtn + // + tileSetBrowseBtn.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + tileSetBrowseBtn.Location = new System.Drawing.Point(1104, 47); + tileSetBrowseBtn.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + tileSetBrowseBtn.Name = "tileSetBrowseBtn"; + tileSetBrowseBtn.Size = new System.Drawing.Size(55, 35); + tileSetBrowseBtn.TabIndex = 63; + tileSetBrowseBtn.Text = "..."; + tileSetBrowseBtn.UseVisualStyleBackColor = true; + tileSetBrowseBtn.Click += tileSetConfigBrowseBtn_Click; + // + // tileSetBuildBtn + // + tileSetBuildBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right; + tileSetBuildBtn.Location = new System.Drawing.Point(944, 167); + tileSetBuildBtn.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + tileSetBuildBtn.Name = "tileSetBuildBtn"; + tileSetBuildBtn.Size = new System.Drawing.Size(213, 35); + tileSetBuildBtn.TabIndex = 63; + tileSetBuildBtn.Text = "Build"; + tileSetBuildBtn.UseVisualStyleBackColor = true; + tileSetBuildBtn.Click += tileSetBuildBtn_Click; + // + // button1 + // + button1.Anchor = System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right; + button1.Location = new System.Drawing.Point(1911, 278); + button1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + button1.Name = "button1"; + button1.Size = new System.Drawing.Size(213, 35); + button1.TabIndex = 62; + button1.Text = "Extract Textures"; + button1.UseVisualStyleBackColor = true; + // + // button2 + // + button2.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + button2.Location = new System.Drawing.Point(2071, 120); + button2.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + button2.Name = "button2"; + button2.Size = new System.Drawing.Size(55, 35); + button2.TabIndex = 61; + button2.Text = "..."; + button2.UseVisualStyleBackColor = true; + // + // button3 + // + button3.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right; + button3.Location = new System.Drawing.Point(2071, 48); + button3.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + button3.Name = "button3"; + button3.Size = new System.Drawing.Size(55, 35); + button3.TabIndex = 58; + button3.Text = "..."; + button3.UseVisualStyleBackColor = true; + // + // tileSetConfigPath + // + tileSetConfigPath.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + tileSetConfigPath.Location = new System.Drawing.Point(13, 51); + tileSetConfigPath.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + tileSetConfigPath.Name = "tileSetConfigPath"; + tileSetConfigPath.Size = new System.Drawing.Size(1091, 27); + tileSetConfigPath.TabIndex = 56; + // + // label1 + // + label1.AutoSize = true; + label1.Location = new System.Drawing.Point(9, 27); + label1.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + label1.Name = "label1"; + label1.Size = new System.Drawing.Size(156, 20); + label1.TabIndex = 57; + label1.Text = "Tile Set Configuration:"; + // + // modRootPath + // + modRootPath.Anchor = System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left | System.Windows.Forms.AnchorStyles.Right; + modRootPath.Location = new System.Drawing.Point(13, 122); + modRootPath.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5); + modRootPath.Name = "modRootPath"; + modRootPath.Size = new System.Drawing.Size(1091, 27); + modRootPath.TabIndex = 59; + // + // label2 + // + label2.AutoSize = true; + label2.Location = new System.Drawing.Point(9, 97); + label2.Margin = new System.Windows.Forms.Padding(4, 0, 4, 0); + label2.Name = "label2"; + label2.Size = new System.Drawing.Size(109, 20); + label2.TabIndex = 60; + label2.Text = "Mod root path:"; + // + // tileSetConfigDlg + // + tileSetConfigDlg.Filter = "Virtual Texture Set Configuration (.xml)|*.xml"; // // VirtualTexturesPane // - this.AutoScaleDimensions = new System.Drawing.SizeF(8F, 16F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.Controls.Add(this.actionProgressLabel); - this.Controls.Add(this.groupBox1); - this.Controls.Add(this.actionProgress); - this.Controls.Add(this.label5); - this.Name = "VirtualTexturesPane"; - this.Size = new System.Drawing.Size(1188, 378); - this.groupBox1.ResumeLayout(false); - this.groupBox1.PerformLayout(); - this.ResumeLayout(false); - this.PerformLayout(); - + AutoScaleDimensions = new System.Drawing.SizeF(8F, 20F); + AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; + Controls.Add(groupBox2); + Controls.Add(actionProgressLabel); + Controls.Add(groupBox1); + Controls.Add(actionProgress); + Controls.Add(label5); + Margin = new System.Windows.Forms.Padding(3, 4, 3, 4); + Name = "VirtualTexturesPane"; + Size = new System.Drawing.Size(1188, 570); + groupBox1.ResumeLayout(false); + groupBox1.PerformLayout(); + groupBox2.ResumeLayout(false); + groupBox2.PerformLayout(); + ResumeLayout(false); + PerformLayout(); } #endregion @@ -205,5 +351,18 @@ private void InitializeComponent() private System.Windows.Forms.Label actionProgressLabel; private System.Windows.Forms.ProgressBar actionProgress; private System.Windows.Forms.Label label5; + private System.Windows.Forms.GroupBox groupBox2; + private System.Windows.Forms.Button button1; + private System.Windows.Forms.Button button2; + private System.Windows.Forms.Button button3; + private System.Windows.Forms.TextBox tileSetConfigPath; + private System.Windows.Forms.Label label1; + private System.Windows.Forms.TextBox modRootPath; + private System.Windows.Forms.Label label2; + private System.Windows.Forms.FolderBrowserDialog modRootPathDlg; + private System.Windows.Forms.OpenFileDialog tileSetConfigDlg; + private System.Windows.Forms.Button modRootPathBrowseBtn; + private System.Windows.Forms.Button tileSetBrowseBtn; + private System.Windows.Forms.Button tileSetBuildBtn; } } diff --git a/ConverterApp/VirtualTexturesPane.cs b/ConverterApp/VirtualTexturesPane.cs index caad02b5..0782e3a5 100644 --- a/ConverterApp/VirtualTexturesPane.cs +++ b/ConverterApp/VirtualTexturesPane.cs @@ -1,14 +1,7 @@ -using Alphaleonis.Win32.Filesystem; -using LSLib.LS; -using LSLib.VirtualTextures; +using LSLib.VirtualTextures; using System; -using System.Collections.Generic; -using System.ComponentModel; -using System.Data; -using System.Drawing; +using System.IO; using System.Linq; -using System.Text; -using System.Threading.Tasks; using System.Windows.Forms; namespace ConverterApp @@ -46,11 +39,13 @@ private void extractTileSetBtn_Click(object sender, EventArgs e) try { var tileSet = new VirtualTileSet(gtsPath.Text); - for (var pfIdx = 0; pfIdx < tileSet.PageFileInfos.Count; pfIdx++) + var textures = tileSet.FourCCMetadata.ExtractTextureMetadata(); + + var i = 0; + foreach (var texture in textures) { - var fileInfo = tileSet.PageFileInfos[pfIdx]; - actionProgressLabel.Text = fileInfo.FileName; - actionProgress.Value = pfIdx * 100 / tileSet.PageFileInfos.Count; + actionProgressLabel.Text = "GTex: " + texture.Name; + actionProgress.Value = i++ * 100 / textures.Count; Application.DoEvents(); for (var layer = 0; layer < tileSet.TileSetLayers.Length; layer++) @@ -59,13 +54,13 @@ private void extractTileSetBtn_Click(object sender, EventArgs e) var level = 0; do { - tex = tileSet.ExtractPageFileTexture(pfIdx, level, layer); + tex = tileSet.ExtractTexture(level, layer, texture); level++; } while (tex == null && level < tileSet.TileSetLevels.Length); if (tex != null) { - var outputPath = destinationPath.Text + Path.DirectorySeparator + Path.GetFileNameWithoutExtension(fileInfo.FileName) + $"_{layer}.dds"; + var outputPath = destinationPath.Text + Path.PathSeparator + texture.Name + $"_{layer}.dds"; tex.SaveDDS(outputPath); } } @@ -87,5 +82,69 @@ private void extractTileSetBtn_Click(object sender, EventArgs e) extractTileSetBtn.Enabled = true; } } + + private void tileSetConfigBrowseBtn_Click(object sender, EventArgs e) + { + if (tileSetConfigDlg.ShowDialog(this) == DialogResult.OK) + { + tileSetConfigPath.Text = tileSetConfigDlg.FileName; + } + } + + private void modRootPathBrowseBtn_Click(object sender, EventArgs e) + { + DialogResult result = modRootPathDlg.ShowDialog(this); + if (result == DialogResult.OK) + { + modRootPath.Text = modRootPathDlg.SelectedPath; + } + } + + private void tileSetBuildBtn_Click(object sender, EventArgs ev) + { + try + { + var descriptor = new TileSetDescriptor(); + descriptor.RootPath = modRootPath.Text; + descriptor.Load(tileSetConfigPath.Text); + + var builder = new TileSetBuilder(descriptor.Config); + builder.OnStepStarted += (step) => { + actionProgressLabel.Text = step; + Application.DoEvents(); + }; + builder.OnStepProgress += (numerator, denumerator) => { + actionProgress.Maximum = denumerator; + actionProgress.Value = numerator; + Application.DoEvents(); + }; + + builder.OnStepStarted("Adding textures"); + foreach (var texture in descriptor.Textures) + { + var layerPaths = texture.Layers.Select(name => name != null ? Path.Combine(descriptor.SourceTexturePath, name) : null).ToList(); + builder.AddTexture(texture.Name, layerPaths); + } + + builder.Build(descriptor.VirtualTexturePath); + + MessageBox.Show("Tile set build completed."); + } + catch (InvalidDataException e) + { + MessageBox.Show($"{e.Message}", "Tile Set Build Failed", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + catch (FileNotFoundException e) + { + MessageBox.Show($"{e.Message}", "Tile Set Build Failed", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + catch (Exception e) + { + MessageBox.Show($"Internal error!{Environment.NewLine}{Environment.NewLine}{e}", "Tile Set Build Failed", MessageBoxButtons.OK, MessageBoxIcon.Error); + } + + actionProgressLabel.Text = ""; + actionProgress.Value = 0; + } } } diff --git a/ConverterApp/VirtualTexturesPane.resx b/ConverterApp/VirtualTexturesPane.resx index 2f94ab20..3d97df92 100644 --- a/ConverterApp/VirtualTexturesPane.resx +++ b/ConverterApp/VirtualTexturesPane.resx @@ -1,17 +1,17 @@  - @@ -118,9 +118,15 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - 1045, 20 + 53, 22 - 1202, 20 + 234, 23 + + + 415, 25 + + + 581, 25 \ No newline at end of file diff --git a/ConverterApp/packages.config b/ConverterApp/packages.config deleted file mode 100644 index 1a84d93a..00000000 --- a/ConverterApp/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/DebuggerFrontend/DebugInfoLoader.cs b/DebuggerFrontend/DebugInfoLoader.cs index ef642757..07fc859f 100644 --- a/DebuggerFrontend/DebugInfoLoader.cs +++ b/DebuggerFrontend/DebugInfoLoader.cs @@ -1,5 +1,4 @@ using System; -using Google.Protobuf; using System.IO; using LSLib.LS; using LSLib.LS.Story.Compiler; @@ -204,7 +203,7 @@ public StoryDebugInfo Load(byte[] msgPayload) var compressed = new byte[msgPayload.Length - 4]; Array.Copy(msgPayload, 0, compressed, 0, msgPayload.Length - 4); - byte flags = BinUtils.MakeCompressionFlags(LSLib.LS.Enums.CompressionMethod.LZ4, LSLib.LS.Enums.CompressionLevel.FastCompression); + byte flags = BinUtils.MakeCompressionFlags(LSLib.LS.Enums.CompressionMethod.LZ4, LSLib.LS.Enums.LSCompressionLevel.FastCompression); byte[] decompressed = BinUtils.Decompress(compressed, (int)decompressedSize, flags); var msg = StoryDebugInfoMsg.Parser.ParseFrom(decompressed); var debugInfo = FromProtobuf(msg); diff --git a/DebuggerFrontend/DebuggerFrontend.csproj b/DebuggerFrontend/DebuggerFrontend.csproj index 1edc4e61..8d69683b 100644 --- a/DebuggerFrontend/DebuggerFrontend.csproj +++ b/DebuggerFrontend/DebuggerFrontend.csproj @@ -1,105 +1,35 @@ - - - + - Debug - AnyCPU - {31E71543-CBCF-43BB-AF77-D210D548118E} + net8.0 Exe LSTools.DebuggerFrontend - DebuggerFrontend - v4.7.2 - 512 - true - - - - x64 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - + false x64 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - ..\packages\CommandLineArgumentsParser.3.0.19\lib\net452\CommandLineArgumentsParser.dll - - - ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll - - - ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll - - - ..\External\gppg\binaries\QUT.ShiftReduceParser.dll - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - + - - {46372c50-4288-4b8e-af21-c934560600e0} - LSLib - + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + - - $(SolutionDir)\External\protoc\bin\protoc.exe --proto_path=$(ProjectDir) --csharp_out=$(ProjectDir) DbgProtocol.proto -$(SolutionDir)\External\protoc\bin\protoc.exe --proto_path=$(ProjectDir)..\StoryCompiler\ --csharp_out=$(ProjectDir) debuginfo.proto -"$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(ProjectDir)\ExpressionParser\Expression.lex.cs" "$(ProjectDir)\ExpressionParser\Expression.lex" -"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(ProjectDir)\ExpressionParser\Expression.yy.cs" "$(ProjectDir)\ExpressionParser\Expression.yy" + "$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(SolutionDir)\DebuggerFrontend\ExpressionParser\Expression.lex.cs" "$(SolutionDir)\DebuggerFrontend\ExpressionParser\Expression.lex" +"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(SolutionDir)\DebuggerFrontend\ExpressionParser\Expression.yy.cs" "$(SolutionDir)\DebuggerFrontend\ExpressionParser\Expression.yy" + Osiris VS Code Debugger Frontend + LSLib + Copyright © Norbyte 2012-2018 + 1.0.0.0 + 1.0.0.0 \ No newline at end of file diff --git a/DebuggerFrontend/Properties/AssemblyInfo.cs b/DebuggerFrontend/Properties/AssemblyInfo.cs index 3499587c..04588128 100644 --- a/DebuggerFrontend/Properties/AssemblyInfo.cs +++ b/DebuggerFrontend/Properties/AssemblyInfo.cs @@ -1,16 +1,7 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Osiris VS Code Debugger Frontend")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LSLib")] -[assembly: AssemblyCopyright("Copyright © Norbyte 2012-2018")] +using System.Runtime.Versioning; [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -20,17 +11,4 @@ [assembly: ComVisible(false)] // The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("31e71543-cbcf-43bb-af77-d210d548118e")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] +[assembly: Guid("31e71543-cbcf-43bb-af77-d210d548118e")] \ No newline at end of file diff --git a/DebuggerFrontend/debuginfo.proto b/DebuggerFrontend/debuginfo.proto new file mode 100644 index 00000000..14914e97 --- /dev/null +++ b/DebuggerFrontend/debuginfo.proto @@ -0,0 +1,89 @@ +syntax = "proto3"; + +package LSTools.StoryCompiler; + +option optimize_for = LITE_RUNTIME; + +message DatabaseDebugInfoMsg { + uint32 id = 1; + string name = 2; + repeated uint32 param_types = 3; +} + +message ActionDebugInfoMsg { + uint32 line = 1; +} + +message GoalDebugInfoMsg { + uint32 id = 1; + string name = 2; + string path = 3; + repeated ActionDebugInfoMsg init_actions = 4; + repeated ActionDebugInfoMsg exit_actions = 5; +} + +message RuleVariableDebugInfoMsg { + uint32 index = 1; + uint32 type = 2; + string name = 3; + bool unused = 4; +} + +message RuleDebugInfoMsg { + uint32 id = 1; + uint32 goal_id = 2; + repeated RuleVariableDebugInfoMsg variables = 3; + string name = 4; + repeated ActionDebugInfoMsg actions = 5; + uint32 conditions_start_line = 6; + uint32 conditions_end_line = 7; + uint32 actions_start_line = 8; + uint32 actions_end_line = 9; +} + +message NodeDebugInfoMsg { + enum NodeType { + UNUSED = 0; + DATABASE = 1; + PROC = 2; + DIV_QUERY = 3; + AND = 4; + NOT_AND = 5; + REL_OP = 6; + RULE = 7; + INTERNAL_QUERY = 8; + USER_QUERY = 9; + } + + uint32 id = 1; + uint32 rule_id = 2; + uint32 line = 3; + map column_maps = 4; + uint32 database_id = 5; + string name = 6; + NodeType type = 7; + uint32 parent_node_id = 8; + string function_name = 9; + uint32 function_arity = 10; +} + +message FunctionParamDebugInfoMsg { + uint32 type_id = 1; + string name = 2; + bool out = 3; +} + +message FunctionDebugInfoMsg { + string name = 1; + repeated FunctionParamDebugInfoMsg params = 2; + uint32 type_id = 3; +} + +message StoryDebugInfoMsg { + repeated DatabaseDebugInfoMsg databases = 1; + repeated GoalDebugInfoMsg goals = 2; + repeated RuleDebugInfoMsg rules = 3; + repeated NodeDebugInfoMsg nodes = 4; + repeated FunctionDebugInfoMsg functions = 5; + uint32 version = 6; +} diff --git a/DebuggerFrontend/packages.config b/DebuggerFrontend/packages.config deleted file mode 100644 index 23b37023..00000000 --- a/DebuggerFrontend/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/Divine/CLI/CommandLineActions.cs b/Divine/CLI/CommandLineActions.cs index 53d20617..a2874c10 100644 --- a/Divine/CLI/CommandLineActions.cs +++ b/Divine/CLI/CommandLineActions.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text.RegularExpressions; -using Alphaleonis.Win32.Filesystem; using LSLib.LS; using LSLib.LS.Enums; diff --git a/Divine/Divine.csproj b/Divine/Divine.csproj index f2e2e89c..e4a8d2e9 100644 --- a/Divine/Divine.csproj +++ b/Divine/Divine.csproj @@ -1,81 +1,19 @@ - - - + - Debug - AnyCPU - {CBFEE38F-5F12-4D6F-B4FB-267FB68A6BEA} + net8.0 Exe - Properties - Divine - divine - v4.7.2 - 512 - true - - - - x64 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - + false x64 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 + LSLib - Divine Commandline Tool + LSLib + 1.15.14.0 + 1.15.14.0 - - ..\packages\AlphaFS.2.2.6\lib\net452\AlphaFS.dll - - - ..\packages\CommandLineArgumentsParser.3.0.19\lib\net452\CommandLineArgumentsParser.dll - - - - - - - - - - - - - - - - - - - - - - - + - - {46372c50-4288-4b8e-af21-c934560600e0} - LSLib - + + - - \ No newline at end of file diff --git a/Divine/Properties/AssemblyInfo.cs b/Divine/Properties/AssemblyInfo.cs index 2f7fd57d..48400ce6 100644 --- a/Divine/Properties/AssemblyInfo.cs +++ b/Divine/Properties/AssemblyInfo.cs @@ -1,16 +1,6 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("LSLib - Divine Commandline Tool")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LSLib")] -[assembly: AssemblyCopyright("")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -21,16 +11,3 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("cbfee38f-5f12-4d6f-b4fb-267fb68a6bea")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.15.14.0")] -[assembly: AssemblyFileVersion("1.15.14.0")] diff --git a/Divine/packages.config b/Divine/packages.config deleted file mode 100644 index 60c919ae..00000000 --- a/Divine/packages.config +++ /dev/null @@ -1,5 +0,0 @@ - - - - - \ No newline at end of file diff --git a/LSLib/Granny/Collada.cs b/LSLib/Granny/Collada.cs index 9013b1c4..14e61362 100644 --- a/LSLib/Granny/Collada.cs +++ b/LSLib/Granny/Collada.cs @@ -41,15 +41,18 @@ public static source MakeFloatSource(string parentName, string name, string[] co parentName = string.Join("", hash.Select(c => ((int)c).ToString("X2"))); } - var positions = new float_array(); - positions.id = parentName + "-" + name + "-array"; - - var source = new source(); - source.id = parentName + "-" + name; - source.name = name; + var positions = new float_array + { + id = parentName + "-" + name + "-array", + count = (ulong)values.Length, + Values = values.Select(x => (double)x).ToArray() + }; - positions.count = (ulong)values.Length; - positions.Values = values.Select(x => (double)x).ToArray(); + var source = new source + { + id = parentName + "-" + name, + name = name + }; var technique = MakeAccessor(type, components, stride, values.Length / components.Length, positions.id); source.technique_common = technique; @@ -59,18 +62,21 @@ public static source MakeFloatSource(string parentName, string name, string[] co public static source MakeNameSource(string parentName, string name, string[] components, string[] values, string type = "name") { - var names = new Name_array(); - names.id = parentName + "-" + name + "-array"; - - var source = new source(); - source.id = parentName + "-" + name; - source.name = name; - - names.count = (ulong)values.Length; var varNames = from v in values select v.Replace(' ', '_'); - names.Values = varNames.ToArray(); + var names = new Name_array + { + id = parentName + "-" + name + "-array", + count = (ulong)values.Length, + Values = varNames.ToArray() + }; + + var source = new source + { + id = parentName + "-" + name, + name = name + }; var technique = MakeAccessor(type, components, 1, values.Length / components.Length, names.id); source.technique_common = technique; diff --git a/LSLib/Granny/ColladaAnimation.cs b/LSLib/Granny/ColladaAnimation.cs index 09fd98dd..12705cbb 100644 --- a/LSLib/Granny/ColladaAnimation.cs +++ b/LSLib/Granny/ColladaAnimation.cs @@ -3,8 +3,7 @@ using System.Linq; using LSLib.Granny.GR2; using LSLib.Granny.Model; -using LSLib.Granny.Model.CurveData; -using OpenTK; +using OpenTK.Mathematics; namespace LSLib.Granny { @@ -23,7 +22,7 @@ public Single Duration private void ImportSources() { - Sources = new Dictionary(); + Sources = []; foreach (var item in Animation.Items) { if (item is source) @@ -55,8 +54,7 @@ private void ImportSampler() if (input.source[0] != '#') throw new ParsingException("Only ID references are supported for animation input sources"); - ColladaSource source; - if (!Sources.TryGetValue(input.source.Substring(1), out source)) + if (!Sources.TryGetValue(input.source.Substring(1), out ColladaSource source)) throw new ParsingException("Animation sampler " + input.semantic + " references nonexistent source: " + input.source); switch (input.semantic) @@ -119,14 +117,13 @@ private void ImportChannel(Skeleton skeleton) if (channel == null) throw new ParsingException("Animation " + Animation.id + " has no channel!"); - var parts = channel.target.Split(new char[] { '/' }); + var parts = channel.target.Split(['/']); if (parts.Length != 2) throw new ParsingException("Unsupported channel target format: " + channel.target); if (skeleton != null) { - Bone bone = null; - if (!skeleton.BonesByID.TryGetValue(parts[0], out bone)) + if (!skeleton.BonesByID.TryGetValue(parts[0], out Bone bone)) throw new ParsingException("Animation channel references nonexistent bone: " + parts[0]); if (bone.TransformSID != parts[1]) diff --git a/LSLib/Granny/ColladaSchema.cs b/LSLib/Granny/ColladaSchema.cs index c90142e8..84570078 100644 --- a/LSLib/Granny/ColladaSchema.cs +++ b/LSLib/Granny/ColladaSchema.cs @@ -25,6 +25,8 @@ using System.Xml; using System.Xml.Serialization; +#pragma warning disable 8981 + namespace LSLib.Granny { // @@ -9974,4 +9976,6 @@ public void Save(Stream stream) xSerializer.Serialize(writer, this); } } -} \ No newline at end of file +} + +#pragma warning restore 8981 diff --git a/LSLib/Granny/GR2/Format.cs b/LSLib/Granny/GR2/Format.cs index 80bc7903..edfcb208 100644 --- a/LSLib/Granny/GR2/Format.cs +++ b/LSLib/Granny/GR2/Format.cs @@ -3,7 +3,7 @@ using System.Diagnostics; using System.Linq; using System.Text; -using OpenTK; +using OpenTK.Mathematics; using System.IO; using System.Reflection; @@ -183,29 +183,7 @@ public Matrix4 ToMatrix4() public override string ToString() { - var sb = new StringBuilder(); - sb.Append("Rotation: ("); - sb.Append(Rotation.X); - sb.Append(", "); - sb.Append(Rotation.Y); - sb.Append(", "); - sb.Append(Rotation.Z); - sb.Append(", "); - sb.Append(Rotation.W); - sb.Append("); Translation: ("); - sb.Append(Translation.X); - sb.Append(", "); - sb.Append(Translation.Y); - sb.Append(", "); - sb.Append(Translation.Z); - sb.Append("); Scale: ("); - sb.Append(ScaleShear[0, 0]); - sb.Append(", "); - sb.Append(ScaleShear[1, 1]); - sb.Append(", "); - sb.Append(ScaleShear[2, 2]); - sb.Append(")"); - return sb.ToString(); + return $"Rotation: ({Rotation.X}, {Rotation.Y}, {Rotation.Z}); Translation: ({Translation.X}, {Translation.Y}, {Translation.Z}); Scale: ({ScaleShear[0, 0]}, {ScaleShear[1, 1]}, {ScaleShear[2, 2]})"; } } @@ -217,47 +195,47 @@ public class Magic /// /// Magic value used for version 7 little-endian 32-bit Granny files /// - private static byte[] LittleEndian32Magic = new byte[] { 0x29, 0xDE, 0x6C, 0xC0, 0xBA, 0xA4, 0x53, 0x2B, 0x25, 0xF5, 0xB7, 0xA5, 0xF6, 0x66, 0xE2, 0xEE }; + private static readonly byte[] LittleEndian32Magic = [0x29, 0xDE, 0x6C, 0xC0, 0xBA, 0xA4, 0x53, 0x2B, 0x25, 0xF5, 0xB7, 0xA5, 0xF6, 0x66, 0xE2, 0xEE]; /// /// Magic value used for version 7 little-endian 32-bit Granny files /// - private static byte[] LittleEndian32Magic2 = new byte[] { 0x29, 0x75, 0x31, 0x82, 0xBA, 0x02, 0x11, 0x77, 0x25, 0x3A, 0x60, 0x2F, 0xF6, 0x6A, 0x8C, 0x2E }; + private static readonly byte[] LittleEndian32Magic2 = [0x29, 0x75, 0x31, 0x82, 0xBA, 0x02, 0x11, 0x77, 0x25, 0x3A, 0x60, 0x2F, 0xF6, 0x6A, 0x8C, 0x2E]; /// /// Magic value used for version 6 little-endian 32-bit Granny files /// - private static byte[] LittleEndian32MagicV6 = new byte[] { 0xB8, 0x67, 0xB0, 0xCA, 0xF8, 0x6D, 0xB1, 0x0F, 0x84, 0x72, 0x8C, 0x7E, 0x5E, 0x19, 0x00, 0x1E }; + private static readonly byte[] LittleEndian32MagicV6 = [0xB8, 0x67, 0xB0, 0xCA, 0xF8, 0x6D, 0xB1, 0x0F, 0x84, 0x72, 0x8C, 0x7E, 0x5E, 0x19, 0x00, 0x1E]; /// /// Magic value used for version 7 big-endian 32-bit Granny files /// - private static byte[] BigEndian32Magic = new byte[] { 0x0E, 0x11, 0x95, 0xB5, 0x6A, 0xA5, 0xB5, 0x4B, 0xEB, 0x28, 0x28, 0x50, 0x25, 0x78, 0xB3, 0x04 }; + private static readonly byte[] BigEndian32Magic = [0x0E, 0x11, 0x95, 0xB5, 0x6A, 0xA5, 0xB5, 0x4B, 0xEB, 0x28, 0x28, 0x50, 0x25, 0x78, 0xB3, 0x04]; /// /// Magic value used for version 7 big-endian 32-bit Granny files /// - private static byte[] BigEndian32Magic2 = new byte[] { 0x0E, 0x74, 0xA2, 0x0A, 0x6A, 0xEB, 0xEB, 0x64, 0xEB, 0x4E, 0x1E, 0xAB, 0x25, 0x91, 0xDB, 0x8F }; + private static readonly byte[] BigEndian32Magic2 = [0x0E, 0x74, 0xA2, 0x0A, 0x6A, 0xEB, 0xEB, 0x64, 0xEB, 0x4E, 0x1E, 0xAB, 0x25, 0x91, 0xDB, 0x8F]; /// /// Magic value used for version 7 little-endian 64-bit Granny files /// - private static byte[] LittleEndian64Magic = new byte[] { 0xE5, 0x9B, 0x49, 0x5E, 0x6F, 0x63, 0x1F, 0x14, 0x1E, 0x13, 0xEB, 0xA9, 0x90, 0xBE, 0xED, 0xC4 }; + private static readonly byte[] LittleEndian64Magic = [0xE5, 0x9B, 0x49, 0x5E, 0x6F, 0x63, 0x1F, 0x14, 0x1E, 0x13, 0xEB, 0xA9, 0x90, 0xBE, 0xED, 0xC4]; /// /// Magic value used for version 7 little-endian 64-bit Granny files /// - private static byte[] LittleEndian64Magic2 = new byte[] { 0xE5, 0x2F, 0x4A, 0xE1, 0x6F, 0xC2, 0x8A, 0xEE, 0x1E, 0xD2, 0xB4, 0x4C, 0x90, 0xD7, 0x55, 0xAF }; + private static readonly byte[] LittleEndian64Magic2 = [0xE5, 0x2F, 0x4A, 0xE1, 0x6F, 0xC2, 0x8A, 0xEE, 0x1E, 0xD2, 0xB4, 0x4C, 0x90, 0xD7, 0x55, 0xAF]; /// /// Magic value used for version 7 big-endian 64-bit Granny files /// - private static byte[] BigEndian64Magic = new byte[] { 0x31, 0x95, 0xD4, 0xE3, 0x20, 0xDC, 0x4F, 0x62, 0xCC, 0x36, 0xD0, 0x3A, 0xB1, 0x82, 0xFF, 0x89 }; + private static readonly byte[] BigEndian64Magic = [0x31, 0x95, 0xD4, 0xE3, 0x20, 0xDC, 0x4F, 0x62, 0xCC, 0x36, 0xD0, 0x3A, 0xB1, 0x82, 0xFF, 0x89]; /// /// Magic value used for version 7 big-endian 64-bit Granny files /// - private static byte[] BigEndian64Magic2 = new byte[] { 0x31, 0xC2, 0x4E, 0x7C, 0x20, 0x40, 0xA3, 0x25, 0xCC, 0xE1, 0xC2, 0x7A, 0xB1, 0x32, 0x49, 0xF3 }; + private static readonly byte[] BigEndian64Magic2 = [0x31, 0xC2, 0x4E, 0x7C, 0x20, 0x40, 0xA3, 0x25, 0xCC, 0xE1, 0xC2, 0x7A, 0xB1, 0x32, 0x49, 0xF3]; /// /// Size of magic value structure, in bytes @@ -344,23 +322,14 @@ public static Format FormatFromSignature(byte[] sig) public static byte[] SignatureFromFormat(Format format) { - switch (format) + return format switch { - case Format.LittleEndian32: - return LittleEndian32Magic; - - case Format.LittleEndian64: - return LittleEndian64Magic; - - case Format.BigEndian32: - return BigEndian32Magic; - - case Format.BigEndian64: - return BigEndian64Magic; - - default: - throw new ArgumentException(); - } + Format.LittleEndian32 => LittleEndian32Magic, + Format.LittleEndian64 => LittleEndian64Magic, + Format.BigEndian32 => BigEndian32Magic, + Format.BigEndian64 => BigEndian64Magic, + _ => throw new ArgumentException(), + }; } public void SetFormat(Format format, bool alternateSignature) @@ -369,45 +338,23 @@ public void SetFormat(Format format, bool alternateSignature) if (alternateSignature) { - switch (format) + this.signature = format switch { - case Format.LittleEndian32: - this.signature = LittleEndian32Magic2; - break; - - case Format.LittleEndian64: - this.signature = LittleEndian64Magic2; - break; - - case Format.BigEndian32: - this.signature = BigEndian32Magic2; - break; - - case Format.BigEndian64: - this.signature = BigEndian64Magic2; - break; - } + Format.LittleEndian32 => LittleEndian32Magic2, + Format.LittleEndian64 => LittleEndian64Magic2, + Format.BigEndian32 => BigEndian32Magic2, + Format.BigEndian64 => BigEndian64Magic2 + }; } else { - switch (format) + this.signature = format switch { - case Format.LittleEndian32: - this.signature = LittleEndian32Magic; - break; - - case Format.LittleEndian64: - this.signature = LittleEndian64Magic; - break; - - case Format.BigEndian32: - this.signature = BigEndian32Magic; - break; - - case Format.BigEndian64: - this.signature = BigEndian64Magic; - break; - } + Format.LittleEndian32 => LittleEndian32Magic, + Format.LittleEndian64 => LittleEndian64Magic, + Format.BigEndian32 => BigEndian32Magic, + Format.BigEndian64 => BigEndian64Magic + }; } } } @@ -494,14 +441,12 @@ public class Header public UInt32 Size() { - UInt32 headerSize; - switch (version) + var headerSize = version switch { - case 6: headerSize = HeaderSize_V6; break; - case 7: headerSize = HeaderSize_V7; break; - default: throw new InvalidDataException("Cannot calculate CRC for unknown header versions."); - } - + 6 => HeaderSize_V6, + 7 => HeaderSize_V7, + _ => throw new InvalidDataException("Cannot calculate CRC for unknown header versions."), + }; return headerSize; } @@ -642,8 +587,7 @@ public override bool Equals(object o) if (o == null) return false; - var reference = o as SectionReference; - return reference != null && reference.Section == Section && reference.Offset == Offset; + return o is SectionReference reference && reference.Section == Section && reference.Offset == Offset; } public bool Equals(SectionReference reference) @@ -680,8 +624,7 @@ public override bool Equals(object o) if (o == null) return false; - var reference = o as RelocatableReference; - return reference != null && reference.Offset == Offset; + return o is RelocatableReference reference && reference.Offset == Offset; } public bool Equals(RelocatableReference reference) @@ -792,7 +735,7 @@ public List Resolve(GR2Reader gr2) #endif var originalPos = gr2.Stream.Position; gr2.Seek(this); - Items = new List(); + Items = []; for (int i = 0; i < Size; i++) { Items.Add(gr2.ReadReference()); @@ -863,61 +806,37 @@ public bool IsScalar public UInt32 Size(GR2Reader gr2) { - switch (Type) + return Type switch { - case MemberType.Inline: - return Definition.Resolve(gr2).Size(gr2); + MemberType.Inline => Definition.Resolve(gr2).Size(gr2), - case MemberType.Int8: - case MemberType.BinormalInt8: - case MemberType.UInt8: - case MemberType.NormalUInt8: - return 1; + MemberType.Int8 => 1, + MemberType.BinormalInt8 => 1, + MemberType.UInt8 => 1, + MemberType.NormalUInt8 => 1, - case MemberType.Int16: - case MemberType.BinormalInt16: - case MemberType.UInt16: - case MemberType.NormalUInt16: - case MemberType.Real16: - return 2; + MemberType.Int16 => 2, + MemberType.BinormalInt16 => 2, + MemberType.UInt16 => 2, + MemberType.NormalUInt16 => 2, + MemberType.Real16 => 2, - case MemberType.Reference: - if (gr2.Magic.Is32Bit) - return 4; - else - return 8; + MemberType.Reference => gr2.Magic.Is32Bit ? 4u : 8, - case MemberType.String: - case MemberType.Real32: - case MemberType.Int32: - case MemberType.UInt32: - return 4; - - case MemberType.VariantReference: - if (gr2.Magic.Is32Bit) - return 8; - else - return 16; + MemberType.String => 4, + MemberType.Real32 => 4, + MemberType.Int32 => 4, + MemberType.UInt32 => 4, - case MemberType.ArrayOfReferences: - case MemberType.ReferenceToArray: - if (gr2.Magic.Is32Bit) - return 8; - else - return 12; + MemberType.VariantReference => gr2.Magic.Is32Bit ? 8u : 16, + MemberType.ArrayOfReferences => gr2.Magic.Is32Bit ? 8u : 12, + MemberType.ReferenceToArray => gr2.Magic.Is32Bit ? 8u : 12, + MemberType.ReferenceToVariantArray => gr2.Magic.Is32Bit ? 12u : 20, - case MemberType.ReferenceToVariantArray: - if (gr2.Magic.Is32Bit) - return 12; - else - return 20; + MemberType.Transform => 17 * 4, - case MemberType.Transform: - return 17 * 4; - - default: - throw new ParsingException(String.Format("Unhandled member type: {0}", Type.ToString())); - } + _ => throw new ParsingException($"Unhandled member type: {Type}") + }; } public UInt32 MarshallingSize() @@ -1028,7 +947,7 @@ public static MemberDefinition CreateFromFieldInfo(FieldInfo info, GR2Writer wri var type = info.FieldType; member.Name = info.Name; member.GrannyName = info.Name; - member.Extra = new UInt32[] { 0, 0, 0 }; + member.Extra = [0, 0, 0]; member.CachedField = info; member.HasCachedField = true; @@ -1055,7 +974,7 @@ public static MemberDefinition CreateFromFieldInfo(FieldInfo info, GR2Writer wri member.Type = MemberType.Int32; else if (type == typeof(UInt32)) member.Type = MemberType.UInt32; - else if (type == typeof(Half)) + else if (type == typeof(OpenTK.Mathematics.Half)) member.Type = MemberType.Real16; else if (type == typeof(Single)) member.Type = MemberType.Real32; diff --git a/LSLib/Granny/GR2/Helpers.cs b/LSLib/Granny/GR2/Helpers.cs index 62f32907..f6999b00 100644 --- a/LSLib/Granny/GR2/Helpers.cs +++ b/LSLib/Granny/GR2/Helpers.cs @@ -6,8 +6,8 @@ namespace LSLib.Granny.GR2 { public static class Helpers { - private static Dictionary CachedConstructors = new Dictionary(); - private static Dictionary CachedArrayConstructors = new Dictionary(); + private static readonly Dictionary CachedConstructors = []; + private static readonly Dictionary CachedArrayConstructors = []; public delegate object ObjectCtor(); public delegate object ArrayCtor(int size); @@ -34,8 +34,7 @@ public static object CreateInstance(Type type) public static object CreateArrayInstance(Type type, int size) { - ArrayCtor ctor; - if (!CachedArrayConstructors.TryGetValue(type, out ctor)) + if (!CachedArrayConstructors.TryGetValue(type, out ArrayCtor ctor)) { var typeCtor = type.GetConstructor(new Type[] { typeof(int) }); var sizeParam = Expression.Parameter(typeof(int), ""); diff --git a/LSLib/Granny/GR2/Reader.cs b/LSLib/Granny/GR2/Reader.cs index 35784ee0..a1b8076d 100644 --- a/LSLib/Granny/GR2/Reader.cs +++ b/LSLib/Granny/GR2/Reader.cs @@ -11,26 +11,23 @@ namespace LSLib.Granny.GR2 { - public class ParsingException : Exception + public class ParsingException(string message) : Exception(message) { - public ParsingException(string message) - : base(message) - { } } - public class GR2Reader + public class GR2Reader(Stream stream) { - internal Stream InputStream; + internal Stream InputStream = stream; internal BinaryReader InputReader; internal Stream Stream; internal BinaryReader Reader; internal Magic Magic; internal Header Header; - internal List
Sections = new List
(); - internal Dictionary Types = new Dictionary(); - private Dictionary CachedStructs = new Dictionary(); + internal List
Sections = []; + internal Dictionary Types = []; + private readonly Dictionary CachedStructs = []; #if DEBUG_GR2_SERIALIZATION - private HashSet DebugPendingResolve = new HashSet(); + private HashSet DebugPendingResolve = []; #endif public UInt32 Tag @@ -38,15 +35,9 @@ public UInt32 Tag get { return Header.tag; } } - public GR2Reader(Stream stream) - { - this.InputStream = stream; - } - public void Dispose() { - if (Stream != null) - Stream.Dispose(); + Stream?.Dispose(); } public void Read(object root) @@ -61,8 +52,10 @@ public void Read(object root) Header = ReadHeader(); for (int i = 0; i < Header.numSections; i++) { - var section = new Section(); - section.Header = ReadSectionHeader(); + var section = new Section + { + Header = ReadSectionHeader() + }; Sections.Add(section); } @@ -84,8 +77,10 @@ public void Read(object root) } } - var rootStruct = new StructReference(); - rootStruct.Offset = Sections[(int)Header.rootType.Section].Header.offsetInFile + Header.rootType.Offset; + var rootStruct = new StructReference + { + Offset = Sections[(int)Header.rootType.Section].Header.offsetInFile + Header.rootType.Offset + }; Seek(Header.rootNode); ReadStruct(rootStruct.Resolve(this), MemberType.Inline, root, null); @@ -94,15 +89,16 @@ public void Read(object root) private Magic ReadMagic() { - var magic = new Magic(); - magic.signature = InputReader.ReadBytes(16); + var magic = new Magic + { + signature = InputReader.ReadBytes(16), + headersSize = InputReader.ReadUInt32(), + headerFormat = InputReader.ReadUInt32(), + reserved1 = InputReader.ReadUInt32(), + reserved2 = InputReader.ReadUInt32() + }; magic.format = Magic.FormatFromSignature(magic.signature); - magic.headersSize = InputReader.ReadUInt32(); - magic.headerFormat = InputReader.ReadUInt32(); - magic.reserved1 = InputReader.ReadUInt32(); - magic.reserved2 = InputReader.ReadUInt32(); - if (magic.headerFormat != 0) throw new ParsingException("Compressed GR2 files are not supported"); @@ -120,16 +116,18 @@ private Magic ReadMagic() private Header ReadHeader() { - var header = new Header(); - header.version = InputReader.ReadUInt32(); - header.fileSize = InputReader.ReadUInt32(); - header.crc = InputReader.ReadUInt32(); - header.sectionsOffset = InputReader.ReadUInt32(); - header.numSections = InputReader.ReadUInt32(); - header.rootType = ReadSectionReferenceUnchecked(); - header.rootNode = ReadSectionReferenceUnchecked(); - header.tag = InputReader.ReadUInt32(); - header.extraTags = new UInt32[Header.ExtraTagCount]; + var header = new Header + { + version = InputReader.ReadUInt32(), + fileSize = InputReader.ReadUInt32(), + crc = InputReader.ReadUInt32(), + sectionsOffset = InputReader.ReadUInt32(), + numSections = InputReader.ReadUInt32(), + rootType = ReadSectionReferenceUnchecked(), + rootNode = ReadSectionReferenceUnchecked(), + tag = InputReader.ReadUInt32(), + extraTags = new UInt32[Header.ExtraTagCount] + }; for (int i = 0; i < Header.ExtraTagCount; i++) header.extraTags[i] = InputReader.ReadUInt32(); @@ -173,18 +171,20 @@ private Header ReadHeader() private SectionHeader ReadSectionHeader() { - var header = new SectionHeader(); - header.compression = InputReader.ReadUInt32(); - header.offsetInFile = InputReader.ReadUInt32(); - header.compressedSize = InputReader.ReadUInt32(); - header.uncompressedSize = InputReader.ReadUInt32(); - header.alignment = InputReader.ReadUInt32(); - header.first16bit = InputReader.ReadUInt32(); - header.first8bit = InputReader.ReadUInt32(); - header.relocationsOffset = InputReader.ReadUInt32(); - header.numRelocations = InputReader.ReadUInt32(); - header.mixedMarshallingDataOffset = InputReader.ReadUInt32(); - header.numMixedMarshallingData = InputReader.ReadUInt32(); + var header = new SectionHeader + { + compression = InputReader.ReadUInt32(), + offsetInFile = InputReader.ReadUInt32(), + compressedSize = InputReader.ReadUInt32(), + uncompressedSize = InputReader.ReadUInt32(), + alignment = InputReader.ReadUInt32(), + first16bit = InputReader.ReadUInt32(), + first8bit = InputReader.ReadUInt32(), + relocationsOffset = InputReader.ReadUInt32(), + numRelocations = InputReader.ReadUInt32(), + mixedMarshallingDataOffset = InputReader.ReadUInt32(), + numMixedMarshallingData = InputReader.ReadUInt32() + }; Debug.Assert(header.offsetInFile <= Header.fileSize); @@ -271,25 +271,23 @@ private void ReadSectionRelocationsInternal(Section section, Stream relocationsS System.Console.WriteLine(String.Format(" ===== Relocations for section at {0:X8} ===== ", section.Header.offsetInFile)); #endif - using (var relocationsReader = new BinaryReader(relocationsStream, Encoding.Default, true)) + using var relocationsReader = new BinaryReader(relocationsStream, Encoding.Default, true); + for (int i = 0; i < section.Header.numRelocations; i++) { - for (int i = 0; i < section.Header.numRelocations; i++) - { - UInt32 offsetInSection = relocationsReader.ReadUInt32(); - Debug.Assert(offsetInSection <= section.Header.uncompressedSize); - var reference = ReadSectionReference(relocationsReader); + UInt32 offsetInSection = relocationsReader.ReadUInt32(); + Debug.Assert(offsetInSection <= section.Header.uncompressedSize); + var reference = ReadSectionReference(relocationsReader); - Stream.Position = section.Header.offsetInFile + offsetInSection; - var fixupAddress = Sections[(int)reference.Section].Header.offsetInFile + reference.Offset; - Stream.Write(BitConverter.GetBytes(fixupAddress), 0, 4); + Stream.Position = section.Header.offsetInFile + offsetInSection; + var fixupAddress = Sections[(int)reference.Section].Header.offsetInFile + reference.Offset; + Stream.Write(BitConverter.GetBytes(fixupAddress), 0, 4); #if DEBUG_GR2_SERIALIZATION - System.Console.WriteLine(String.Format(" LOCAL {0:X8} --> {1}:{2:X8}", offsetInSection, (SectionType)reference.Section, reference.Offset)); - System.Console.WriteLine(String.Format(" GLOBAL {0:X8} --> {1:X8}", - offsetInSection + section.Header.offsetInFile, - reference.Offset + Sections[(int)reference.Section].Header.offsetInFile)); + System.Console.WriteLine(String.Format(" LOCAL {0:X8} --> {1}:{2:X8}", offsetInSection, (SectionType)reference.Section, reference.Offset)); + System.Console.WriteLine(String.Format(" GLOBAL {0:X8} --> {1:X8}", + offsetInSection + section.Header.offsetInFile, + reference.Offset + Sections[(int)reference.Section].Header.offsetInFile)); #endif - } } } @@ -300,17 +298,13 @@ private void ReadSectionRelocations(Section section) InputStream.Seek(section.Header.relocationsOffset, SeekOrigin.Begin); if (section.Header.compression == 4) { - using (var reader = new BinaryReader(InputStream, Encoding.Default, true)) - { - UInt32 compressedSize = reader.ReadUInt32(); - byte[] compressed = reader.ReadBytes((int)compressedSize); - var uncompressed = Granny2Compressor.Decompress4( - compressed, (int)(section.Header.numRelocations * 12)); - using (var ms = new MemoryStream(uncompressed)) - { - ReadSectionRelocationsInternal(section, ms); - } - } + using var reader = new BinaryReader(InputStream, Encoding.Default, true); + UInt32 compressedSize = reader.ReadUInt32(); + byte[] compressed = reader.ReadBytes((int)compressedSize); + var uncompressed = Granny2Compressor.Decompress4( + compressed, (int)(section.Header.numRelocations * 12)); + using var ms = new MemoryStream(uncompressed); + ReadSectionRelocationsInternal(section, ms); } else { @@ -361,24 +355,24 @@ private void ReadSectionMixedMarshallingRelocationsInternal(Section section, Str System.Console.WriteLine(String.Format(" ===== Mixed marshalling relocations for section at {0:X8} ===== ", section.Header.offsetInFile)); #endif - using (var relocationsReader = new BinaryReader(relocationsStream, Encoding.Default, true)) + using var relocationsReader = new BinaryReader(relocationsStream, Encoding.Default, true); + for (int i = 0; i < section.Header.numMixedMarshallingData; i++) { - for (int i = 0; i < section.Header.numMixedMarshallingData; i++) + UInt32 count = relocationsReader.ReadUInt32(); + UInt32 offsetInSection = relocationsReader.ReadUInt32(); + Debug.Assert(offsetInSection <= section.Header.uncompressedSize); + var type = ReadSectionReference(relocationsReader); + var typeDefn = new StructReference { - UInt32 count = relocationsReader.ReadUInt32(); - UInt32 offsetInSection = relocationsReader.ReadUInt32(); - Debug.Assert(offsetInSection <= section.Header.uncompressedSize); - var type = ReadSectionReference(relocationsReader); - var typeDefn = new StructReference(); - typeDefn.Offset = Sections[(int)type.Section].Header.offsetInFile + type.Offset; + Offset = Sections[(int)type.Section].Header.offsetInFile + type.Offset + }; - Seek(section, offsetInSection); - MixedMarshal(count, typeDefn.Resolve(this)); + Seek(section, offsetInSection); + MixedMarshal(count, typeDefn.Resolve(this)); #if DEBUG_GR2_SERIALIZATION - System.Console.WriteLine(String.Format(" {0:X8} [{1}] --> {2}:{3:X8}", offsetInSection, count, (SectionType)type.Section, type.Offset)); + System.Console.WriteLine(String.Format(" {0:X8} [{1}] --> {2}:{3:X8}", offsetInSection, count, (SectionType)type.Section, type.Offset)); #endif - } } } @@ -389,17 +383,13 @@ private void ReadSectionMixedMarshallingRelocations(Section section) InputStream.Seek(section.Header.mixedMarshallingDataOffset, SeekOrigin.Begin); if (section.Header.compression == 4) { - using (var reader = new BinaryReader(InputStream, Encoding.Default, true)) - { - UInt32 compressedSize = reader.ReadUInt32(); - byte[] compressed = reader.ReadBytes((int)compressedSize); - var uncompressed = Granny2Compressor.Decompress4( - compressed, (int)(section.Header.numMixedMarshallingData * 16)); - using (var ms = new MemoryStream(uncompressed)) - { - ReadSectionMixedMarshallingRelocationsInternal(section, ms); - } - } + using var reader = new BinaryReader(InputStream, Encoding.Default, true); + UInt32 compressedSize = reader.ReadUInt32(); + byte[] compressed = reader.ReadBytes((int)compressedSize); + var uncompressed = Granny2Compressor.Decompress4( + compressed, (int)(section.Header.numMixedMarshallingData * 16)); + using var ms = new MemoryStream(uncompressed); + ReadSectionMixedMarshallingRelocationsInternal(section, ms); } else { @@ -409,10 +399,11 @@ private void ReadSectionMixedMarshallingRelocations(Section section) public SectionReference ReadSectionReferenceUnchecked(BinaryReader reader) { - var reference = new SectionReference(); - reference.Section = reader.ReadUInt32(); - reference.Offset = reader.ReadUInt32(); - return reference; + return new SectionReference + { + Section = reader.ReadUInt32(), + Offset = reader.ReadUInt32() + }; } public SectionReference ReadSectionReferenceUnchecked() @@ -465,8 +456,10 @@ public StringReference ReadStringReference() public ArrayReference ReadArrayReference() { - var reference = new ArrayReference(); - reference.Size = Reader.ReadUInt32(); + var reference = new ArrayReference + { + Size = Reader.ReadUInt32() + }; if (Magic.Is32Bit) reference.Offset = Reader.ReadUInt32(); else @@ -476,8 +469,10 @@ public ArrayReference ReadArrayReference() public ArrayIndicesReference ReadArrayIndicesReference() { - var reference = new ArrayIndicesReference(); - reference.Size = Reader.ReadUInt32(); + var reference = new ArrayIndicesReference + { + Size = Reader.ReadUInt32() + }; if (Magic.Is32Bit) reference.Offset = Reader.ReadUInt32(); else @@ -506,7 +501,7 @@ public MemberDefinition ReadMemberDefinition() // Remove "The Divinity Engine" prefix from LSM fields if (defn.Name.StartsWith("The Divinity Engine", StringComparison.Ordinal)) { - defn.Name = defn.Name.Substring(19); + defn.Name = defn.Name[19..]; } defn.GrannyName = defn.Name; @@ -728,11 +723,9 @@ internal object ReadInstance(MemberDefinition definition, object node, Type prop else { // For non-native arrays we always assume the property is an IList - if (node == null) - node = Helpers.CreateInstance(propertyType); + node ??= Helpers.CreateInstance(propertyType); var items = node as System.Collections.IList; - var type = items.GetType().GetGenericArguments().Single(); for (int i = 0; i < definition.ArraySize; i++) { items.Add(ReadElement(definition, null, elementType, parent)); diff --git a/LSLib/Granny/GR2/Writer.cs b/LSLib/Granny/GR2/Writer.cs index 4dd1d039..2a5374af 100644 --- a/LSLib/Granny/GR2/Writer.cs +++ b/LSLib/Granny/GR2/Writer.cs @@ -27,11 +27,11 @@ public class WritableSection : Section public BinaryWriter Writer; public GR2Writer GR2; - public Dictionary Fixups = new Dictionary(); + public Dictionary Fixups = []; // Fixups for the data area that we'll need to update after serialization is finished - public Dictionary DataFixups = new Dictionary(); + public Dictionary DataFixups = []; - public List MixedMarshalling = new List(); + public List MixedMarshalling = []; public WritableSection(SectionType type, GR2Writer writer) { @@ -61,20 +61,20 @@ public void Finish() private SectionHeader InitHeader() { - var header = new SectionHeader(); - header.compression = 0; - header.offsetInFile = 0; // Set after serialization is finished - header.compressedSize = 0; // Set after serialization is finished - header.uncompressedSize = 0; // Set after serialization is finished - header.alignment = 4; - header.first16bit = 0; // Set after serialization is finished - header.first8bit = 0; // Set after serialization is finished - header.relocationsOffset = 0; // Set after serialization is finished - header.numRelocations = 0; // Set after serialization is finished - header.mixedMarshallingDataOffset = 0; // Set after serialization is finished - header.numMixedMarshallingData = 0; // Set after serialization is finished - - return header; + return new SectionHeader + { + compression = 0, + offsetInFile = 0, // Set after serialization is finished + compressedSize = 0, // Set after serialization is finished + uncompressedSize = 0, // Set after serialization is finished + alignment = 4, + first16bit = 0, // Set after serialization is finished + first8bit = 0, // Set after serialization is finished + relocationsOffset = 0, // Set after serialization is finished + numRelocations = 0, // Set after serialization is finished + mixedMarshallingDataOffset = 0, // Set after serialization is finished + numMixedMarshallingData = 0 // Set after serialization is finished + }; } public void AddFixup(object o) @@ -91,10 +91,12 @@ public void AddFixup(object o) internal void AddMixedMarshalling(object o, UInt32 count, StructDefinition type) { - var marshal = new MixedMarshallingData(); - marshal.Obj = o; - marshal.Count = count; - marshal.Type = type; + var marshal = new MixedMarshallingData + { + Obj = o, + Count = count, + Type = type + }; MixedMarshalling.Add(marshal); } @@ -133,11 +135,7 @@ public void WriteStructReference(StructDefinition defn) if (defn != null) { AddFixup(defn); - - if (!GR2.Types.ContainsKey(defn.Type)) - { - GR2.Types.Add(defn.Type, defn); - } + GR2.Types.TryAdd(defn.Type, defn); } if (GR2.Magic.Is32Bit) @@ -216,9 +214,11 @@ public void WriteStructDefinition(StructDefinition defn) } } - var end = new MemberDefinition(); - end.Type = MemberType.None; - end.Extra = new UInt32[] { 0, 0, 0 }; + var end = new MemberDefinition + { + Type = MemberType.None, + Extra = [0, 0, 0] + }; WriteMemberDefinition(end); } @@ -369,35 +369,32 @@ internal void WriteInstance(MemberDefinition definition, Type propertyType, obje { if (definition.ArraySize == 0) { - WriteElement(definition, propertyType, node); + WriteElement(definition, node); return; } if (propertyType.IsArray) { // If the property is a native array (ie. SomeType[]), create an array instance and set its values - var elementType = propertyType.GetElementType(); - Array arr = node as Array; Debug.Assert(arr.Length == definition.ArraySize); for (int i = 0; i < definition.ArraySize; i++) { - WriteElement(definition, elementType, arr.GetValue(i)); + WriteElement(definition, arr.GetValue(i)); } } else { // For non-native arrays we always assume the property is an IList var items = node as System.Collections.IList; - var elementType = items.GetType().GetGenericArguments().Single(); foreach (var element in items) { - WriteElement(definition, elementType, element); + WriteElement(definition, element); } } } - private void WriteElement(MemberDefinition definition, Type propertyType, object node) + private void WriteElement(MemberDefinition definition, object node) { var type = definition.CachedField.FieldType; bool dataArea = definition.DataArea || (Writer == DataWriter); @@ -679,17 +676,17 @@ struct QueuedStringSerialization internal Magic Magic; internal Header Header; internal WritableSection CurrentSection; - internal List Sections = new List(); - internal Dictionary Types = new Dictionary(); + internal List Sections = []; + internal Dictionary Types = []; internal RelocationArea Relocations; - private List StructWrites = new List(); - private List ArrayWrites = new List(); - private List StringWrites = new List(); + private List StructWrites = []; + private List ArrayWrites = []; + private List StringWrites = []; - internal Dictionary ObjectOffsets = new Dictionary(); - internal Dictionary DataObjectOffsets = new Dictionary(); - internal HashSet Strings = new HashSet(); + internal Dictionary ObjectOffsets = []; + internal Dictionary DataObjectOffsets = []; + internal HashSet Strings = []; // Version tag that will be written to the GR2 file public UInt32 VersionTag = Header.DefaultTag; @@ -720,9 +717,9 @@ public void FlushPendingWrites() var arrayWrites = ArrayWrites; var structWrites = StructWrites; var stringWrites = StringWrites; - ArrayWrites = new List(); - StructWrites = new List(); - StringWrites = new List(); + ArrayWrites = []; + StructWrites = []; + StringWrites = []; foreach (var write in structWrites) { @@ -896,22 +893,26 @@ private void WriteMagic(Magic magic) private Header InitHeader(uint numCustomSections) { - var header = new Header(); - header.version = Header.Version; - header.fileSize = 0; // Set after serialization is finished - header.crc = 0; // Set after serialization is finished + var header = new Header + { + version = Header.Version, + fileSize = 0, // Set after serialization is finished + crc = 0, // Set after serialization is finished + rootType = new SectionReference(), // Updated after serialization is finished + rootNode = new SectionReference(), // Updated after serialization is finished + numSections = (UInt32)SectionType.FirstVertexData + numCustomSections, + tag = VersionTag, + extraTags = new UInt32[Header.ExtraTagCount], + stringTableCrc = 0, + reserved1 = 0, + reserved2 = 0, + reserved3 = 0 + }; + header.sectionsOffset = header.Size(); - header.rootType = new SectionReference(); // Updated after serialization is finished - header.rootNode = new SectionReference(); // Updated after serialization is finished - header.numSections = (UInt32)SectionType.FirstVertexData + numCustomSections; - header.tag = VersionTag; - header.extraTags = new UInt32[Header.ExtraTagCount]; + for (int i = 0; i < Header.ExtraTagCount; i++) header.extraTags[i] = 0; - header.stringTableCrc = 0; - header.reserved1 = 0; - header.reserved2 = 0; - header.reserved3 = 0; return header; } @@ -957,8 +958,7 @@ public void WriteSectionReference(SectionReference r) internal StructDefinition LookupStructDefinition(Type type, object instance) { - StructDefinition defn = null; - if (Types.TryGetValue(type, out defn)) + if (Types.TryGetValue(type, out StructDefinition defn)) { return defn; } diff --git a/LSLib/Granny/GR2Utils.cs b/LSLib/Granny/GR2Utils.cs index 41a2b793..a38d334a 100644 --- a/LSLib/Granny/GR2Utils.cs +++ b/LSLib/Granny/GR2Utils.cs @@ -5,9 +5,6 @@ using LSLib.Granny.GR2; using LSLib.Granny.Model; using LSLib.LS; -using Directory = Alphaleonis.Win32.Filesystem.Directory; -using Path = Alphaleonis.Win32.Filesystem.Path; -using File = Alphaleonis.Win32.Filesystem.File; namespace LSLib.Granny { @@ -24,18 +21,12 @@ public static ExportFormat ExtensionToModelFormat(string path) { string extension = Path.GetExtension(path)?.ToLower(); - switch (extension) + return extension switch { - case ".gr2": - case ".lsm": - return ExportFormat.GR2; - - case ".dae": - return ExportFormat.DAE; - - default: - throw new ArgumentException($"Unrecognized model file extension: {extension}"); - } + ".gr2" or ".lsm" => ExportFormat.GR2, + ".dae" => ExportFormat.DAE, + _ => throw new ArgumentException($"Unrecognized model file extension: {extension}"), + }; } public static Root LoadModel(string inputPath) @@ -53,14 +44,12 @@ public static Root LoadModel(string inputPath, ExporterOptions options) { case ExportFormat.GR2: { - using (var fs = File.Open(inputPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - { - var root = new Root(); - var gr2 = new GR2Reader(fs); - gr2.Read(root); - root.PostLoad(gr2.Tag); - return root; - } + using var fs = File.Open(inputPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + var root = new Root(); + var gr2 = new GR2Reader(fs); + gr2.Read(root); + root.PostLoad(gr2.Tag); + return root; } case ExportFormat.DAE: diff --git a/LSLib/Granny/Model/Animation.cs b/LSLib/Granny/Model/Animation.cs index e13827d0..b3eca439 100644 --- a/LSLib/Granny/Model/Animation.cs +++ b/LSLib/Granny/Model/Animation.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.Model.CurveData; using LSLib.Granny.GR2; @@ -47,11 +47,14 @@ public void UpgradeToGr7() if (this.Degree == 0) { // Degree 0 curves are identities in all cases - var curve = new DaIdentity(); - curve.CurveDataHeader_DaIdentity = new CurveDataHeader(); - curve.CurveDataHeader_DaIdentity.Format = (byte)CurveFormat.DaIdentity; - curve.CurveDataHeader_DaIdentity.Degree = 0; - this.CurveData = curve; + CurveData = new DaIdentity + { + CurveDataHeader_DaIdentity = new CurveDataHeader + { + Format = (byte)CurveFormat.DaIdentity, + Degree = 0 + } + }; } else if (this.Degree == 2) { @@ -61,13 +64,16 @@ public void UpgradeToGr7() } // Degree 2 curves are stored in K32fC32f (v6 didn't support multiple curve formats) - var curve = new DaK32fC32f(); - curve.CurveDataHeader_DaK32fC32f = new CurveDataHeader(); - curve.CurveDataHeader_DaK32fC32f.Format = (byte)CurveFormat.DaK32fC32f; - curve.CurveDataHeader_DaK32fC32f.Degree = 2; - curve.Controls = Controls; - curve.Knots = Knots; - this.CurveData = curve; + CurveData = new DaK32fC32f + { + CurveDataHeader_DaK32fC32f = new CurveDataHeader + { + Format = (byte)CurveFormat.DaK32fC32f, + Degree = 2 + }, + Controls = Controls, + Knots = Knots + }; } else { @@ -105,14 +111,13 @@ public void FromTransform(Transform transform) public class KeyframeTrack { - public SortedList Keyframes = new SortedList(); + public SortedList Keyframes = []; private static Int32 FindFrame(IList list, T value, IComparer comparer = null) { - if (list == null) - throw new ArgumentNullException("list"); + ArgumentNullException.ThrowIfNull(list); - comparer = comparer ?? Comparer.Default; + comparer ??= Comparer.Default; Int32 lower = 0; Int32 upper = list.Count - 1; @@ -372,7 +377,7 @@ public void RemoveTrivialRotations() } } - if (keyframesToRemove == transforms.Count - 2 && (transforms[0] - transforms[transforms.Count - 1]).Length < 0.0001f) + if (keyframesToRemove == transforms.Count - 2 && (transforms[0] - transforms[^1]).Length < 0.0001f) { for (int i = 1; i < times.Count; i++) { @@ -534,16 +539,20 @@ public class TransformTrack public static TransformTrack FromKeyframes(KeyframeTrack keyframes) { - var track = new TransformTrack(); - track.Flags = 0; - + var track = new TransformTrack + { + Flags = 0 + }; + var translateTimes = keyframes.Keyframes.Where(f => f.Value.HasTranslation).Select(f => f.Key).ToList(); var translations = keyframes.Keyframes.Where(f => f.Value.HasTranslation).Select(f => f.Value.Translation).ToList(); if (translateTimes.Count == 1) { - var posCurve = new D3Constant32f(); - posCurve.CurveDataHeader_D3Constant32f = new CurveDataHeader { Format = (int)CurveFormat.D3Constant32f, Degree = 2 }; - posCurve.Controls = new float[3] { translations[0].X, translations[0].Y, translations[0].Z }; + var posCurve = new D3Constant32f + { + CurveDataHeader_D3Constant32f = new CurveDataHeader { Format = (int)CurveFormat.D3Constant32f, Degree = 2 }, + Controls = new float[3] { translations[0].X, translations[0].Y, translations[0].Z } + }; track.PositionCurve = new AnimationCurve { CurveData = posCurve }; } else @@ -559,9 +568,11 @@ public static TransformTrack FromKeyframes(KeyframeTrack keyframes) var rotations = keyframes.Keyframes.Where(f => f.Value.HasRotation).Select(f => f.Value.Rotation).ToList(); if (rotationTimes.Count == 1) { - var rotCurve = new D4Constant32f(); - rotCurve.CurveDataHeader_D4Constant32f = new CurveDataHeader { Format = (int)CurveFormat.D4Constant32f, Degree = 2 }; - rotCurve.Controls = new float[4] { rotations[0].X, rotations[0].Y, rotations[0].Z, rotations[0].W }; + var rotCurve = new D4Constant32f + { + CurveDataHeader_D4Constant32f = new CurveDataHeader { Format = (int)CurveFormat.D4Constant32f, Degree = 2 }, + Controls = new float[4] { rotations[0].X, rotations[0].Y, rotations[0].Z, rotations[0].W } + }; track.OrientationCurve = new AnimationCurve { CurveData = rotCurve }; } else @@ -580,12 +591,12 @@ public static TransformTrack FromKeyframes(KeyframeTrack keyframes) var scaleCurve = new DaConstant32f(); scaleCurve.CurveDataHeader_DaConstant32f = new CurveDataHeader { Format = (int)CurveFormat.DaConstant32f, Degree = 2 }; var m = scales[0]; - scaleCurve.Controls = new List - { + scaleCurve.Controls = + [ m[0, 0], m[0, 1], m[0, 2], m[1, 0], m[1, 1], m[1, 2], m[2, 0], m[2, 1], m[2, 2] - }; + ]; track.ScaleShearCurve = new AnimationCurve { CurveData = scaleCurve }; } else diff --git a/LSLib/Granny/Model/ColladaExporter.cs b/LSLib/Granny/Model/ColladaExporter.cs index 2231ff20..21a98420 100644 --- a/LSLib/Granny/Model/ColladaExporter.cs +++ b/LSLib/Granny/Model/ColladaExporter.cs @@ -3,29 +3,22 @@ using System.Linq; using LSLib.Granny.GR2; using LSLib.LS; -using Alphaleonis.Win32.Filesystem; using System.Xml; using System.Xml.Linq; using LSLib.LS.Enums; +using System.IO; namespace LSLib.Granny.Model { - public class ColladaMeshExporter + public class ColladaMeshExporter(Mesh mesh, ExporterOptions options) { - private Mesh ExportedMesh; - private ExporterOptions Options; + private Mesh ExportedMesh = mesh; + private ExporterOptions Options = options; private List Sources; private List Inputs; private List InputOffsets; private ulong LastInputOffset = 0; - private XmlDocument Xml = new XmlDocument(); - - - public ColladaMeshExporter(Mesh mesh, ExporterOptions options) - { - ExportedMesh = mesh; - Options = options; - } + private XmlDocument Xml = new(); private void AddInput(source collSource, string inputSemantic, string localInputSemantic = null, ulong setIndex = 0) { @@ -36,18 +29,22 @@ private void AddInput(source collSource, string inputSemantic, string localInput if (inputSemantic != null) { - var input = new InputLocal(); - input.semantic = inputSemantic; - input.source = "#" + collSource.id; + var input = new InputLocal + { + semantic = inputSemantic, + source = "#" + collSource.id + }; Inputs.Add(input); } if (localInputSemantic != null) { - var vertexInputOff = new InputLocalOffset(); - vertexInputOff.semantic = localInputSemantic; - vertexInputOff.source = "#" + collSource.id; - vertexInputOff.offset = LastInputOffset++; + var vertexInputOff = new InputLocalOffset + { + semantic = localInputSemantic, + source = "#" + collSource.id, + offset = LastInputOffset++ + }; if (localInputSemantic == "TEXCOORD" || localInputSemantic == "COLOR") { vertexInputOff.set = setIndex; @@ -109,7 +106,7 @@ private void DetermineInputsFromComponentNames(List componentNames) { if (Options.ExportUVs) { - int uvIndex = Int32.Parse(component.Substring(component.Length - 1)); + int uvIndex = Int32.Parse(component[^1..]); var uvs = ExportedMesh.PrimaryVertexData.MakeColladaUVs(ExportedMesh.Name, uvIndex, Options.FlipUVs); AddInput(uvs, null, "TEXCOORD", (ulong)uvIndex); } @@ -125,7 +122,7 @@ private void DetermineInputsFromComponentNames(List componentNames) { if (Options.ExportUVs) { - int uvIndex = Int32.Parse(component.Substring(component.Length - 1)) - 1; + int uvIndex = Int32.Parse(component[^1..]) - 1; var uvs = ExportedMesh.PrimaryVertexData.MakeColladaUVs(ExportedMesh.Name, uvIndex, Options.FlipUVs); AddInput(uvs, null, "TEXCOORD", (ulong)uvIndex); } @@ -309,9 +306,9 @@ private technique ExportLSLibProfile() public mesh Export() { // Jank we need to create XMLElements on the fly - Sources = new List(); - Inputs = new List(); - InputOffsets = new List(); + Sources = []; + Inputs = []; + InputOffsets = []; LastInputOffset = 0; var vertexData = ExportedMesh.PrimaryVertexData; @@ -336,21 +333,25 @@ public mesh Export() vertexData.Deduplicator.Colors.Select(color => color.DeduplicationMap).ToList() ); - var colladaMesh = new mesh(); - colladaMesh.vertices = new vertices(); - colladaMesh.vertices.id = ExportedMesh.Name + "-vertices"; - colladaMesh.vertices.input = Inputs.ToArray(); - colladaMesh.source = Sources.ToArray(); - colladaMesh.Items = new object[] { triangles }; - colladaMesh.extra = new extra[] + var colladaMesh = new mesh { - new extra + vertices = new vertices { - technique = new technique[] + id = ExportedMesh.Name + "-vertices", + input = Inputs.ToArray() + }, + source = Sources.ToArray(), + Items = [triangles], + extra = + [ + new extra { - ExportLSLibProfile() + technique = + [ + ExportLSLibProfile() + ] } - } + ] }; return colladaMesh; @@ -361,18 +362,20 @@ public mesh Export() public class ColladaExporter { [Serialization(Kind = SerializationKind.None)] - public ExporterOptions Options = new ExporterOptions(); + public ExporterOptions Options = new(); - private XmlDocument Xml = new XmlDocument(); + private XmlDocument Xml = new(); private void ExportMeshBinding(Model model, string skelRef, MeshBinding meshBinding, List geometries, List controllers, List geomNodes) { var exporter = new ColladaMeshExporter(meshBinding.Mesh, Options); var mesh = exporter.Export(); - var geom = new geometry(); - geom.id = meshBinding.Mesh.Name + "-geom"; - geom.name = meshBinding.Mesh.Name; - geom.Item = mesh; + var geom = new geometry + { + id = meshBinding.Mesh.Name + "-geom", + name = meshBinding.Mesh.Name, + Item = mesh + }; geometries.Add(geom); bool hasSkin = skelRef != null && meshBinding.Mesh.IsSkinned(); @@ -387,30 +390,38 @@ private void ExportMeshBinding(Model model, string skelRef, MeshBinding meshBind } skin = ExportSkin(meshBinding.Mesh, model.Skeleton.Bones, boneNames, geom.id); - ctrl = new controller(); - ctrl.id = meshBinding.Mesh.Name + "-skin"; - ctrl.name = meshBinding.Mesh.Name + "_Skin"; - ctrl.Item = skin; + ctrl = new controller + { + id = meshBinding.Mesh.Name + "-skin", + name = meshBinding.Mesh.Name + "_Skin", + Item = skin + }; controllers.Add(ctrl); } - var geomNode = new node(); - geomNode.id = geom.name + "-node"; - geomNode.name = geom.name; - geomNode.type = NodeType.NODE; + var geomNode = new node + { + id = geom.name + "-node", + name = geom.name, + type = NodeType.NODE + }; if (hasSkin) { - var controllerInstance = new instance_controller(); - controllerInstance.url = "#" + ctrl.id; - controllerInstance.skeleton = new string[] { "#" + skelRef }; - geomNode.instance_controller = new instance_controller[] { controllerInstance }; + var controllerInstance = new instance_controller + { + url = "#" + ctrl.id, + skeleton = ["#" + skelRef] + }; + geomNode.instance_controller = [controllerInstance]; } else { - var geomInstance = new instance_geometry(); - geomInstance.url = "#" + geom.id; - geomNode.instance_geometry = new instance_geometry[] { geomInstance }; + var geomInstance = new instance_geometry + { + url = "#" + geom.id + }; + geomNode.instance_geometry = [geomInstance]; } geomNodes.Add(geomNode); @@ -459,8 +470,8 @@ private skin ExportSkin(Mesh mesh, List bones, Dictionary na }); } - var jointSource = ColladaUtils.MakeNameSource(mesh.Name, "joints", new string[] { "JOINT" }, joints.ToArray()); - var poseSource = ColladaUtils.MakeFloatSource(mesh.Name, "poses", new string[] { "TRANSFORM" }, poses.ToArray(), 16, "float4x4"); + var jointSource = ColladaUtils.MakeNameSource(mesh.Name, "joints", ["JOINT"], joints.ToArray()); + var poseSource = ColladaUtils.MakeFloatSource(mesh.Name, "poses", ["TRANSFORM"], poses.ToArray(), 16, "float4x4"); var weightsSource = mesh.PrimaryVertexData.MakeBoneWeights(mesh.Name); var vertices = mesh.PrimaryVertexData.Deduplicator.Vertices.Uniques; @@ -485,38 +496,52 @@ private skin ExportSkin(Mesh mesh, List bones, Dictionary na vertexInfluenceCounts.Add(influences); } - var jointOffsets = new InputLocalOffset(); - jointOffsets.semantic = "JOINT"; - jointOffsets.source = "#" + jointSource.id; - jointOffsets.offset = 0; + var jointOffsets = new InputLocalOffset + { + semantic = "JOINT", + source = "#" + jointSource.id, + offset = 0 + }; - var weightOffsets = new InputLocalOffset(); - weightOffsets.semantic = "WEIGHT"; - weightOffsets.source = "#" + weightsSource.id; - weightOffsets.offset = 1; + var weightOffsets = new InputLocalOffset + { + semantic = "WEIGHT", + source = "#" + weightsSource.id, + offset = 1 + }; - var vertWeights = new skinVertex_weights(); - vertWeights.count = (ulong)vertices.Count; - vertWeights.input = new InputLocalOffset[] { jointOffsets, weightOffsets }; - vertWeights.v = string.Join(" ", vertexInfluences.Select(x => x.ToString()).ToArray()); - vertWeights.vcount = string.Join(" ", vertexInfluenceCounts.Select(x => x.ToString()).ToArray()); + var vertWeights = new skinVertex_weights + { + count = (ulong)vertices.Count, + input = [jointOffsets, weightOffsets], + v = string.Join(" ", vertexInfluences.Select(x => x.ToString()).ToArray()), + vcount = string.Join(" ", vertexInfluenceCounts.Select(x => x.ToString()).ToArray()) + }; - var skin = new skin(); - skin.source1 = "#" + geometryId; - skin.bind_shape_matrix = "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1"; + var skin = new skin + { + source1 = "#" + geometryId, + bind_shape_matrix = "1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1", - var skinJoints = new skinJoints(); - var skinJointInput = new InputLocal(); - skinJointInput.semantic = "JOINT"; - skinJointInput.source = "#" + jointSource.id; - var skinInvBindInput = new InputLocal(); - skinInvBindInput.semantic = "INV_BIND_MATRIX"; - skinInvBindInput.source = "#" + poseSource.id; - skinJoints.input = new InputLocal[] { skinJointInput, skinInvBindInput }; + joints = new skinJoints + { + input = [ + new InputLocal + { + semantic = "JOINT", + source = "#" + jointSource.id + }, + new InputLocal + { + semantic = "INV_BIND_MATRIX", + source = "#" + poseSource.id + } + ] + }, - skin.joints = skinJoints; - skin.source = new source[] { jointSource, poseSource, weightsSource }; - skin.vertex_weights = vertWeights; + source = [jointSource, poseSource, weightsSource], + vertex_weights = vertWeights + }; return skin; } @@ -619,7 +644,6 @@ public List ExportKeyframeTrack(TransformTrack transformTrack, BG3Tra track.InterpolateFrames(); var anims = new List(); - var inputs = new List(); var outputs = new List(track.Keyframes.Count * 16); foreach (var keyframe in track.Keyframes.Values) @@ -658,53 +682,60 @@ public List ExportKeyframeTrack(TransformTrack transformTrack, BG3Tra interpolations.Add(interpolations[0]); } - var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", new string[] { "TIME" }, knots.ToArray()); - var knotsInput = new InputLocal(); - knotsInput.semantic = "INPUT"; - knotsInput.source = "#" + knotsSource.id; - inputs.Add(knotsInput); - - var outSource = ColladaUtils.MakeFloatSource(name, "outputs", new string[] { "TRANSFORM" }, outputs.ToArray(), 16, "float4x4"); - var outInput = new InputLocal(); - outInput.semantic = "OUTPUT"; - outInput.source = "#" + outSource.id; - inputs.Add(outInput); - - var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", new string[] { "INTERPOLATION" }, interpolations.ToArray()); + var knotsSource = ColladaUtils.MakeFloatSource(name, "inputs", ["TIME"], knots.ToArray()); + var outSource = ColladaUtils.MakeFloatSource(name, "outputs", ["TRANSFORM"], outputs.ToArray(), 16, "float4x4"); + var interpSource = ColladaUtils.MakeNameSource(name, "interpolations", ["INTERPOLATION"], interpolations.ToArray()); - var interpInput = new InputLocal(); - interpInput.semantic = "INTERPOLATION"; - interpInput.source = "#" + interpSource.id; - inputs.Add(interpInput); - - var sampler = new sampler(); - sampler.id = name + "_sampler"; - sampler.input = inputs.ToArray(); - - var channel = new channel(); - channel.source = "#" + sampler.id; - channel.target = target; - - var animation = new animation(); - animation.id = name; - animation.name = name; - var animItems = new List(); - animItems.Add(knotsSource); - animItems.Add(outSource); - animItems.Add(interpSource); - animItems.Add(sampler); - animItems.Add(channel); - animation.Items = animItems.ToArray(); + var sampler = new sampler + { + id = name + "_sampler", + input = + [ + new InputLocal + { + semantic = "INTERPOLATION", + source = "#" + interpSource.id + }, + new InputLocal + { + semantic = "OUTPUT", + source = "#" + outSource.id + }, + new InputLocal + { + semantic = "INPUT", + source = "#" + knotsSource.id + } + ] + }; - animation.extra = new extra[] + var channel = new channel { - new extra - { - technique = new technique[] + source = "#" + sampler.id, + target = target + }; + + var animation = new animation + { + id = name, + name = name, + Items = [ + knotsSource, + outSource, + interpSource, + sampler, + channel + ], + extra = + [ + new extra { - ExportAnimationLSLibProfile(extData) + technique = + [ + ExportAnimationLSLibProfile(extData) + ] } - } + ] }; anims.Add(animation); @@ -832,25 +863,29 @@ private technique ExportRootLSLibProfile(Root root) public void Export(Root root, string outputPath) { - var collada = new COLLADA(); - var asset = new asset(); var contributor = new assetContributor(); if (root.ArtToolInfo != null) contributor.authoring_tool = root.ArtToolInfo.FromArtToolName; else contributor.authoring_tool = "LSLib COLLADA Exporter v" + Common.LibraryVersion(); - asset.contributor = new assetContributor[] { contributor }; - asset.created = DateTime.Now; - asset.modified = DateTime.Now; - asset.unit = new assetUnit(); - asset.unit.name = "meter"; + + var asset = new asset + { + contributor = [contributor], + created = DateTime.Now, + modified = DateTime.Now, + unit = new assetUnit + { + name = "meter" + }, + up_axis = UpAxisType.Y_UP + }; + // TODO: Handle up vector, etc. properly? if (root.ArtToolInfo != null) asset.unit.meter = root.ArtToolInfo.UnitsPerMeter; else asset.unit.meter = 1; - asset.up_axis = UpAxisType.Y_UP; - collada.asset = asset; var geometries = new List(); var controllers = new List(); @@ -864,18 +899,22 @@ public void Export(Root root, string outputPath) { var anims = ExportAnimations(anim); animations.AddRange(anims); - var clip = new animation_clip(); - clip.id = anim.Name + "_Animation"; - clip.name = anim.Name; - clip.start = 0.0; - clip.end = anim.Duration; - clip.endSpecified = true; + var clip = new animation_clip + { + id = anim.Name + "_Animation", + name = anim.Name, + start = 0.0, + end = anim.Duration, + endSpecified = true + }; var animInstances = new List(); foreach (var animChannel in anims) { - var instance = new InstanceWithExtra(); - instance.url = "#" + animChannel.id; + var instance = new InstanceWithExtra + { + url = "#" + animChannel.id + }; animInstances.Add(instance); } @@ -887,65 +926,79 @@ public void Export(Root root, string outputPath) if (animations.Count > 0) { - var animationLib = new library_animations(); - animationLib.animation = animations.ToArray(); + var animationLib = new library_animations + { + animation = animations.ToArray() + }; rootElements.Add(animationLib); } if (animationClips.Count > 0) { - var animationClipLib = new library_animation_clips(); - animationClipLib.animation_clip = animationClips.ToArray(); + var animationClipLib = new library_animation_clips + { + animation_clip = animationClips.ToArray() + }; rootElements.Add(animationClipLib); } if (geometries.Count > 0) { - var geometryLib = new library_geometries(); - geometryLib.geometry = geometries.ToArray(); + var geometryLib = new library_geometries + { + geometry = geometries.ToArray() + }; rootElements.Add(geometryLib); } if (controllers.Count > 0) { - var controllerLib = new library_controllers(); - controllerLib.controller = controllers.ToArray(); + var controllerLib = new library_controllers + { + controller = controllers.ToArray() + }; rootElements.Add(controllerLib); } var visualScenes = new library_visual_scenes(); - var visualScene = new visual_scene(); - visualScene.id = "DefaultVisualScene"; - visualScene.name = "unnamed"; - - visualScene.node = geomNodes.ToArray(); - visualScenes.visual_scene = new visual_scene[] { visualScene }; + var visualScene = new visual_scene + { + id = "DefaultVisualScene", + name = "unnamed", + node = geomNodes.ToArray() + }; + visualScenes.visual_scene = [visualScene]; - var visualSceneInstance = new InstanceWithExtra(); - visualSceneInstance.url = "#DefaultVisualScene"; + var visualSceneInstance = new InstanceWithExtra + { + url = "#DefaultVisualScene" + }; rootElements.Add(visualScenes); - var scene = new COLLADAScene(); - scene.instance_visual_scene = visualSceneInstance; - collada.scene = scene; - - collada.Items = rootElements.ToArray(); + var scene = new COLLADAScene + { + instance_visual_scene = visualSceneInstance + }; - collada.extra = new extra[] + var collada = new COLLADA { - new extra - { - technique = new technique[] + asset = asset, + scene = scene, + Items = rootElements.ToArray(), + extra = + [ + new extra { - ExportRootLSLibProfile(root) + technique = + [ + ExportRootLSLibProfile(root) + ] } - } + ] }; - using (var stream = File.Open(outputPath, System.IO.FileMode.Create)) - { - collada.Save(stream); - } + using var stream = File.Open(outputPath, FileMode.Create); + collada.Save(stream); } } } diff --git a/LSLib/Granny/Model/ColladaHelpers.cs b/LSLib/Granny/Model/ColladaHelpers.cs index feb1659a..b024793b 100644 --- a/LSLib/Granny/Model/ColladaHelpers.cs +++ b/LSLib/Granny/Model/ColladaHelpers.cs @@ -1,5 +1,5 @@ using LSLib.Granny.GR2; -using OpenTK; +using OpenTK.Mathematics; using System; using System.Collections.Generic; @@ -38,15 +38,13 @@ public static Matrix4 ToMatrix4(this rotate r) public static Matrix4 TranslationToMatrix4(this TargetableFloat3 t) { - Matrix4 trans; - Matrix4.CreateTranslation((float)t.Values[0], (float)t.Values[1], (float)t.Values[2], out trans); + Matrix4.CreateTranslation((float)t.Values[0], (float)t.Values[1], (float)t.Values[2], out Matrix4 trans); return trans; } public static Matrix4 ScaleToMatrix4(this TargetableFloat3 t) { - Matrix4 scale; - Matrix4.CreateScale((float)t.Values[0], (float)t.Values[1], (float)t.Values[2], out scale); + Matrix4.CreateScale((float)t.Values[0], (float)t.Values[1], (float)t.Values[2], out Matrix4 scale); return scale; } @@ -59,27 +57,14 @@ public static Matrix4 GetLocalTransform(this node n) for (var i = 0; i < n.ItemsElementName.Length; i++) { var name = n.ItemsElementName[i]; - switch (name) + accum = name switch { - case ItemsChoiceType2.matrix: - accum = (n.Items[i] as matrix).ToMatrix4() * Matrix4.Identity; - break; - - case ItemsChoiceType2.translate: - accum = (n.Items[i] as TargetableFloat3).TranslationToMatrix4() * Matrix4.Identity; - break; - - case ItemsChoiceType2.rotate: - accum = (n.Items[i] as rotate).ToMatrix4() * Matrix4.Identity; - break; - - case ItemsChoiceType2.scale: - accum = (n.Items[i] as TargetableFloat3).ScaleToMatrix4() * Matrix4.Identity; - break; - - default: - throw new Exception("Unsupported Collada NODE transform: " + name); - } + ItemsChoiceType2.matrix => (n.Items[i] as matrix).ToMatrix4() * Matrix4.Identity, + ItemsChoiceType2.translate => (n.Items[i] as TargetableFloat3).TranslationToMatrix4() * Matrix4.Identity, + ItemsChoiceType2.rotate => (n.Items[i] as rotate).ToMatrix4() * Matrix4.Identity, + ItemsChoiceType2.scale => (n.Items[i] as TargetableFloat3).ScaleToMatrix4() * Matrix4.Identity, + _ => throw new Exception("Unsupported Collada NODE transform: " + name), + }; } } @@ -203,14 +188,14 @@ public static List StringsToIntegers(String s) { if (startingPos != -1) { - floats.Add(int.Parse(s.Substring(startingPos, i - startingPos))); + floats.Add(int.Parse(s[startingPos..i])); startingPos = -1; } } } if (startingPos != -1) - floats.Add(int.Parse(s.Substring(startingPos, s.Length - startingPos))); + floats.Add(int.Parse(s[startingPos..])); return floats; } diff --git a/LSLib/Granny/Model/ColladaImporter.cs b/LSLib/Granny/Model/ColladaImporter.cs index d20ef062..5c38f59d 100644 --- a/LSLib/Granny/Model/ColladaImporter.cs +++ b/LSLib/Granny/Model/ColladaImporter.cs @@ -1,10 +1,10 @@ using System; using System.Collections.Generic; +using System.IO; using System.Linq; -using Alphaleonis.Win32.Filesystem; using LSLib.Granny.GR2; using LSLib.LS; -using OpenTK; +using OpenTK.Mathematics; namespace LSLib.Granny.Model { @@ -17,8 +17,10 @@ internal class ColladaSource public static ColladaSource FromCollada(source src) { - var source = new ColladaSource(); - source.id = src.id; + var source = new ColladaSource + { + id = src.id + }; var accessor = src.technique_common.accessor; // TODO: check src.#ID? @@ -29,8 +31,7 @@ public static ColladaSource FromCollada(source src) { floats = src.Item as float_array; // Workaround for empty arrays being null - if (floats.Values == null) - floats.Values = new double[] { }; + floats.Values ??= []; if ((int)floats.count != floats.Values.Length || floats.count < accessor.stride * accessor.count + accessor.offset) throw new ParsingException("Float source data size mismatch. Check source and accessor item counts."); @@ -39,8 +40,7 @@ public static ColladaSource FromCollada(source src) { names = src.Item as Name_array; // Workaround for empty arrays being null - if (names.Values == null) - names.Values = new string[] { }; + names.Values ??= []; if ((int)names.count != names.Values.Length || names.count < accessor.stride * accessor.count + accessor.offset) throw new ParsingException("Name source data size mismatch. Check source and accessor item counts."); @@ -51,8 +51,7 @@ public static ColladaSource FromCollada(source src) var paramOffset = 0; foreach (var param in accessor.param) { - if (param.name == null) - param.name = "default"; + param.name ??= "default"; if (param.type == "float" || param.type == "double") { var items = new List((int)accessor.count); @@ -115,7 +114,7 @@ class RootBoneInfo public class ColladaImporter { [Serialization(Kind = SerializationKind.None)] - public ExporterOptions Options = new ExporterOptions(); + public ExporterOptions Options = new(); private bool ZUp = false; @@ -128,12 +127,14 @@ public class ColladaImporter private ArtToolInfo ImportArtToolInfo(COLLADA collada) { ZUp = false; - var toolInfo = new ArtToolInfo(); - toolInfo.FromArtToolName = "Unknown"; - toolInfo.ArtToolMajorRevision = 1; - toolInfo.ArtToolMinorRevision = 0; - toolInfo.ArtToolPointerSize = Options.Is64Bit ? 64 : 32; - toolInfo.Origin = new float[] { 0, 0, 0 }; + var toolInfo = new ArtToolInfo + { + FromArtToolName = "Unknown", + ArtToolMajorRevision = 1, + ArtToolMinorRevision = 0, + ArtToolPointerSize = Options.Is64Bit ? 64 : 32, + Origin = [0, 0, 0] + }; toolInfo.SetYUp(); if (collada.asset != null) @@ -176,13 +177,14 @@ private ArtToolInfo ImportArtToolInfo(COLLADA collada) private ExporterInfo ImportExporterInfo(COLLADA collada) { - var exporterInfo = new ExporterInfo(); - exporterInfo.ExporterName = String.Format("LSLib GR2 Exporter v{0}", Common.LibraryVersion()); - exporterInfo.ExporterMajorRevision = Common.MajorVersion; - exporterInfo.ExporterMinorRevision = Common.MinorVersion; - exporterInfo.ExporterBuildNumber = 0; - exporterInfo.ExporterCustomization = Common.PatchVersion; - return exporterInfo; + return new ExporterInfo + { + ExporterName = $"LSLib GR2 Exporter v{Common.LibraryVersion()}", + ExporterMajorRevision = Common.MajorVersion, + ExporterMinorRevision = Common.MinorVersion, + ExporterBuildNumber = 0, + ExporterCustomization = Common.PatchVersion + }; } private DivinityModelFlag DetermineSkeletonModelFlagsFromModels(Root root, Skeleton skeleton, DivinityModelFlag meshFlagOverrides) @@ -219,10 +221,7 @@ private void BuildExtendedData(Root root) modelFlags = mesh.ExtendedData.UserMeshProperties.MeshFlags; } - if (mesh.ExtendedData == null) - { - mesh.ExtendedData = DivinityMeshExtendedData.Make(); - } + mesh.ExtendedData ??= DivinityMeshExtendedData.Make(); mesh.ExtendedData.UserMeshProperties.MeshFlags = modelFlags; mesh.ExtendedData.UpdateFromModelInfo(mesh, Options.ModelInfoFormat); } @@ -242,11 +241,7 @@ private void BuildExtendedData(Root root) foreach (var bone in skeleton.Bones ?? Enumerable.Empty()) { - if (bone.ExtendedData == null) - { - bone.ExtendedData = new DivinityBoneExtendedData(); - } - + bone.ExtendedData ??= new DivinityBoneExtendedData(); var userDefinedProperties = UserDefinedPropertiesHelpers.MeshFlagsToUserDefinedProperties(accumulatedFlags); bone.ExtendedData.UserDefinedProperties = userDefinedProperties; bone.ExtendedData.IsRigid = (accumulatedFlags.IsRigid()) ? 1 : 0; @@ -282,19 +277,13 @@ private void FindRootBones(List parents, node node, List roo public static technique FindExporterExtraData(extra[] extras) { - if (extras != null) + foreach (var extra in extras ?? Enumerable.Empty()) { - foreach (var extra in extras) + foreach (var technique in extra.technique ?? Enumerable.Empty()) { - if (extra.technique != null) + if (technique.profile == "LSTools") { - foreach (var technique in extra.technique) - { - if (technique.profile == "LSTools") - { - return technique; - } - } + return technique; } } } @@ -445,7 +434,7 @@ private void ValidateLSLibProfileMetadataVersion(string ver) } } - private void LoadColladaLSLibProfileData(Root root, COLLADA collada) + private void LoadColladaLSLibProfileData(COLLADA collada) { var technique = FindExporterExtraData(collada.extra); if (technique == null || technique.Any == null) return; @@ -476,12 +465,32 @@ private Mesh ImportMesh(geometry geom, mesh mesh, VertexDescriptor vertexFormat) bool isSkinned = SkinnedMeshes.Contains(geom.id); collada.ImportFromCollada(mesh, vertexFormat, isSkinned, Options); - var m = new Mesh(); - m.VertexFormat = collada.InternalVertexType; - m.Name = "Unnamed"; + var m = new Mesh + { + VertexFormat = collada.InternalVertexType, + Name = "Unnamed", + + PrimaryVertexData = new VertexData + { + Vertices = collada.ConsolidatedVertices + }, + + PrimaryTopology = new TriTopology + { + Indices = collada.ConsolidatedIndices, + Groups = [ + new TriTopologyGroup + { + MaterialIndex = 0, + TriFirst = 0, + TriCount = collada.TriangleCount + } + ] + }, - m.PrimaryVertexData = new VertexData(); - m.PrimaryVertexData.Vertices = collada.ConsolidatedVertices; + MaterialBindings = [new MaterialBinding()], + OriginalToConsolidatedVertexIndexMap = collada.OriginalToConsolidatedVertexIndexMap + }; if (!Options.StripMetadata) { @@ -493,22 +502,6 @@ private Mesh ImportMesh(geometry geom, mesh mesh, VertexDescriptor vertexFormat) m.PrimaryVertexData.VertexComponentNames = null; } - m.PrimaryTopology = new TriTopology(); - m.PrimaryTopology.Indices = collada.ConsolidatedIndices; - m.PrimaryTopology.Groups = new List(); - var triGroup = new TriTopologyGroup(); - triGroup.MaterialIndex = 0; - triGroup.TriFirst = 0; - triGroup.TriCount = collada.TriangleCount; - m.PrimaryTopology.Groups.Add(triGroup); - - m.MaterialBindings = new List(); - m.MaterialBindings.Add(new MaterialBinding()); - - // m.BoneBindings; - TODO - - m.OriginalToConsolidatedVertexIndexMap = collada.OriginalToConsolidatedVertexIndexMap; - MakeExtendedData(mesh, m); Utils.Info(String.Format("Imported {0} mesh ({1} tri groups, {2} tris)", @@ -534,8 +527,7 @@ private void ImportSkin(Root root, skin skin) if (skin.source1[0] != '#') throw new ParsingException("Only ID references are supported for skin geometries"); - Mesh mesh = null; - if (!ColladaGeometries.TryGetValue(skin.source1.Substring(1), out mesh)) + if (!ColladaGeometries.TryGetValue(skin.source1[1..], out Mesh mesh)) throw new ParsingException("Skin references nonexistent mesh: " + skin.source1); if (!mesh.VertexFormat.HasBoneWeights) @@ -559,8 +551,7 @@ private void ImportSkin(Root root, skin skin) if (input.source[0] != '#') throw new ParsingException("Only ID references are supported for joint input sources"); - ColladaSource inputSource = null; - if (!sources.TryGetValue(input.source.Substring(1), out inputSource)) + if (!sources.TryGetValue(input.source.Substring(1), out ColladaSource inputSource)) throw new ParsingException("Joint input source does not exist: " + input.source); if (input.semantic == "JOINT") @@ -570,12 +561,11 @@ private void ImportSkin(Root root, skin skin) throw new ParsingException("Joint input source 'JOINT' must contain array of names."); var skeleton = root.Skeletons[0]; - joints = new List(); + joints = []; foreach (var name in jointNames) { - Bone bone = null; var lookupName = name.Replace("_x0020_", " "); - if (!skeleton.BonesBySID.TryGetValue(lookupName, out bone)) + if (!skeleton.BonesBySID.TryGetValue(lookupName, out Bone bone)) throw new ParsingException("Joint name list references nonexistent bone: " + lookupName); joints.Add(bone); @@ -628,8 +618,7 @@ private void ImportSkin(Root root, skin skin) if (input.source[0] != '#') throw new ParsingException("Only ID references are supported for weight input sources"); - ColladaSource inputSource = null; - if (!sources.TryGetValue(input.source.Substring(1), out inputSource)) + if (!sources.TryGetValue(input.source[1..], out ColladaSource inputSource)) throw new ParsingException("Weight input source does not exist: " + input.source); if (!inputSource.FloatParams.TryGetValue("WEIGHT", out weights)) @@ -658,8 +647,7 @@ private void ImportSkin(Root root, skin skin) var weightIndex = influences[offset + weightInputIndex]; var joint = joints[jointIndex]; var weight = weights[weightIndex]; - if (!boundBones.Contains(joint)) - boundBones.Add(joint); + boundBones.Add(joint); offset += stride; } @@ -667,7 +655,7 @@ private void ImportSkin(Root root, skin skin) if (boundBones.Count > 127) throw new ParsingException("D:OS supports at most 127 bound bones per mesh."); - mesh.BoneBindings = new List(); + mesh.BoneBindings = []; var boneToIndexMaps = new Dictionary(); for (var i = 0; i < joints.Count; i++) { @@ -678,22 +666,24 @@ private void ImportSkin(Root root, skin skin) // Hopefully the Collada ones are all equal ... var iwt = invBindMatrices[i]; // iwt.Transpose(); - joints[i].InverseWorldTransform = new float[] { + joints[i].InverseWorldTransform = [ iwt[0, 0], iwt[1, 0], iwt[2, 0], iwt[3, 0], iwt[0, 1], iwt[1, 1], iwt[2, 1], iwt[3, 1], iwt[0, 2], iwt[1, 2], iwt[2, 2], iwt[3, 2], iwt[0, 3], iwt[1, 3], iwt[2, 3], iwt[3, 3] - }; + ]; // Bind all bones that affect vertices to the mesh, so we can reference them // later from the vertexes BoneIndices. - var binding = new BoneBinding(); - binding.BoneName = joints[i].Name; - // TODO - // Use small bounding box values, as it interferes with object placement - // in D:OS 2 (after the Gift Bag 2 update) - binding.OBBMin = new float[] { -0.1f, -0.1f, -0.1f }; - binding.OBBMax = new float[] { 0.1f, 0.1f, 0.1f }; + var binding = new BoneBinding + { + BoneName = joints[i].Name, + // TODO + // Use small bounding box values, as it interferes with object placement + // in D:OS 2 (after the Gift Bag 2 update) + OBBMin = [-0.1f, -0.1f, -0.1f], + OBBMax = [0.1f, 0.1f, 0.1f] + }; mesh.BoneBindings.Add(binding); boneToIndexMaps.Add(joints[i], boneToIndexMaps.Count); } @@ -748,7 +738,7 @@ private void ImportSkin(Root root, skin skin) if (skin.bind_shape_matrix != null) { - var bindShapeFloats = skin.bind_shape_matrix.Trim().Split(new char[] { ' ' }).Select(s => Single.Parse(s)).ToArray(); + var bindShapeFloats = skin.bind_shape_matrix.Trim().Split([' ']).Select(s => Single.Parse(s)).ToArray(); var bindShapeMat = ColladaHelpers.FloatsToMatrix(bindShapeFloats); bindShapeMat.Transpose(); @@ -794,7 +784,7 @@ private void UpdateOBBs(Skeleton skeleton, Mesh mesh) var bone = skeleton.GetBoneByName(mesh.BoneBindings[bi].BoneName); var invWorldTransform = ColladaHelpers.FloatsToMatrix(bone.InverseWorldTransform); - var transformed = Vector3.Transform(vert.Position, invWorldTransform); + var transformed = Vector3.TransformPosition(vert.Position, invWorldTransform); obb.Min.X = Math.Min(obb.Min.X, transformed.X); obb.Min.Y = Math.Min(obb.Min.Y, transformed.Y); @@ -812,13 +802,13 @@ private void UpdateOBBs(Skeleton skeleton, Mesh mesh) var obb = obbs[i]; if (obb.NumVerts > 0) { - mesh.BoneBindings[i].OBBMin = new float[] { obb.Min.X, obb.Min.Y, obb.Min.Z }; - mesh.BoneBindings[i].OBBMax = new float[] { obb.Max.X, obb.Max.Y, obb.Max.Z }; + mesh.BoneBindings[i].OBBMin = [obb.Min.X, obb.Min.Y, obb.Min.Z]; + mesh.BoneBindings[i].OBBMax = [obb.Max.X, obb.Max.Y, obb.Max.Z]; } else { - mesh.BoneBindings[i].OBBMin = new float[] { 0.0f, 0.0f, 0.0f }; - mesh.BoneBindings[i].OBBMax = new float[] { 0.0f, 0.0f, 0.0f }; + mesh.BoneBindings[i].OBBMin = [0.0f, 0.0f, 0.0f]; + mesh.BoneBindings[i].OBBMax = [0.0f, 0.0f, 0.0f]; } } } @@ -851,10 +841,10 @@ public void ImportAnimations(IEnumerable anims, Root root, Skeleton s var trackGroup = new TrackGroup { Name = (skeleton != null) ? skeleton.Name : "Dummy_Root", - TransformTracks = new List(), + TransformTracks = [], InitialPlacement = new Transform(), AccumulationFlags = 2, - LoopTranslation = new float[] { 0, 0, 0 } + LoopTranslation = [0, 0, 0] }; var animation = new Animation @@ -865,7 +855,7 @@ public void ImportAnimations(IEnumerable anims, Root root, Skeleton s DefaultLoopCount = 1, Flags = 1, Duration = .0f, - TrackGroups = new List { trackGroup } + TrackGroups = [trackGroup] }; foreach (var colladaTrack in anims) @@ -899,7 +889,7 @@ public void ImportAnimation(animation colladaAnim, Animation animation, TrackGro var duration = .0f; if (childAnims < colladaAnim.Items.Length) { - ColladaAnimation importAnim = new ColladaAnimation(); + ColladaAnimation importAnim = new(); if (importAnim.ImportFromCollada(colladaAnim, skeleton)) { duration = Math.Max(duration, importAnim.Duration); @@ -920,26 +910,26 @@ public Root Import(string inputPath) collada = COLLADA.Load(stream); } - var root = new Root(); - LoadColladaLSLibProfileData(root, collada); - root.ArtToolInfo = ImportArtToolInfo(collada); - if (!Options.StripMetadata) - { - root.ExporterInfo = ImportExporterInfo(collada); - } - - root.FromFileName = inputPath; + LoadColladaLSLibProfileData(collada); - root.Skeletons = new List(); - root.VertexDatas = new List(); - root.TriTopologies = new List(); - root.Meshes = new List(); - root.Models = new List(); - root.TrackGroups = new List(); - root.Animations = new List(); + var root = new Root + { + ArtToolInfo = ImportArtToolInfo(collada), + ExporterInfo = Options.StripMetadata ? null : ImportExporterInfo(collada), + + FromFileName = inputPath, + + Skeletons = [], + VertexDatas = [], + TriTopologies = [], + Meshes = [], + Models = [], + TrackGroups = [], + Animations = [] + }; - ColladaGeometries = new Dictionary(); - SkinnedMeshes = new HashSet(); + ColladaGeometries = []; + SkinnedMeshes = []; var collGeometries = new List(); var collSkins = new List(); @@ -961,7 +951,7 @@ public Root Import(string inputPath) if (controller.Item is skin) { collSkins.Add(controller.Item as skin); - SkinnedMeshes.Add((controller.Item as skin).source1.Substring(1)); + SkinnedMeshes.Add((controller.Item as skin).source1[1..]); } else { @@ -982,7 +972,7 @@ public Root Import(string inputPath) foreach (var node in scene.node) { collNodes.Add(node); - FindRootBones(new List(), node, rootBones); + FindRootBones([], node, rootBones); } } } @@ -1016,7 +1006,7 @@ public Root Import(string inputPath) } else { - Utils.Warn(String.Format("Library {0} is unsupported and will be ignored", item.GetType().Name)); + Utils.Warn($"Library {item.GetType().Name} is unsupported and will be ignored"); } } @@ -1031,9 +1021,8 @@ public Root Import(string inputPath) foreach (var geometry in collGeometries) { - VertexDescriptor vertexFormat = null; // Use the override vertex format, if one was specified - Options.VertexFormats.TryGetValue(geometry.name, out vertexFormat); + Options.VertexFormats.TryGetValue(geometry.name, out VertexDescriptor vertexFormat); var mesh = ImportMesh(root, geometry.name, geometry, geometry.Item as mesh, vertexFormat); ColladaGeometries.Add(geometry.id, mesh); } diff --git a/LSLib/Granny/Model/ColladaMesh.cs b/LSLib/Granny/Model/ColladaMesh.cs index a8a05126..387f2258 100644 --- a/LSLib/Granny/Model/ColladaMesh.cs +++ b/LSLib/Granny/Model/ColladaMesh.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model @@ -24,8 +24,8 @@ public class ColladaMesh private int NormalsInputIndex = -1; private int TangentsInputIndex = -1; private int BinormalsInputIndex = -1; - private List UVInputIndices = new List(); - private List ColorInputIndices = new List(); + private List UVInputIndices = []; + private List ColorInputIndices = []; private VertexDescriptor InputVertexType; private VertexDescriptor OutputVertexType; private bool HasNormals = false; @@ -77,7 +77,7 @@ public int GetHashCode(int[] obj) void computeTangents() { // Check if the vertex format has at least one UV set - if (ConsolidatedVertices.Count() > 0) + if (ConsolidatedVertices.Count > 0) { var v = ConsolidatedVertices[0]; if (v.Format.TextureCoordinates == 0) @@ -194,7 +194,7 @@ private void computeNormals() { for (var vertexIdx = 0; vertexIdx < Vertices.Count; vertexIdx++) { - Vector3 N = new Vector3(0, 0, 0); + Vector3 N = new(0, 0, 0); var numIndices = VertexIndexCount(); for (int triVertIdx = 0; triVertIdx < numIndices; triVertIdx++) { @@ -206,7 +206,7 @@ private void computeNormals() VertexIndex(baseIdx + 1), VertexIndex(baseIdx + 2) }; - N = N + triangleNormalFromVertex(indices, triVertIdx - baseIdx); + N += triangleNormalFromVertex(indices, triVertIdx - baseIdx); } } @@ -266,8 +266,7 @@ private ColladaSource FindSource(string id) if (id.Length == 0 || id[0] != '#') throw new ParsingException("Only ID references are supported for input sources: " + id); - ColladaSource inputSource = null; - if (!Sources.TryGetValue(id.Substring(1), out inputSource)) + if (!Sources.TryGetValue(id.Substring(1), out ColladaSource inputSource)) throw new ParsingException("Input source does not exist: " + id); return inputSource; @@ -361,7 +360,7 @@ private void ImportVertices() private void ImportColors() { ColorInputIndices.Clear(); - Colors = new List>(); + Colors = []; foreach (var input in Inputs) { if (input.semantic == "COLOR") @@ -402,7 +401,7 @@ private void ImportUVs() { bool flip = Options.FlipUVs; UVInputIndices.Clear(); - UVs = new List>(); + UVs = []; foreach (var input in Inputs) { if (input.semantic == "TEXCOORD") @@ -413,7 +412,7 @@ private void ImportUVs() throw new ParsingException("Only ID references are supported for UV input sources"); ColladaSource inputSource = null; - if (!Sources.TryGetValue(input.source.Substring(1), out inputSource)) + if (!Sources.TryGetValue(input.source[1..], out inputSource)) throw new ParsingException("UV input source does not exist: " + input.source); List s = null, t = null; @@ -434,7 +433,7 @@ private void ImportUVs() private void ImportSources() { - Sources = new Dictionary(); + Sources = []; foreach (var source in Mesh.source) { var src = ColladaSource.FromCollada(source); @@ -444,8 +443,10 @@ private void ImportSources() private VertexDescriptor FindVertexFormat(bool isSkinned) { - var desc = new VertexDescriptor(); - desc.PositionType = PositionType.Float3; + var desc = new VertexDescriptor + { + PositionType = PositionType.Float3 + }; if (isSkinned) { desc.HasBoneWeights = true; @@ -497,10 +498,7 @@ public void ImportFromCollada(mesh mesh, VertexDescriptor vertexFormat, bool isS ImportSources(); ImportFaces(); - if (vertexFormat == null) - { - vertexFormat = FindVertexFormat(isSkinned); - } + vertexFormat ??= FindVertexFormat(isSkinned); InputVertexType = vertexFormat; OutputVertexType = new VertexDescriptor @@ -534,13 +532,13 @@ public void ImportFromCollada(mesh mesh, VertexDescriptor vertexFormat, bool isS ImportColors(); ImportUVs(); - if (UVInputIndices.Count() > 0 || ColorInputIndices.Count() > 0 + if (UVInputIndices.Count > 0 || ColorInputIndices.Count > 0 || NormalsInputIndex != -1 || TangentsInputIndex != -1 || BinormalsInputIndex != -1) { var outVertexIndices = new Dictionary(new VertexIndexComparer()); ConsolidatedIndices = new List(TriangleCount * 3); ConsolidatedVertices = new List(Vertices.Count); - OriginalToConsolidatedVertexIndexMap = new Dictionary>(); + OriginalToConsolidatedVertexIndexMap = []; for (var vert = 0; vert < TriangleCount * 3; vert++) { var index = new int[InputOffsetCount]; @@ -549,8 +547,7 @@ public void ImportFromCollada(mesh mesh, VertexDescriptor vertexFormat, bool isS index[i] = Indices[vert * InputOffsetCount + i]; } - int consolidatedIndex; - if (!outVertexIndices.TryGetValue(index, out consolidatedIndex)) + if (!outVertexIndices.TryGetValue(index, out int consolidatedIndex)) { var vertexIndex = index[VertexInputIndex]; consolidatedIndex = ConsolidatedVertices.Count; @@ -567,21 +564,20 @@ public void ImportFromCollada(mesh mesh, VertexDescriptor vertexFormat, bool isS { vertex.Binormal = Binormals[index[BinormalsInputIndex]]; } - for (int uv = 0; uv < UVInputIndices.Count(); uv++ ) + for (int uv = 0; uv < UVInputIndices.Count; uv++) { vertex.SetUV(uv, UVs[uv][index[UVInputIndices[uv]]]); } - for (int color = 0; color < ColorInputIndices.Count(); color++) + for (int color = 0; color < ColorInputIndices.Count; color++) { vertex.SetColor(color, Colors[color][index[ColorInputIndices[color]]]); } outVertexIndices.Add(index, consolidatedIndex); ConsolidatedVertices.Add(vertex); - List mappedIndices = null; - if (!OriginalToConsolidatedVertexIndexMap.TryGetValue(vertexIndex, out mappedIndices)) + if (!OriginalToConsolidatedVertexIndexMap.TryGetValue(vertexIndex, out List mappedIndices)) { - mappedIndices = new List(); + mappedIndices = []; OriginalToConsolidatedVertexIndexMap.Add(vertexIndex, mappedIndices); } @@ -603,9 +599,9 @@ public void ImportFromCollada(mesh mesh, VertexDescriptor vertexFormat, bool isS for (var vert = 0; vert < TriangleCount * 3; vert++) ConsolidatedIndices.Add(VertexIndex(vert)); - OriginalToConsolidatedVertexIndexMap = new Dictionary>(); + OriginalToConsolidatedVertexIndexMap = []; for (var i = 0; i < Vertices.Count; i++) - OriginalToConsolidatedVertexIndexMap.Add(i, new List { i }); + OriginalToConsolidatedVertexIndexMap.Add(i, [i]); } if ((InputVertexType.TangentType == NormalType.None diff --git a/LSLib/Granny/Model/CurveData/AnimationCurveData.cs b/LSLib/Granny/Model/CurveData/AnimationCurveData.cs index c4f096fd..29782f07 100644 --- a/LSLib/Granny/Model/CurveData/AnimationCurveData.cs +++ b/LSLib/Granny/Model/CurveData/AnimationCurveData.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData @@ -23,8 +23,8 @@ private static void Init() return; } - TypeToFormatMap = new Dictionary(); - NameToTypeMap = new Dictionary(); + TypeToFormatMap = []; + NameToTypeMap = []; Register(typeof(DaKeyframes32f), CurveFormat.DaKeyframes32f); Register(typeof(DaK32fC32f), CurveFormat.DaK32fC32f); @@ -58,8 +58,7 @@ public static Type Resolve(String name) { Init(); - Type type = null; - if (!NameToTypeMap.TryGetValue(name, out type)) + if (!NameToTypeMap.TryGetValue(name, out Type type)) throw new ParsingException("Unsupported curve type: " + name); return type; @@ -181,10 +180,10 @@ public Type SelectType(MemberDefinition member, object node) public Type SelectType(MemberDefinition member, StructDefinition defn, object parent) { var fieldName = defn.Members[0].Name; - if (fieldName.Substring(0, 16) != "CurveDataHeader_") + if (fieldName[..16] != "CurveDataHeader_") throw new ParsingException("Unrecognized curve data header type: " + fieldName); - var curveType = fieldName.Substring(16); + var curveType = fieldName[16..]; return CurveRegistry.Resolve(curveType); } } @@ -204,7 +203,7 @@ public enum ExportType protected float ConvertOneOverKnotScaleTrunc(UInt16 oneOverKnotScaleTrunc) { - UInt32[] i = new UInt32[] { (UInt32)oneOverKnotScaleTrunc << 16 }; + UInt32[] i = [(UInt32)oneOverKnotScaleTrunc << 16]; float[] f = new float[1]; Buffer.BlockCopy(i, 0, f, 0, i.Length * 4); return f[0]; @@ -231,7 +230,7 @@ public virtual List GetMatrices() public virtual List GetQuaternions() { var matrices = GetMatrices(); - List quats = new List(matrices.Count); + List quats = new(matrices.Count); foreach (var matrix in matrices) { // Check that the matrix is orthogonal diff --git a/LSLib/Granny/Model/CurveData/D3Constant32f.cs b/LSLib/Granny/Model/CurveData/D3Constant32f.cs index d9ce2ec5..adbc18cb 100644 --- a/LSLib/Granny/Model/CurveData/D3Constant32f.cs +++ b/LSLib/Granny/Model/CurveData/D3Constant32f.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData @@ -20,12 +20,12 @@ public override int NumKnots() public override List GetKnots() { - return new List() { 0.0f }; + return [0.0f]; } public override List GetPoints() { - return new List() { new Vector3(Controls[0], Controls[1], Controls[2]) }; + return [new Vector3(Controls[0], Controls[1], Controls[2])]; } } } diff --git a/LSLib/Granny/Model/CurveData/D3I1K16uC16u.cs b/LSLib/Granny/Model/CurveData/D3I1K16uC16u.cs index ebaa8106..dcc0783a 100644 --- a/LSLib/Granny/Model/CurveData/D3I1K16uC16u.cs +++ b/LSLib/Granny/Model/CurveData/D3I1K16uC16u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/D3I1K32fC32f.cs b/LSLib/Granny/Model/CurveData/D3I1K32fC32f.cs index 886de201..40856eb9 100644 --- a/LSLib/Granny/Model/CurveData/D3I1K32fC32f.cs +++ b/LSLib/Granny/Model/CurveData/D3I1K32fC32f.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/D3I1K8uC8u.cs b/LSLib/Granny/Model/CurveData/D3I1K8uC8u.cs index 0953e02d..115d79f0 100644 --- a/LSLib/Granny/Model/CurveData/D3I1K8uC8u.cs +++ b/LSLib/Granny/Model/CurveData/D3I1K8uC8u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/D3K16uC16u.cs b/LSLib/Granny/Model/CurveData/D3K16uC16u.cs index b9b79ee6..6a74d99e 100644 --- a/LSLib/Granny/Model/CurveData/D3K16uC16u.cs +++ b/LSLib/Granny/Model/CurveData/D3K16uC16u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/D3K8uC8u.cs b/LSLib/Granny/Model/CurveData/D3K8uC8u.cs index a4f875c9..d562324b 100644 --- a/LSLib/Granny/Model/CurveData/D3K8uC8u.cs +++ b/LSLib/Granny/Model/CurveData/D3K8uC8u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/D4Constant32f.cs b/LSLib/Granny/Model/CurveData/D4Constant32f.cs index 2ce96118..df13f86f 100644 --- a/LSLib/Granny/Model/CurveData/D4Constant32f.cs +++ b/LSLib/Granny/Model/CurveData/D4Constant32f.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData @@ -20,13 +20,13 @@ public override int NumKnots() public override List GetKnots() { - return new List() { 0.0f }; + return [0.0f]; } // TODO: GetMatrices public override List GetQuaternions() { - return new List() { new Quaternion(Controls[0], Controls[1], Controls[2], Controls[3]) }; + return [new Quaternion(Controls[0], Controls[1], Controls[2], Controls[3])]; } } } diff --git a/LSLib/Granny/Model/CurveData/D4nK16uC15u.cs b/LSLib/Granny/Model/CurveData/D4nK16uC15u.cs index 108556f8..8cd7774f 100644 --- a/LSLib/Granny/Model/CurveData/D4nK16uC15u.cs +++ b/LSLib/Granny/Model/CurveData/D4nK16uC15u.cs @@ -1,25 +1,25 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData { public class D4nK16uC15u : AnimationCurveData { - private static float[] ScaleTable = { + private readonly static float[] ScaleTable = [ 1.4142135f, 0.70710677f, 0.35355338f, 0.35355338f, 0.35355338f, 0.17677669f, 0.17677669f, 0.17677669f, -1.4142135f, -0.70710677f, -0.35355338f, -0.35355338f, -0.35355338f, -0.17677669f, -0.17677669f, -0.17677669f - }; + ]; - private static float[] OffsetTable = { + private readonly static float[] OffsetTable = [ -0.70710677f, -0.35355338f, -0.53033006f, -0.17677669f, 0.17677669f, -0.17677669f, -0.088388346f, 0.0f, 0.70710677f, 0.35355338f, 0.53033006f, 0.17677669f, -0.17677669f, 0.17677669f, 0.088388346f, -0.0f - }; + ]; [Serialization(Type = MemberType.Inline)] public CurveDataHeader CurveDataHeader_D4nK16uC15u; diff --git a/LSLib/Granny/Model/CurveData/D4nK8uC7u.cs b/LSLib/Granny/Model/CurveData/D4nK8uC7u.cs index 99eed782..2a58537d 100644 --- a/LSLib/Granny/Model/CurveData/D4nK8uC7u.cs +++ b/LSLib/Granny/Model/CurveData/D4nK8uC7u.cs @@ -1,25 +1,25 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData { public class D4nK8uC7u : AnimationCurveData { - private static float[] ScaleTable = { + private static readonly float[] ScaleTable = [ 1.4142135f, 0.70710677f, 0.35355338f, 0.35355338f, 0.35355338f, 0.17677669f, 0.17677669f, 0.17677669f, -1.4142135f, -0.70710677f, -0.35355338f, -0.35355338f, -0.35355338f, -0.17677669f, -0.17677669f, -0.17677669f - }; + ]; - private static float[] OffsetTable = { + private static readonly float[] OffsetTable = [ -0.70710677f, -0.35355338f, -0.53033006f, -0.17677669f, 0.17677669f, -0.17677669f, -0.088388346f, 0.0f, 0.70710677f, 0.35355338f, 0.53033006f, 0.17677669f, -0.17677669f, 0.17677669f, 0.088388346f, -0.0f - }; + ]; [Serialization(Type = MemberType.Inline)] public CurveDataHeader CurveDataHeader_D4nK8uC7u; diff --git a/LSLib/Granny/Model/CurveData/D9I1K16uC16u.cs b/LSLib/Granny/Model/CurveData/D9I1K16uC16u.cs index 28e19437..e700b6bb 100644 --- a/LSLib/Granny/Model/CurveData/D9I1K16uC16u.cs +++ b/LSLib/Granny/Model/CurveData/D9I1K16uC16u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/D9I1K8uC8u.cs b/LSLib/Granny/Model/CurveData/D9I1K8uC8u.cs index 5a507cc9..bb9ed368 100644 --- a/LSLib/Granny/Model/CurveData/D9I1K8uC8u.cs +++ b/LSLib/Granny/Model/CurveData/D9I1K8uC8u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/D9I3K16uC16u.cs b/LSLib/Granny/Model/CurveData/D9I3K16uC16u.cs index 07600bd6..b51b8bd2 100644 --- a/LSLib/Granny/Model/CurveData/D9I3K16uC16u.cs +++ b/LSLib/Granny/Model/CurveData/D9I3K16uC16u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/D9I3K8uC8u.cs b/LSLib/Granny/Model/CurveData/D9I3K8uC8u.cs index d59d7e10..9b2fa0ff 100644 --- a/LSLib/Granny/Model/CurveData/D9I3K8uC8u.cs +++ b/LSLib/Granny/Model/CurveData/D9I3K8uC8u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/DaConstant32f.cs b/LSLib/Granny/Model/CurveData/DaConstant32f.cs index 10a53e48..53d8b4f2 100644 --- a/LSLib/Granny/Model/CurveData/DaConstant32f.cs +++ b/LSLib/Granny/Model/CurveData/DaConstant32f.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; using System.Diagnostics; @@ -21,20 +21,20 @@ public override int NumKnots() public override List GetKnots() { - return new List() { 0.0f }; + return [0.0f]; } public override List GetMatrices() { Debug.Assert(Controls.Count == 9); var m = Controls; - Matrix3 mat = new Matrix3( + Matrix3 mat = new( m[0], m[1], m[2], m[3], m[4], m[5], m[6], m[7], m[8] ); - return new List { mat }; + return [mat]; } } } diff --git a/LSLib/Granny/Model/CurveData/DaIdentity.cs b/LSLib/Granny/Model/CurveData/DaIdentity.cs index 6f08cf1c..0179b378 100644 --- a/LSLib/Granny/Model/CurveData/DaIdentity.cs +++ b/LSLib/Granny/Model/CurveData/DaIdentity.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData @@ -18,17 +18,17 @@ public override int NumKnots() public override List GetKnots() { - return new List() { 0.0f }; + return [0.0f]; } public override List GetPoints() { - return new List() { new Vector3(0.0f, 0.0f, 0.0f) }; + return [new Vector3(0.0f, 0.0f, 0.0f)]; } public override List GetMatrices() { - return new List() { Matrix3.Identity }; + return [Matrix3.Identity]; } } } diff --git a/LSLib/Granny/Model/CurveData/DaK16uC16u.cs b/LSLib/Granny/Model/CurveData/DaK16uC16u.cs index 8305caf9..cfbac448 100644 --- a/LSLib/Granny/Model/CurveData/DaK16uC16u.cs +++ b/LSLib/Granny/Model/CurveData/DaK16uC16u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using System.Diagnostics; using LSLib.Granny.GR2; diff --git a/LSLib/Granny/Model/CurveData/DaK32fC32f.cs b/LSLib/Granny/Model/CurveData/DaK32fC32f.cs index 8b628c0d..c12d4829 100644 --- a/LSLib/Granny/Model/CurveData/DaK32fC32f.cs +++ b/LSLib/Granny/Model/CurveData/DaK32fC32f.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/CurveData/DaK8uC8u.cs b/LSLib/Granny/Model/CurveData/DaK8uC8u.cs index 3300661a..fb730f70 100644 --- a/LSLib/Granny/Model/CurveData/DaK8uC8u.cs +++ b/LSLib/Granny/Model/CurveData/DaK8uC8u.cs @@ -1,6 +1,6 @@ using System; using System.Collections.Generic; -using OpenTK; +using OpenTK.Mathematics; using System.Diagnostics; using LSLib.Granny.GR2; diff --git a/LSLib/Granny/Model/CurveData/DaKeyframes32f.cs b/LSLib/Granny/Model/CurveData/DaKeyframes32f.cs index b69a349e..6b065dd2 100644 --- a/LSLib/Granny/Model/CurveData/DaKeyframes32f.cs +++ b/LSLib/Granny/Model/CurveData/DaKeyframes32f.cs @@ -1,7 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model.CurveData diff --git a/LSLib/Granny/Model/DivinityMesh.cs b/LSLib/Granny/Model/DivinityMesh.cs index 2e9a0f70..2aa64c10 100644 --- a/LSLib/Granny/Model/DivinityMesh.cs +++ b/LSLib/Granny/Model/DivinityMesh.cs @@ -130,12 +130,12 @@ private static DivinityFormatDesc Make(DivinityVertexUsage usage, DivinityVertex { return new DivinityFormatDesc { - Stream = new SByte[] { 0 }, - Usage = new Byte[] { (byte)usage }, - UsageIndex = new Byte[] { usageIndex }, - RefType = new Byte[] { 0 }, - Format = new Byte[] { (byte)format }, - Size = new Byte[] { size } + Stream = [0], + Usage = [(byte)usage], + UsageIndex = [usageIndex], + RefType = [0], + Format = [(byte)format], + Size = [size] }; } @@ -278,12 +278,12 @@ public static DivinityMeshExtendedData Make() UserDefinedProperties = "", UserMeshProperties = new DivinityMeshProperties { - Flags = new UInt32[] { 0, 0, 0, 0 }, - Lod = new Int32[] { -1 }, + Flags = [0, 0, 0, 0], + Lod = [-1], FormatDescs = null, ExtendedData = null, - LodDistance = new float[] { 3.40282347E+38f }, - IsImpostor = new Int32[] { 0 } + LodDistance = [3.40282347E+38f], + IsImpostor = [0] }, LSMVersion = CurrentLSMVersion }; @@ -336,7 +336,7 @@ public void UpdateFromModelInfo(Mesh mesh, DivinityModelInfoFormat format) else { LSMVersion = 0; - UserMeshProperties.FormatDescs = new List(); + UserMeshProperties.FormatDescs = []; } } } @@ -357,7 +357,7 @@ public static class UserDefinedPropertiesHelpers public static string MeshFlagsToUserDefinedProperties(DivinityModelFlag meshFlags) { - List properties = new List(); + List properties = new(); if (meshFlags.IsRigid()) { properties.Add(UserDefinedProperties_Rigid); diff --git a/LSLib/Granny/Model/Exporter.cs b/LSLib/Granny/Model/Exporter.cs index 00091e97..3418a879 100644 --- a/LSLib/Granny/Model/Exporter.cs +++ b/LSLib/Granny/Model/Exporter.cs @@ -4,19 +4,12 @@ using System.IO; using System.Linq; using LSLib.LS; -using OpenTK; -using Alphaleonis.Win32.Filesystem; -using File = Alphaleonis.Win32.Filesystem.File; using LSLib.LS.Enums; -using System.Numerics; namespace LSLib.Granny.Model { - public class ExportException : Exception + public class ExportException(string message) : Exception(message) { - public ExportException(string message) - : base(message) - { } } public enum ExportFormat @@ -93,7 +86,7 @@ public class ExporterOptions public bool ConformAnimations = true; public bool ConformMeshBoneBindings = true; public bool ConformModels = true; - public Dictionary VertexFormats = new Dictionary(); + public Dictionary VertexFormats = []; // Extended model info format to use when exporting to D:OS public DivinityModelInfoFormat ModelInfoFormat = DivinityModelInfoFormat.None; // Model flags to use when exporting @@ -117,9 +110,9 @@ public class ExporterOptions // See: Spherical Skinning with Dual-Quaternions and QTangents, Crytek R&D public bool EnableQTangents = true; - public List DisabledAnimations = new List(); - public List DisabledModels = new List(); - public List DisabledSkeletons = new List(); + public List DisabledAnimations = []; + public List DisabledModels = []; + public List DisabledSkeletons = []; public void LoadGameSettings(Game game) { @@ -168,9 +161,9 @@ public class Exporter private Root LoadGR2(string inPath) { - var root = new LSLib.Granny.Model.Root(); - FileStream fs = File.Open(inPath, FileMode.Open, System.IO.FileAccess.Read, FileShare.ReadWrite); - var gr2 = new LSLib.Granny.GR2.GR2Reader(fs); + var root = new Root(); + FileStream fs = File.Open(inPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite); + var gr2 = new GR2Reader(fs); gr2.Read(root); root.PostLoad(gr2.Tag); fs.Close(); @@ -180,8 +173,10 @@ private Root LoadGR2(string inPath) private Root LoadDAE(string inPath) { - var importer = new ColladaImporter(); - importer.Options = Options; + var importer = new ColladaImporter + { + Options = Options + }; return importer.Import(inPath); } @@ -203,12 +198,12 @@ private Root Load(string inPath, ExportFormat format) private void SaveGR2(string outPath, Root root) { root.PreSave(); - var writer = new LSLib.Granny.GR2.GR2Writer(); - - writer.Format = Options.Is64Bit ? Magic.Format.LittleEndian64 : Magic.Format.LittleEndian32; - writer.AlternateMagic = Options.AlternateSignature; - writer.VersionTag = Options.VersionTag; - + var writer = new GR2Writer + { + Format = Options.Is64Bit ? Magic.Format.LittleEndian64 : Magic.Format.LittleEndian32, + AlternateMagic = Options.AlternateSignature, + VersionTag = Options.VersionTag + }; if (Options.UseObsoleteVersionTag) { @@ -227,8 +222,10 @@ private void SaveGR2(string outPath, Root root) private void SaveDAE(Root root, ExporterOptions options) { - var exporter = new ColladaExporter(); - exporter.Options = options; + var exporter = new ColladaExporter + { + Options = options + }; exporter.Export(root, options.OutputPath); } @@ -257,17 +254,21 @@ private void GenerateDummySkeleton(Root root) if (model.Skeleton == null) { Utils.Info($"Generating dummy skeleton for model '{model.Name}'"); - var skeleton = new Skeleton(); - skeleton.Name = model.Name; - skeleton.LODType = 1; - skeleton.IsDummy = true; - root.Skeletons.Add(skeleton); + var bone = new Bone + { + Name = model.Name, + ParentIndex = -1, + Transform = new Transform() + }; - var bone = new Bone(); - bone.Name = model.Name; - bone.ParentIndex = -1; - skeleton.Bones = new List { bone }; - bone.Transform = new Transform(); + var skeleton = new Skeleton + { + Name = model.Name, + LODType = 1, + IsDummy = true, + Bones = [bone] + }; + root.Skeletons.Add(skeleton); // TODO: Transform / IWT is not always identity on dummy bones! skeleton.UpdateWorldTransforms(); @@ -280,14 +281,16 @@ private void GenerateDummySkeleton(Root root) throw new ParsingException("Failed to generate dummy skeleton: Mesh already has bone bindings."); } - var binding = new BoneBinding(); - binding.BoneName = bone.Name; - // TODO: Calculate bounding box! - // Use small bounding box values, as it interferes with object placement - // in D:OS 2 (after the Gift Bag 2 update) - binding.OBBMin = new float[] { -0.1f, -0.1f, -0.1f }; - binding.OBBMax = new float[] { 0.1f, 0.1f, 0.1f }; - mesh.Mesh.BoneBindings = new List { binding }; + var binding = new BoneBinding + { + BoneName = bone.Name, + // TODO: Calculate bounding box! + // Use small bounding box values, as it interferes with object placement + // in D:OS 2 (after the Gift Bag 2 update) + OBBMin = [-0.1f, -0.1f, -0.1f], + OBBMax = [0.1f, 0.1f, 0.1f] + }; + mesh.Mesh.BoneBindings = [binding]; } } } @@ -303,11 +306,8 @@ private void ConformAnimationBindPoses(Skeleton skeleton, Skeleton conformToSkel { var track = trackGroup.TransformTracks[i]; var bone = skeleton.GetBoneByName(track.Name); - if(bone == null) - { - //Dummy_Foot -> Dummy_Foot_01 - bone = skeleton.GetBoneByName(track.Name + "_01"); - } + //Dummy_Foot -> Dummy_Foot_01 + bone ??= skeleton.GetBoneByName(track.Name + "_01"); if (bone == null) { @@ -393,9 +393,9 @@ private void ConformSkeletonAnimations(Skeleton skeleton) { foreach (var track in trackGroup.TransformTracks) { - var bone = skeleton.GetBoneByName(track.Name); //Dummy_Foot -> Dummy_Foot_01 - if (bone == null) bone = skeleton.GetBoneByName(track.Name + "_01"); + var bone = skeleton.GetBoneByName(track.Name) ?? skeleton.GetBoneByName(track.Name + "_01"); + if (bone == null) { throw new ExportException($"Animation track references bone '{track.Name}' that cannot be found in the skeleton '{skeleton.Name}'."); @@ -423,15 +423,14 @@ private void ConformSkeletons(IEnumerable skeletons) // Generate a dummy model if there isn't one, otherwise we won't // be able to bind the animations to anything - if (Root.Models == null) - { - Root.Models = new List(); - var model = new Model(); - model.InitialPlacement = new Transform(); - model.Name = skeleton.Name; - model.Skeleton = skeleton; - Root.Models.Add(model); - } + Root.Models ??= [ + new Model + { + InitialPlacement = new Transform(), + Name = skeleton.Name, + Skeleton = skeleton + } + ]; ConformSkeletonAnimations(skeleton); } @@ -453,7 +452,7 @@ private void ConformSkeletons(IEnumerable skeletons) } // Allow name mismatches if there is only 1 skeleton in each file - if (conformingSkel == null && skeletons.Count() == 1 && Root.Skeletons.Count() == 1) + if (conformingSkel == null && skeletons.Count() == 1 && Root.Skeletons.Count == 1) { conformingSkel = skeletons.First(); } @@ -469,10 +468,7 @@ private void ConformSkeletons(IEnumerable skeletons) private void ConformMeshBoneBindings(Mesh mesh, Mesh conformToMesh) { - if (mesh.BoneBindings == null) - { - mesh.BoneBindings = new List(); - } + mesh.BoneBindings ??= []; foreach (var conformBone in conformToMesh.BoneBindings) { @@ -489,8 +485,10 @@ private void ConformMeshBoneBindings(Mesh mesh, Mesh conformToMesh) if (inputBone == null) { // Create a new "dummy" binding if it does not exist in the new mesh - inputBone = new BoneBinding(); - inputBone.BoneName = conformBone.BoneName; + inputBone = new BoneBinding + { + BoneName = conformBone.BoneName + }; mesh.BoneBindings.Add(inputBone); } @@ -533,30 +531,35 @@ private Mesh GenerateDummyMesh(MeshBinding meshBinding) var vertexData = new VertexData(); vertexData.VertexComponentNames = meshBinding.Mesh.PrimaryVertexData.VertexComponentNames .Select(name => new GrannyString(name.String)).ToList(); - vertexData.Vertices = new List(); + vertexData.Vertices = []; var dummyVertex = meshBinding.Mesh.VertexFormat.CreateInstance(); vertexData.Vertices.Add(dummyVertex); Root.VertexDatas.Add(vertexData); - var topology = new TriTopology(); - topology.Groups = new List(); - var group = new TriTopologyGroup(); - group.MaterialIndex = 0; - group.TriCount = 0; - group.TriFirst = 0; - topology.Groups.Add(group); - - topology.Indices = new List(); + var topology = new TriTopology + { + Groups = [ + new TriTopologyGroup + { + MaterialIndex = 0, + TriCount = 0, + TriFirst = 0 + } + ], + Indices = [] + }; Root.TriTopologies.Add(topology); - var mesh = new Mesh(); - mesh.Name = meshBinding.Mesh.Name; - mesh.VertexFormat = meshBinding.Mesh.VertexFormat; - mesh.PrimaryTopology = topology; - mesh.PrimaryVertexData = vertexData; + var mesh = new Mesh + { + Name = meshBinding.Mesh.Name, + VertexFormat = meshBinding.Mesh.VertexFormat, + PrimaryTopology = topology, + PrimaryVertexData = vertexData + }; if (meshBinding.Mesh.BoneBindings != null) { - mesh.BoneBindings = new List(); + mesh.BoneBindings = []; ConformMeshBoneBindings(mesh, meshBinding.Mesh); } @@ -565,9 +568,11 @@ private Mesh GenerateDummyMesh(MeshBinding meshBinding) private Model MakeDummyModel(Model original) { - var newModel = new Model(); - newModel.InitialPlacement = original.InitialPlacement; - newModel.Name = original.Name; + var newModel = new Model + { + InitialPlacement = original.InitialPlacement, + Name = original.Name + }; if (original.Skeleton != null) { @@ -582,7 +587,7 @@ private Model MakeDummyModel(Model original) if (original.MeshBindings != null) { - newModel.MeshBindings = new List(); + newModel.MeshBindings = []; foreach (var meshBinding in original.MeshBindings) { // Try to bind the original mesh, if it exists in the source file. @@ -594,8 +599,10 @@ private Model MakeDummyModel(Model original) Root.Meshes.Add(mesh); } - var binding = new MeshBinding(); - binding.Mesh = mesh; + var binding = new MeshBinding + { + Mesh = mesh + }; newModel.MeshBindings.Add(binding); } } @@ -614,7 +621,7 @@ private void ConformModels(IEnumerable models) // Rebuild the model list to match the order used in the original GR2 // If a model is missing, generate a dummy model & mesh. var originalModels = Root.Models; - Root.Models = new List(); + Root.Models = []; foreach (var model in models) { diff --git a/LSLib/Granny/Model/Mesh.cs b/LSLib/Granny/Model/Mesh.cs index 621184af..790afc91 100644 --- a/LSLib/Granny/Model/Mesh.cs +++ b/LSLib/Granny/Model/Mesh.cs @@ -2,22 +2,16 @@ using System.Collections.Generic; using System.Linq; using System.Text; -using System.Reflection; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; namespace LSLib.Granny.Model { - public class Deduplicator + public class Deduplicator(IEqualityComparer comparer) { - private IEqualityComparer Comparer; - public Dictionary DeduplicationMap = new Dictionary(); - public List Uniques = new List(); - - public Deduplicator(IEqualityComparer comparer) - { - Comparer = comparer; - } + private readonly IEqualityComparer Comparer = comparer; + public Dictionary DeduplicationMap = []; + public List Uniques = []; public void MakeIdentityMapping(IEnumerable items) { @@ -36,8 +30,7 @@ public void Deduplicate(IEnumerable items) var i = 0; foreach (var item in items) { - int mappedIndex; - if (!uniqueItems.TryGetValue(item, out mappedIndex)) + if (!uniqueItems.TryGetValue(item, out int mappedIndex)) { mappedIndex = uniqueItems.Count; uniqueItems.Add(item, mappedIndex); @@ -84,14 +77,14 @@ public override int GetHashCode() public class VertexDeduplicator { - public Deduplicator Vertices = new Deduplicator(new GenericEqualityComparer()); - public Deduplicator Normals = new Deduplicator(new GenericEqualityComparer()); - public List> UVs = new List>(); - public List> Colors = new List>(); + public Deduplicator Vertices = new(new GenericEqualityComparer()); + public Deduplicator Normals = new(new GenericEqualityComparer()); + public List> UVs = []; + public List> Colors = []; public void MakeIdentityMapping(List vertices) { - if (vertices.Count() == 0) return; + if (vertices.Count == 0) return; var format = vertices[0].Format; @@ -127,7 +120,7 @@ public void MakeIdentityMapping(List vertices) public void Deduplicate(List vertices) { - if (vertices.Count() == 0) return; + if (vertices.Count == 0) return; var format = vertices[0].Format; @@ -176,9 +169,9 @@ public class VertexDataSectionSelector : SectionSelector { public SectionType SelectSection(MemberDefinition member, Type type, object obj) { - if (obj is VertexData) + if (obj is VertexData data) { - return ((VertexData)obj).SerializationSection; + return data.SerializationSection; } else { @@ -206,7 +199,7 @@ public void PostLoad() // Fix missing vertex component names if (VertexComponentNames == null) { - VertexComponentNames = new List(); + VertexComponentNames = []; if (Vertices.Count > 0) { var components = Vertices[0].Format.ComponentNames(); @@ -250,7 +243,7 @@ public source MakeColladaPositions(string name) positions[index++] = pos[2]; } - return ColladaUtils.MakeFloatSource(name, "positions", new string[] { "X", "Y", "Z" }, positions); + return ColladaUtils.MakeFloatSource(name, "positions", ["X", "Y", "Z"], positions); } public source MakeColladaNormals(string name) @@ -267,7 +260,7 @@ public source MakeColladaNormals(string name) normals[index++] = normal[2]; } - return ColladaUtils.MakeFloatSource(name, "normals", new string[] { "X", "Y", "Z" }, normals); + return ColladaUtils.MakeFloatSource(name, "normals", ["X", "Y", "Z"], normals); } public source MakeColladaTangents(string name) @@ -284,7 +277,7 @@ public source MakeColladaTangents(string name) tangents[index++] = tangent[2]; } - return ColladaUtils.MakeFloatSource(name, "tangents", new string[] { "X", "Y", "Z" }, tangents); + return ColladaUtils.MakeFloatSource(name, "tangents", ["X", "Y", "Z"], tangents); } public source MakeColladaBinormals(string name) @@ -301,7 +294,7 @@ public source MakeColladaBinormals(string name) binormals[index++] = binormal[2]; } - return ColladaUtils.MakeFloatSource(name, "binormals", new string[] { "X", "Y", "Z" }, binormals); + return ColladaUtils.MakeFloatSource(name, "binormals", ["X", "Y", "Z"], binormals); } public source MakeColladaUVs(string name, int uvIndex, bool flip) @@ -319,7 +312,7 @@ public source MakeColladaUVs(string name, int uvIndex, bool flip) uvs[index++] = uv[1]; } - return ColladaUtils.MakeFloatSource(name, "uvs" + uvIndex.ToString(), new string[] { "S", "T" }, uvs); + return ColladaUtils.MakeFloatSource(name, "uvs" + uvIndex.ToString(), ["S", "T"], uvs); } public source MakeColladaColors(string name, int setIndex) @@ -335,7 +328,7 @@ public source MakeColladaColors(string name, int setIndex) colors[index++] = color[2]; } - return ColladaUtils.MakeFloatSource(name, "colors" + setIndex.ToString(), new string[] { "R", "G", "B" }, colors); + return ColladaUtils.MakeFloatSource(name, "colors" + setIndex.ToString(), ["R", "G", "B"], colors); } public source MakeBoneWeights(string name) @@ -353,7 +346,7 @@ public source MakeBoneWeights(string name) } } - return ColladaUtils.MakeFloatSource(name, "weights", new string[] { "WEIGHT" }, weights.ToArray()); + return ColladaUtils.MakeFloatSource(name, "weights", ["WEIGHT"], weights.ToArray()); } public void Transform(Matrix4 transformation) @@ -514,11 +507,13 @@ public triangles MakeColladaTriangles(InputLocalOffset[] inputs, int numTris = (from grp in Groups select grp.TriCount).Sum(); - var tris = new triangles(); - tris.count = (ulong)numTris; - tris.input = inputs; + var tris = new triangles + { + count = (ulong)numTris, + input = inputs + }; - List> inputMaps = new List>(); + List> inputMaps = []; int uvIndex = 0, colorIndex = 0; for (int i = 0; i < inputs.Length; i++) { diff --git a/LSLib/Granny/Model/Root.cs b/LSLib/Granny/Model/Root.cs index 09b1cc0a..e8c44a03 100644 --- a/LSLib/Granny/Model/Root.cs +++ b/LSLib/Granny/Model/Root.cs @@ -2,7 +2,7 @@ using System.Collections.Generic; using System.Linq; using LSLib.Granny.GR2; -using OpenTK; +using OpenTK.Mathematics; namespace LSLib.Granny.Model { @@ -71,10 +71,7 @@ public void ConvertToYUp(bool transformSkeletons) TransformSkeletons(transform); } - if (ArtToolInfo != null) - { - ArtToolInfo.SetYUp(); - } + ArtToolInfo?.SetYUp(); ZUp = false; } @@ -125,10 +122,7 @@ public void PostLoad(UInt32 tag) triTopology.PostLoad(); } - if (Meshes != null) - { - Meshes.ForEach(m => m.PostLoad()); - } + Meshes?.ForEach(m => m.PostLoad()); var modelIndex = 0; foreach (var model in Models ?? Enumerable.Empty()) diff --git a/LSLib/Granny/Model/Skeleton.cs b/LSLib/Granny/Model/Skeleton.cs index c97da639..0ad614f4 100644 --- a/LSLib/Granny/Model/Skeleton.cs +++ b/LSLib/Granny/Model/Skeleton.cs @@ -1,11 +1,9 @@ using System; using System.Collections.Generic; using System.Linq; -using OpenTK; +using OpenTK.Mathematics; using LSLib.Granny.GR2; using System.Xml; -using LSLib.LS.Story; -using System.Reflection; namespace LSLib.Granny.Model { @@ -51,12 +49,12 @@ public void UpdateWorldTransforms(List bones) } var iwt = WorldTransform.Inverted(); - InverseWorldTransform = new float[] { + InverseWorldTransform = [ iwt[0, 0], iwt[0, 1], iwt[0, 2], iwt[0, 3], iwt[1, 0], iwt[1, 1], iwt[1, 2], iwt[1, 3], iwt[2, 0], iwt[2, 1], iwt[2, 2], iwt[2, 3], iwt[3, 0], iwt[3, 1], iwt[3, 2], iwt[3, 3] - }; + ]; } private void ImportLSLibProfile(node node) @@ -83,21 +81,25 @@ private void ImportLSLibProfile(node node) public static Bone FromCollada(node bone, int parentIndex, List bones, Dictionary boneSIDs, Dictionary boneIDs) { var transMat = ColladaHelpers.TransformFromNode(bone); - var colladaBone = new Bone(); - colladaBone.TransformSID = transMat.TransformSID; var myIndex = bones.Count; - bones.Add(colladaBone); - boneSIDs.Add(bone.sid, colladaBone); + var colladaBone = new Bone + { + TransformSID = transMat.TransformSID, + ParentIndex = parentIndex, + Name = bone.name, + LODError = 0, // TODO + OriginalTransform = transMat.transform, + Transform = Transform.FromMatrix4(transMat.transform) + }; + if (bone.id != null) { boneIDs.Add(bone.id, colladaBone); } - colladaBone.ParentIndex = parentIndex; - colladaBone.Name = bone.name; - colladaBone.LODError = 0; // TODO - colladaBone.OriginalTransform = transMat.transform; - colladaBone.Transform = Transform.FromMatrix4(transMat.transform); + bones.Add(colladaBone); + boneSIDs.Add(bone.sid, colladaBone); + colladaBone.UpdateWorldTransforms(bones); colladaBone.ImportLSLibProfile(bone); @@ -131,43 +133,41 @@ private technique ExportLSLibProfile(XmlDocument Xml) public node MakeCollada(XmlDocument Xml) { - var node = new node(); - node.id = "Bone_" + Name.Replace(' ', '_'); - node.name = Name; // .Replace(' ', '_'); - node.sid = Name.Replace(' ', '_'); - node.type = NodeType.JOINT; - - var transforms = new List(); - var transformTypes = new List(); - - var transform = new matrix(); - transform.sid = "Transform"; var mat = Transform.ToMatrix4(); mat.Transpose(); - transform.Values = new double[] { - mat[0, 0], mat[0, 1], mat[0, 2], mat[0, 3], - mat[1, 0], mat[1, 1], mat[1, 2], mat[1, 3], - mat[2, 0], mat[2, 1], mat[2, 2], mat[2, 3], - mat[3, 0], mat[3, 1], mat[3, 2], mat[3, 3] - }; - transforms.Add(transform); - transformTypes.Add(ItemsChoiceType2.matrix); - - node.Items = transforms.ToArray(); - node.ItemsElementName = transformTypes.ToArray(); - node.extra = new extra[] + return new node { - new extra - { - technique = new technique[] + id = "Bone_" + Name.Replace(' ', '_'), + name = Name, // .Replace(' ', '_'); + sid = Name.Replace(' ', '_'), + type = NodeType.JOINT, + + Items = [ + new matrix { - ExportLSLibProfile(Xml) + sid = "Transform", + Values = [ + mat[0, 0], mat[0, 1], mat[0, 2], mat[0, 3], + mat[1, 0], mat[1, 1], mat[1, 2], mat[1, 3], + mat[2, 0], mat[2, 1], mat[2, 2], mat[2, 3], + mat[3, 0], mat[3, 1], mat[3, 2], mat[3, 3] + ] } - } - }; + ], + ItemsElementName = [ItemsChoiceType2.matrix], - return node; + extra = + [ + new extra + { + technique = + [ + ExportLSLibProfile(Xml) + ] + } + ] + }; } } @@ -190,12 +190,14 @@ public class Skeleton public static Skeleton FromCollada(node root) { - var skeleton = new Skeleton(); - skeleton.Bones = new List(); - skeleton.LODType = 1; - skeleton.Name = root.name; - skeleton.BonesBySID = new Dictionary(); - skeleton.BonesByID = new Dictionary(); + var skeleton = new Skeleton + { + Bones = [], + LODType = 1, + Name = root.name, + BonesBySID = [], + BonesByID = [] + }; Bone.FromCollada(root, -1, skeleton.Bones, skeleton.BonesBySID, skeleton.BonesByID); return skeleton; } diff --git a/LSLib/Granny/Model/Vertex.cs b/LSLib/Granny/Model/Vertex.cs index 8d073e0e..15840380 100644 --- a/LSLib/Granny/Model/Vertex.cs +++ b/LSLib/Granny/Model/Vertex.cs @@ -1,5 +1,5 @@ using LSLib.Granny.GR2; -using OpenTK; +using OpenTK.Mathematics; using System; using System.Collections.Generic; @@ -312,16 +312,16 @@ protected Vertex() { } public Vector2 GetUV(int index) { - switch (index) + return index switch { - case 0: return TextureCoordinates0; - case 1: return TextureCoordinates1; - case 2: return TextureCoordinates2; - case 3: return TextureCoordinates3; - case 4: return TextureCoordinates4; - case 5: return TextureCoordinates5; - default: throw new ArgumentException($"At most {MaxUVs} UVs are supported."); - } + 0 => TextureCoordinates0, + 1 => TextureCoordinates1, + 2 => TextureCoordinates2, + 3 => TextureCoordinates3, + 4 => TextureCoordinates4, + 5 => TextureCoordinates5, + _ => throw new ArgumentException($"At most {MaxUVs} UVs are supported."), + }; } public void SetUV(int index, Vector2 uv) @@ -340,12 +340,12 @@ public void SetUV(int index, Vector2 uv) public Vector4 GetColor(int index) { - switch (index) + return index switch { - case 0: return Color0; - case 1: return Color1; - default: throw new ArgumentException($"At most {MaxColors} color maps are supported."); - } + 0 => Color0, + 1 => Color1, + _ => throw new ArgumentException($"At most {MaxColors} color maps are supported."), + }; } public void SetColor(int index, Vector4 color) @@ -590,8 +590,7 @@ public Vertex ReadVertex(GR2Reader reader, VertexDescriptor descriptor) public object Read(GR2Reader gr2, StructDefinition definition, MemberDefinition member, uint arraySize, object parent) { - VertexDescriptor descriptor; - if (!VertexTypeCache.TryGetValue(parent, out descriptor)) + if (!VertexTypeCache.TryGetValue(parent, out VertexDescriptor descriptor)) { descriptor = ConstructDescriptor(member, definition, parent); VertexTypeCache.Add(parent, descriptor); diff --git a/LSLib/Granny/Model/VertexSerialization.cs b/LSLib/Granny/Model/VertexSerialization.cs index bba43d3e..543b6d23 100644 --- a/LSLib/Granny/Model/VertexSerialization.cs +++ b/LSLib/Granny/Model/VertexSerialization.cs @@ -1,5 +1,5 @@ using LSLib.Granny.GR2; -using OpenTK; +using OpenTK.Mathematics; using System; using System.Collections.Generic; using System.Reflection; @@ -55,12 +55,13 @@ public static Vector3 ReadHalfVector4As3(GR2Reader reader) public static Quaternion ReadBinormalShortVector4(GR2Reader reader) { - Quaternion v = new Quaternion(); - v.X = reader.Reader.ReadInt16() / 32767.0f; - v.Y = reader.Reader.ReadInt16() / 32767.0f; - v.Z = reader.Reader.ReadInt16() / 32767.0f; - v.W = reader.Reader.ReadInt16() / 32767.0f; - return v; + return new Quaternion + { + X = reader.Reader.ReadInt16() / 32767.0f, + Y = reader.Reader.ReadInt16() / 32767.0f, + Z = reader.Reader.ReadInt16() / 32767.0f, + W = reader.Reader.ReadInt16() / 32767.0f + }; } public static Vector4 ReadVector4(GR2Reader reader) @@ -444,14 +445,12 @@ public static void Unserialize(GR2Reader reader, Vertex v) { for (var i = 0; i < d.ColorMaps; i++) { - Vector4 color; - switch (d.ColorMapType) + var color = d.ColorMapType switch { - case ColorMapType.Float4: color = ReadVector4(reader); break; - case ColorMapType.Byte4: color = ReadNormalByteVector4(reader); break; - default: throw new Exception($"Cannot unserialize color map: Unsupported format {d.ColorMapType}"); - } - + ColorMapType.Float4 => ReadVector4(reader), + ColorMapType.Byte4 => ReadNormalByteVector4(reader), + _ => throw new Exception($"Cannot unserialize color map: Unsupported format {d.ColorMapType}"), + }; v.SetColor(i, color); } } @@ -460,14 +459,12 @@ public static void Unserialize(GR2Reader reader, Vertex v) { for (var i = 0; i < d.TextureCoordinates; i++) { - Vector2 uv; - switch (d.TextureCoordinateType) + var uv = d.TextureCoordinateType switch { - case TextureCoordinateType.Float2: uv = ReadVector2(reader); break; - case TextureCoordinateType.Half2: uv = ReadHalfVector2(reader); break; - default: throw new Exception($"Cannot unserialize UV map: Unsupported format {d.TextureCoordinateType}"); - } - + TextureCoordinateType.Float2 => ReadVector2(reader), + TextureCoordinateType.Half2 => ReadHalfVector2(reader), + _ => throw new Exception($"Cannot unserialize UV map: Unsupported format {d.TextureCoordinateType}"), + }; v.SetUV(i, uv); } } @@ -486,8 +483,8 @@ private static ModuleBuilder GetModuleBuilder() } var an = new AssemblyName("VertexFactoryAssembly"); - AssemblyBuilder assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); - ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule("VertexFactoryClasses"); + var assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); + var moduleBuilder = assemblyBuilder.DefineDynamicModule("VertexFactoryClasses"); ModBuilder = moduleBuilder; return ModBuilder; } @@ -530,7 +527,7 @@ private void AddMember(StructDefinition defn, String name, MemberType type, UInt GrannyName = name, Definition = null, ArraySize = arraySize, - Extra = new UInt32[] { 0, 0, 0 }, + Extra = [0, 0, 0], Unknown = 0 }; defn.Members.Add(member); @@ -541,7 +538,7 @@ public StructDefinition CreateStructDefinition(object instance) var desc = (instance as Vertex).Format; var defn = new StructDefinition { - Members = new List(), + Members = [], MixedMarshal = true, Type = typeof(Vertex) }; diff --git a/LSLib/LS/BinUtils.cs b/LSLib/LS/BinUtils.cs index 9cfd04db..ceb30d6e 100644 --- a/LSLib/LS/BinUtils.cs +++ b/LSLib/LS/BinUtils.cs @@ -1,9 +1,9 @@ -using zlib; -using LZ4; +using LZ4; using System; using System.IO; using System.Runtime.InteropServices; using LSLib.LS.Enums; +using System.IO.Compression; namespace LSLib.LS { @@ -270,41 +270,27 @@ public static void WriteAttribute(BinaryWriter writer, NodeAttribute attr) public static CompressionMethod CompressionFlagsToMethod(byte flags) { - switch (flags & 0x0f) + return (flags & 0x0f) switch { - case (int)CompressionMethod.None: - return CompressionMethod.None; - - case (int)CompressionMethod.Zlib: - return CompressionMethod.Zlib; - - case (int)CompressionMethod.LZ4: - return CompressionMethod.LZ4; - - default: - throw new ArgumentException("Invalid compression method"); - } + (int)CompressionMethod.None => CompressionMethod.None, + (int)CompressionMethod.Zlib => CompressionMethod.Zlib, + (int)CompressionMethod.LZ4 => CompressionMethod.LZ4, + _ => throw new ArgumentException("Invalid compression method") + }; } - public static CompressionLevel CompressionFlagsToLevel(byte flags) + public static LSCompressionLevel CompressionFlagsToLevel(byte flags) { - switch (flags & 0xf0) + return (flags & 0xf0) switch { - case (int)CompressionFlags.FastCompress: - return CompressionLevel.FastCompression; - - case (int)CompressionFlags.DefaultCompress: - return CompressionLevel.DefaultCompression; - - case (int)CompressionFlags.MaxCompressionLevel: - return CompressionLevel.MaxCompression; - - default: - throw new ArgumentException("Invalid compression flags"); - } + (int)CompressionFlags.FastCompress => LSCompressionLevel.FastCompression, + (int)CompressionFlags.DefaultCompress => LSCompressionLevel.DefaultCompression, + (int)CompressionFlags.MaxCompressionLevel => LSCompressionLevel.MaxCompression, + _ => throw new ArgumentException("Invalid compression flags") + }; } - public static byte MakeCompressionFlags(CompressionMethod method, CompressionLevel level) + public static byte MakeCompressionFlags(CompressionMethod method, LSCompressionLevel level) { if (method == CompressionMethod.None) { @@ -317,11 +303,11 @@ public static byte MakeCompressionFlags(CompressionMethod method, CompressionLev else if (method == CompressionMethod.LZ4) flags = 0x2; - if (level == CompressionLevel.FastCompression) + if (level == LSCompressionLevel.FastCompression) flags |= 0x10; - else if (level == CompressionLevel.DefaultCompression) + else if (level == LSCompressionLevel.DefaultCompression) flags |= 0x20; - else if (level == CompressionLevel.MaxCompression) + else if (level == LSCompressionLevel.MaxCompression) flags |= 0x40; return flags; @@ -329,7 +315,7 @@ public static byte MakeCompressionFlags(CompressionMethod method, CompressionLev public static byte[] Decompress(byte[] compressed, int decompressedSize, byte compressionFlags, bool chunked = false) { - switch ((CompressionMethod)(compressionFlags & 0x0F)) + switch (CompressionFlagsToMethod(compressionFlags)) { case CompressionMethod.None: return compressed; @@ -338,11 +324,11 @@ public static byte[] Decompress(byte[] compressed, int decompressedSize, byte co { using (var compressedStream = new MemoryStream(compressed)) using (var decompressedStream = new MemoryStream()) - using (var stream = new ZInputStream(compressedStream)) + using (var stream = new ZLibStream(compressedStream, CompressionMode.Decompress)) { byte[] buf = new byte[0x10000]; int length = 0; - while ((length = stream.read(buf, 0, buf.Length)) > 0) + while ((length = stream.Read(buf, 0, buf.Length)) > 0) { decompressedStream.Write(buf, 0, length); } @@ -377,58 +363,42 @@ public static byte[] Compress(byte[] uncompressed, byte compressionFlags) return Compress(uncompressed, (CompressionMethod)(compressionFlags & 0x0F), CompressionFlagsToLevel(compressionFlags)); } - public static byte[] Compress(byte[] uncompressed, CompressionMethod method, CompressionLevel compressionLevel, bool chunked = false) + public static byte[] Compress(byte[] uncompressed, CompressionMethod method, LSCompressionLevel compressionLevel, bool chunked = false) { - switch (method) + return method switch { - case CompressionMethod.None: - return uncompressed; - - case CompressionMethod.Zlib: - return CompressZlib(uncompressed, compressionLevel); - - case CompressionMethod.LZ4: - return CompressLZ4(uncompressed, compressionLevel, chunked); - - default: - throw new ArgumentException("Invalid compression method specified"); - } + CompressionMethod.None => uncompressed, + CompressionMethod.Zlib => CompressZlib(uncompressed, compressionLevel), + CompressionMethod.LZ4 => CompressLZ4(uncompressed, compressionLevel, chunked), + _ => throw new ArgumentException("Invalid compression method specified") + }; } - public static byte[] CompressZlib(byte[] uncompressed, CompressionLevel compressionLevel) + public static byte[] CompressZlib(byte[] uncompressed, LSCompressionLevel compressionLevel) { - int level = zlib.zlibConst.Z_DEFAULT_COMPRESSION; - switch (compressionLevel) + var level = compressionLevel switch { - case CompressionLevel.FastCompression: - level = zlib.zlibConst.Z_BEST_SPEED; - break; - - case CompressionLevel.DefaultCompression: - level = zlib.zlibConst.Z_DEFAULT_COMPRESSION; - break; - - case CompressionLevel.MaxCompression: - level = zlib.zlibConst.Z_BEST_COMPRESSION; - break; - } - - using (var outputStream = new MemoryStream()) - using (var compressor = new ZOutputStream(outputStream, level)) - { - compressor.Write(uncompressed, 0, uncompressed.Length); - compressor.finish(); - return outputStream.ToArray(); - } + LSCompressionLevel.FastCompression => CompressionLevel.Fastest, + LSCompressionLevel.DefaultCompression => CompressionLevel.Optimal, + LSCompressionLevel.MaxCompression => CompressionLevel.SmallestSize, + _ => throw new ArgumentException() + }; + + using var outputStream = new MemoryStream(); + using var compressor = new ZLibStream(outputStream, level); + + compressor.Write(uncompressed, 0, uncompressed.Length); + compressor.Flush(); + return outputStream.ToArray(); } - public static byte[] CompressLZ4(byte[] uncompressed, CompressionLevel compressionLevel, bool chunked = false) + public static byte[] CompressLZ4(byte[] uncompressed, LSCompressionLevel compressionLevel, bool chunked = false) { if (chunked) { return Native.LZ4FrameCompressor.Compress(uncompressed); } - else if (compressionLevel == CompressionLevel.FastCompression) + else if (compressionLevel == LSCompressionLevel.FastCompression) { return LZ4Codec.Encode(uncompressed, 0, uncompressed.Length); } diff --git a/LSLib/LS/Common.cs b/LSLib/LS/Common.cs index 90349980..a3c59c04 100644 --- a/LSLib/LS/Common.cs +++ b/LSLib/LS/Common.cs @@ -7,9 +7,9 @@ public static class Common { public const int MajorVersion = 1; - public const int MinorVersion = 18; + public const int MinorVersion = 19; - public const int PatchVersion = 7; + public const int PatchVersion = 0; // Version of LSTools profile data in generated DAE files public const int ColladaMetadataVersion = 3; diff --git a/LSLib/LS/Enums/CompressionLevel.cs b/LSLib/LS/Enums/CompressionLevel.cs index 81684d7d..0119e48a 100644 --- a/LSLib/LS/Enums/CompressionLevel.cs +++ b/LSLib/LS/Enums/CompressionLevel.cs @@ -1,6 +1,6 @@ namespace LSLib.LS.Enums { - public enum CompressionLevel + public enum LSCompressionLevel { FastCompression, DefaultCompression, diff --git a/LSLib/LS/FileManager.cs b/LSLib/LS/FileManager.cs index d5877e39..478a2692 100644 --- a/LSLib/LS/FileManager.cs +++ b/LSLib/LS/FileManager.cs @@ -1,5 +1,5 @@ using System; -using Alphaleonis.Win32.Filesystem; +using System.IO; namespace LSLib.LS { diff --git a/LSLib/LS/Localization.cs b/LSLib/LS/Localization.cs index cdcccec1..a2a2a550 100644 --- a/LSLib/LS/Localization.cs +++ b/LSLib/LS/Localization.cs @@ -1,15 +1,9 @@ using System; using System.IO; -using System.Linq; using System.Runtime.InteropServices; using System.Text; -using LZ4; -using File = Alphaleonis.Win32.Filesystem.File; -using LSLib.LS.Enums; using System.Collections.Generic; -using LSLib.Granny; using System.Xml; -using System.Diagnostics; namespace LSLib.LS { @@ -67,14 +61,9 @@ public class LocaResource } - public class LocaReader : IDisposable + public class LocaReader(Stream stream) : IDisposable { - private Stream Stream; - - public LocaReader(Stream stream) - { - this.Stream = stream; - } + private readonly Stream Stream = stream; public void Dispose() { @@ -83,95 +72,82 @@ public void Dispose() public LocaResource Read() { - using (var reader = new BinaryReader(Stream)) + using var reader = new BinaryReader(Stream); + var loca = new LocaResource { - var loca = new LocaResource - { - Entries = new List() - }; - var header = BinUtils.ReadStruct(reader); + Entries = [] + }; + var header = BinUtils.ReadStruct(reader); - if (header.Signature != (ulong)LocaHeader.DefaultSignature) - { - throw new InvalidDataException("Incorrect signature in localization file"); - } + if (header.Signature != (ulong)LocaHeader.DefaultSignature) + { + throw new InvalidDataException("Incorrect signature in localization file"); + } - var entries = new LocaEntry[header.NumEntries]; - BinUtils.ReadStructs(reader, entries); + var entries = new LocaEntry[header.NumEntries]; + BinUtils.ReadStructs(reader, entries); - Stream.Position = header.TextsOffset; - foreach (var entry in entries) + Stream.Position = header.TextsOffset; + foreach (var entry in entries) + { + var text = Encoding.UTF8.GetString(reader.ReadBytes((int)entry.Length - 1)); + loca.Entries.Add(new LocalizedText { - var text = Encoding.UTF8.GetString(reader.ReadBytes((int)entry.Length - 1)); - loca.Entries.Add(new LocalizedText - { - Key = entry.KeyString, - Version = entry.Version, - Text = text - }); - reader.ReadByte(); - } - - return loca; + Key = entry.KeyString, + Version = entry.Version, + Text = text + }); + reader.ReadByte(); } + + return loca; } } - public class LocaWriter + public class LocaWriter(Stream stream) { - private Stream stream; - - public LocaWriter(Stream stream) - { - this.stream = stream; - } + private readonly Stream stream = stream; public void Write(LocaResource res) { - using (var writer = new BinaryWriter(stream)) + using var writer = new BinaryWriter(stream); + var header = new LocaHeader { - var header = new LocaHeader { - Signature = LocaHeader.DefaultSignature, - NumEntries = (uint)res.Entries.Count, - TextsOffset = (uint)(Marshal.SizeOf(typeof(LocaHeader)) + Marshal.SizeOf(typeof(LocaEntry)) * res.Entries.Count) - }; - BinUtils.WriteStruct(writer, ref header); + Signature = LocaHeader.DefaultSignature, + NumEntries = (uint)res.Entries.Count, + TextsOffset = (uint)(Marshal.SizeOf(typeof(LocaHeader)) + Marshal.SizeOf(typeof(LocaEntry)) * res.Entries.Count) + }; + BinUtils.WriteStruct(writer, ref header); - var entries = new LocaEntry[header.NumEntries]; - for (var i = 0; i < entries.Length; i++) + var entries = new LocaEntry[header.NumEntries]; + for (var i = 0; i < entries.Length; i++) + { + var entry = res.Entries[i]; + entries[i] = new LocaEntry { - var entry = res.Entries[i]; - entries[i] = new LocaEntry - { - KeyString = entry.Key, - Version = entry.Version, - Length = (uint)Encoding.UTF8.GetByteCount(entry.Text) + 1 - }; - } + KeyString = entry.Key, + Version = entry.Version, + Length = (uint)Encoding.UTF8.GetByteCount(entry.Text) + 1 + }; + } - BinUtils.WriteStructs(writer, entries); + BinUtils.WriteStructs(writer, entries); - foreach (var entry in res.Entries) - { - var bin = Encoding.UTF8.GetBytes(entry.Text); - writer.Write(bin); - writer.Write((Byte)0); - } + foreach (var entry in res.Entries) + { + var bin = Encoding.UTF8.GetBytes(entry.Text); + writer.Write(bin); + writer.Write((Byte)0); } } } - public class LocaXmlReader : IDisposable + public class LocaXmlReader(Stream stream) : IDisposable { - private Stream stream; + private readonly Stream stream = stream; private XmlReader reader; private LocaResource resource; - public LocaXmlReader(Stream stream) - { - this.stream = stream; - } - public void Dispose() { stream.Dispose(); @@ -207,7 +183,7 @@ public LocaResource Read() { resource = new LocaResource { - Entries = new List() + Entries = [] }; using (this.reader = XmlReader.Create(stream)) @@ -226,38 +202,32 @@ public LocaResource Read() } - public class LocaXmlWriter + public class LocaXmlWriter(Stream stream) { - private Stream stream; - private XmlWriter writer; - - public LocaXmlWriter(Stream stream) - { - this.stream = stream; - } + private readonly Stream stream = stream; public void Write(LocaResource res) { - var settings = new XmlWriterSettings(); - settings.Indent = true; - settings.IndentChars = "\t"; - - using (this.writer = XmlWriter.Create(stream, settings)) + var settings = new XmlWriterSettings { - writer.WriteStartElement("contentList"); + Indent = true, + IndentChars = "\t" + }; - foreach (var entry in res.Entries) - { - writer.WriteStartElement("content"); - writer.WriteAttributeString("contentuid", entry.Key); - writer.WriteAttributeString("version", entry.Version.ToString()); - writer.WriteString(entry.Text); - writer.WriteEndElement(); - } + using var writer = XmlWriter.Create(stream, settings); + writer.WriteStartElement("contentList"); + foreach (var entry in res.Entries) + { + writer.WriteStartElement("content"); + writer.WriteAttributeString("contentuid", entry.Key); + writer.WriteAttributeString("version", entry.Version.ToString()); + writer.WriteString(entry.Text); writer.WriteEndElement(); - writer.Flush(); } + + writer.WriteEndElement(); + writer.Flush(); } } @@ -273,17 +243,12 @@ public static LocaFormat ExtensionToFileFormat(string path) { var extension = Path.GetExtension(path).ToLower(); - switch (extension) + return extension switch { - case ".loca": - return LocaFormat.Loca; - - case ".xml": - return LocaFormat.Xml; - - default: - throw new ArgumentException("Unrecognized file extension: " + extension); - } + ".loca" => LocaFormat.Loca, + ".xml" => LocaFormat.Xml, + _ => throw new ArgumentException("Unrecognized file extension: " + extension), + }; } public static LocaResource Load(string inputPath) @@ -293,10 +258,8 @@ public static LocaResource Load(string inputPath) public static LocaResource Load(string inputPath, LocaFormat format) { - using (var stream = File.Open(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return Load(stream, format); - } + using var stream = File.Open(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read); + return Load(stream, format); } public static LocaResource Load(Stream stream, LocaFormat format) @@ -305,18 +268,14 @@ public static LocaResource Load(Stream stream, LocaFormat format) { case LocaFormat.Loca: { - using (var reader = new LocaReader(stream)) - { - return reader.Read(); - } + using var reader = new LocaReader(stream); + return reader.Read(); } case LocaFormat.Xml: { - using (var reader = new LocaXmlReader(stream)) - { - return reader.Read(); - } + using var reader = new LocaXmlReader(stream); + return reader.Read(); } default: @@ -333,27 +292,25 @@ public static void Save(LocaResource resource, string outputPath, LocaFormat for { FileManager.TryToCreateDirectory(outputPath); - using (var file = File.Open(outputPath, FileMode.Create, FileAccess.Write)) + using var file = File.Open(outputPath, FileMode.Create, FileAccess.Write); + switch (format) { - switch (format) - { - case LocaFormat.Loca: - { - var writer = new LocaWriter(file); - writer.Write(resource); - break; - } - - case LocaFormat.Xml: - { - var writer = new LocaXmlWriter(file); - writer.Write(resource); - break; - } - - default: - throw new ArgumentException("Invalid loca format"); - } + case LocaFormat.Loca: + { + var writer = new LocaWriter(file); + writer.Write(resource); + break; + } + + case LocaFormat.Xml: + { + var writer = new LocaXmlWriter(file); + writer.Write(resource); + break; + } + + default: + throw new ArgumentException("Invalid loca format"); } } } diff --git a/LSLib/LS/Mods/ModResources.cs b/LSLib/LS/Mods/ModResources.cs index 11f681fa..f4fb4af3 100644 --- a/LSLib/LS/Mods/ModResources.cs +++ b/LSLib/LS/Mods/ModResources.cs @@ -1,20 +1,20 @@ -using Alphaleonis.Win32.Filesystem; -using LSLib.LS.Story.Compiler; +using LSLib.LS.Story.Compiler; using System; using System.Collections.Generic; +using System.IO; using System.Linq; using System.Text.RegularExpressions; namespace LSLib.LS { - public class ModInfo + public class ModInfo(string name) { - public string Name; + public string Name = name; public AbstractFileInfo Meta; - public Dictionary Scripts = new Dictionary(); - public Dictionary Stats = new Dictionary(); - public Dictionary Globals = new Dictionary(); - public Dictionary LevelObjects = new Dictionary(); + public Dictionary Scripts = []; + public Dictionary Stats = []; + public Dictionary Globals = []; + public Dictionary LevelObjects = []; public AbstractFileInfo OrphanQueryIgnoreList; public AbstractFileInfo StoryHeaderFile; public AbstractFileInfo TypeCoercionWhitelistFile; @@ -22,18 +22,13 @@ public class ModInfo public AbstractFileInfo ValueListsFile; public AbstractFileInfo ActionResourcesFile; public AbstractFileInfo ActionResourceGroupsFile; - public List TagFiles = new List(); - - public ModInfo(string name) - { - Name = name; - } + public List TagFiles = []; } public class ModResources : IDisposable { - public Dictionary Mods = new Dictionary(); - public List LoadedPackages = new List(); + public Dictionary Mods = []; + public List LoadedPackages = []; public void Dispose() { @@ -42,20 +37,20 @@ public void Dispose() } } - public class ModPathVisitor + public partial class ModPathVisitor { - private static readonly Regex metaRe = new Regex("^Mods/([^/]+)/meta\\.lsx$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static readonly Regex scriptRe = new Regex("^Mods/([^/]+)/Story/RawFiles/Goals/(.*\\.txt)$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static readonly Regex statRe = new Regex("^Public/([^/]+)/Stats/Generated/Data/(.*\\.txt)$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static readonly Regex staticLsxRe = new Regex("^Public/([^/]+)/(.*\\.lsx)$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static readonly Regex statStructureRe = new Regex("^Public/([^/]+)/Stats/Generated/Structure/(.*\\.txt)$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static readonly Regex orphanQueryIgnoresRe = new Regex("^Mods/([^/]+)/Story/story_orphanqueries_ignore_local\\.txt$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static readonly Regex storyDefinitionsRe = new Regex("^Mods/([^/]+)/Story/RawFiles/story_header\\.div$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static readonly Regex typeCoercionWhitelistRe = new Regex("^Mods/([^/]+)/Story/RawFiles/TypeCoercionWhitelist\\.txt$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static readonly Regex globalsRe = new Regex("^Mods/([^/]+)/Globals/.*/.*/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); - private static readonly Regex levelObjectsRe = new Regex("^Mods/([^/]+)/Levels/.*/(Characters|Items|Triggers)/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); + private static readonly Regex metaRe = MetaRegex(); + private static readonly Regex scriptRe = ScriptRegex(); + private static readonly Regex statRe = StatRegex(); + private static readonly Regex staticLsxRe = StaticLsxRegex(); + private static readonly Regex statStructureRe = StatStructureRegex(); + private static readonly Regex orphanQueryIgnoresRe = OrphanQueryIgnoresRegex(); + private static readonly Regex storyDefinitionsRe = StoryDefinitionsRegex(); + private static readonly Regex typeCoercionWhitelistRe = TypeCoercionWhitelistRegex(); + private static readonly Regex globalsRe = GlobalsRegex(); + private static readonly Regex levelObjectsRe = LevelObjectsRegex(); // Pattern for excluding subsequent parts of a multi-part archive - public static readonly Regex archivePartRe = new Regex("^(.*)_[0-9]+\\.pak$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant | RegexOptions.Compiled); + public static readonly Regex archivePartRe = ArchivePartRegex(); public readonly ModResources Resources; @@ -76,10 +71,10 @@ private static void EnumerateFiles(List paths, string rootPath, string c { foreach (string filePath in Directory.GetFiles(currentPath, pattern)) { - var relativePath = filePath.Substring(rootPath.Length); + var relativePath = filePath[rootPath.Length..]; if (relativePath[0] == '/' || relativePath[0] == '\\') { - relativePath = relativePath.Substring(1); + relativePath = relativePath[1..]; } paths.Add(relativePath); @@ -274,8 +269,8 @@ public void DiscoverBuiltinPackages(string gameDataPath) // List of packages we won't ever load // These packages don't contain any mod resources, but have a large // file table that makes loading unneccessarily slow. - HashSet packageBlacklist = new HashSet - { + HashSet packageBlacklist = + [ "Assets.pak", "Effects.pak", "Engine.pak", @@ -295,7 +290,7 @@ public void DiscoverBuiltinPackages(string gameDataPath) "SharedSounds.pak", "Textures.pak", "VirtualTextures.pak" - }; + ]; // Collect priority value from headers var packagePriorities = new List>(); @@ -344,7 +339,7 @@ private void DiscoverModGoals(string modName, string modPath) var goalPath = modPath + @"\Story\RawFiles\Goals"; if (!Directory.Exists(goalPath)) return; - List goalFiles = new List(); + List goalFiles = []; EnumerateFiles(goalFiles, goalPath, goalPath, "*.txt"); foreach (var goalFile in goalFiles) @@ -363,7 +358,7 @@ private void DiscoverModStats(string modName, string modPublicPath) var statsPath = modPublicPath + @"\Stats\Generated\Data"; if (!Directory.Exists(statsPath)) return; - List statFiles = new List(); + List statFiles = []; EnumerateFiles(statFiles, statsPath, statsPath, "*.txt"); foreach (var statFile in statFiles) @@ -382,7 +377,7 @@ private void DiscoverModGlobals(string modName, string modPath) var globalsPath = modPath + @"\Globals"; if (!Directory.Exists(globalsPath)) return; - List globalFiles = new List(); + List globalFiles = []; EnumerateFiles(globalFiles, globalsPath, globalsPath, "*.lsf"); foreach (var globalFile in globalFiles) @@ -401,10 +396,10 @@ private void DiscoverModLevelObjects(string modName, string modPath) var levelsPath = modPath + @"\Levels"; if (!Directory.Exists(levelsPath)) return; - List levelFiles = new List(); + List levelFiles = []; EnumerateFiles(levelFiles, levelsPath, levelsPath, "*.lsf"); - var levelObjectsRe = new Regex("^(Characters|Items|Triggers)/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant); + var levelObjectsRe = LevelObjectsLocalRegex(); foreach (var levelFile in levelFiles) { var fileInfo = new FilesystemFileInfo @@ -505,5 +500,41 @@ public void Discover(String gameDataPath) DiscoverMods(gameDataPath); } + + [GeneratedRegex("^Mods/([^/]+)/meta\\.lsx$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex MetaRegex(); + + [GeneratedRegex("^Mods/([^/]+)/Story/RawFiles/Goals/(.*\\.txt)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex ScriptRegex(); + + [GeneratedRegex("^Public/([^/]+)/Stats/Generated/Data/(.*\\.txt)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex StatRegex(); + + [GeneratedRegex("^Public/([^/]+)/(.*\\.lsx)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex StaticLsxRegex(); + + [GeneratedRegex("^Public/([^/]+)/Stats/Generated/Structure/(.*\\.txt)$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex StatStructureRegex(); + + [GeneratedRegex("^Mods/([^/]+)/Story/story_orphanqueries_ignore_local\\.txt$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex OrphanQueryIgnoresRegex(); + + [GeneratedRegex("^Mods/([^/]+)/Story/RawFiles/story_header\\.div$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex StoryDefinitionsRegex(); + + [GeneratedRegex("^Mods/([^/]+)/Story/RawFiles/TypeCoercionWhitelist\\.txt$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex TypeCoercionWhitelistRegex(); + + [GeneratedRegex("^Mods/([^/]+)/Globals/.*/.*/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex GlobalsRegex(); + + [GeneratedRegex("^Mods/([^/]+)/Levels/.*/(Characters|Items|Triggers)/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex LevelObjectsRegex(); + + [GeneratedRegex("^(.*)_[0-9]+\\.pak$", RegexOptions.IgnoreCase | RegexOptions.Compiled | RegexOptions.CultureInvariant)] + private static partial Regex ArchivePartRegex(); + + [GeneratedRegex("^(Characters|Items|Triggers)/.*\\.lsf$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant)] + private static partial Regex LevelObjectsLocalRegex(); } } diff --git a/LSLib/LS/NodeAttribute.cs b/LSLib/LS/NodeAttribute.cs index 28dea121..801e2b14 100644 --- a/LSLib/LS/NodeAttribute.cs +++ b/LSLib/LS/NodeAttribute.cs @@ -49,7 +49,7 @@ public void InitFromMeta(string meta) public string BuildMeta() { - List tags = new List { "v1" }; + List tags = [ "v1" ]; if (ByteSwapGuids) { tags.Add("bswap_guids"); @@ -59,7 +59,7 @@ public string BuildMeta() } } - public class NodeAttribute + public class NodeAttribute(NodeAttribute.DataType type) { public enum DataType { @@ -102,7 +102,7 @@ public enum DataType DT_Max = DT_TranslatedFSString }; - private DataType type; + private readonly DataType type = type; private object value; public DataType Type @@ -116,11 +116,6 @@ public object Value set { this.value = value; } } - public NodeAttribute(DataType type) - { - this.type = type; - } - public override string ToString() { throw new NotImplementedException("ToString() is not safe to use anymore, AsString(settings) instead"); @@ -139,34 +134,34 @@ public static Guid ByteSwapGuid(Guid g) public string AsString(NodeSerializationSettings settings) { - switch (this.type) + switch (type) { case DataType.DT_ScratchBuffer: // ScratchBuffer is a special case, as its stored as byte[] and ToString() doesn't really do what we want - return Convert.ToBase64String((byte[])this.value); + return Convert.ToBase64String((byte[])value); case DataType.DT_IVec2: case DataType.DT_IVec3: case DataType.DT_IVec4: - return String.Join(" ", new List((int[])this.value).ConvertAll(i => i.ToString()).ToArray()); + return String.Join(" ", new List((int[])value).ConvertAll(i => i.ToString()).ToArray()); case DataType.DT_Vec2: case DataType.DT_Vec3: case DataType.DT_Vec4: - return String.Join(" ", new List((float[])this.value).ConvertAll(i => i.ToString()).ToArray()); + return String.Join(" ", new List((float[])value).ConvertAll(i => i.ToString()).ToArray()); case DataType.DT_UUID: if (settings.ByteSwapGuids) { - return ByteSwapGuid((Guid)this.value).ToString(); + return ByteSwapGuid((Guid)value).ToString(); } else { - return this.value.ToString(); + return value.ToString(); } default: - return this.value.ToString(); + return value.ToString(); } } @@ -248,9 +243,9 @@ public void FromString(string str, NodeSerializationSettings settings) str = "0"; } // Handle hexadecimal integers in XML files - else if (str.Length > 2 && str.Substring(0, 2) == "0x") + else if (str.Length > 2 && str[..2] == "0x") { - str = Convert.ToUInt64(str.Substring(2), 16).ToString(); + str = Convert.ToUInt64(str[2..], 16).ToString(); } } @@ -351,8 +346,7 @@ public void FromString(string str, NodeSerializationSettings settings) case DataType.DT_TranslatedString: // We'll only set the value part of the translated string, not the TranslatedStringKey / Handle part // That can be changed separately via attribute.Value.Handle - if (value == null) - value = new TranslatedString(); + value ??= new TranslatedString(); ((TranslatedString)value).Value = str; break; @@ -360,8 +354,7 @@ public void FromString(string str, NodeSerializationSettings settings) case DataType.DT_TranslatedFSString: // We'll only set the value part of the translated string, not the TranslatedStringKey / Handle part // That can be changed separately via attribute.Value.Handle - if (value == null) - value = new TranslatedFSString(); + value ??= new TranslatedFSString(); ((TranslatedFSString)value).Value = str; break; diff --git a/LSLib/LS/PackageCommon.cs b/LSLib/LS/PackageCommon.cs index 56308ceb..ba701226 100644 --- a/LSLib/LS/PackageCommon.cs +++ b/LSLib/LS/PackageCommon.cs @@ -6,11 +6,6 @@ using System.Text; using LSLib.LS.Enums; using LSLib.Native; -using Alphaleonis.Win32.Filesystem; -using Path = Alphaleonis.Win32.Filesystem.Path; -using FileInfo = Alphaleonis.Win32.Filesystem.FileInfo; -using Directory = Alphaleonis.Win32.Filesystem.Directory; -using File = Alphaleonis.Win32.Filesystem.File; namespace LSLib.LS { @@ -440,7 +435,7 @@ internal static PackagedFileInfo CreateFromEntry(FileEntry7 entry, Stream dataSt info.ArchivePart = entry.ArchivePart; info.Crc = 0; - info.Flags = entry.UncompressedSize > 0 ? BinUtils.MakeCompressionFlags(CompressionMethod.Zlib, CompressionLevel.DefaultCompression) : (uint) 0; + info.Flags = entry.UncompressedSize > 0 ? BinUtils.MakeCompressionFlags(CompressionMethod.Zlib, LSCompressionLevel.DefaultCompression) : (uint) 0; return info; } @@ -537,15 +532,11 @@ public void Dispose() public override UInt32 CRC() => throw new NotImplementedException("!"); - public override Stream MakeStream() => _stream ?? (_stream = File.Open(FilesystemPath, FileMode.Open, FileAccess.Read, FileShare.Read)); + public override Stream MakeStream() => _stream ??= File.Open(FilesystemPath, FileMode.Open, FileAccess.Read, FileShare.Read); public override void ReleaseStream() { - if (_stream == null) - { - return; - } - _stream.Dispose(); + _stream?.Dispose(); _stream = null; } @@ -602,16 +593,10 @@ public class Package { public const PackageVersion CurrentVersion = PackageVersion.V18; - public static byte[] Signature = - { - 0x4C, - 0x53, - 0x50, - 0x4B - }; - - public PackageMetadata Metadata = new PackageMetadata(); - public List Files = new List(); + public readonly static byte[] Signature = [ 0x4C, 0x53, 0x50, 0x4B ]; + + public PackageMetadata Metadata = new(); + public List Files = []; public PackageVersion Version; public static string MakePartFilename(string path, int part) @@ -676,16 +661,12 @@ public void UncompressPackage(Package package, string outputPath, Func 0) { - using (FileStream outFile = File.Open(outPath, FileMode.Create, FileAccess.Write)) - { - int read; - while ((read = inReader.Read(buffer, 0, buffer.Length)) > 0) - { - outFile.Write(buffer, 0, read); - } - } + outFile.Write(buffer, 0, read); } } finally @@ -698,11 +679,9 @@ public void UncompressPackage(Package package, string outputPath, Func filter = null) { ProgressUpdate("Reading package headers ...", 0, 1, null); - using (var reader = new PackageReader(packagePath)) - { - Package package = reader.Read(); - UncompressPackage(package, outputPath, filter); - } + using var reader = new PackageReader(packagePath); + Package package = reader.Read(); + UncompressPackage(package, outputPath, filter); } private static Package CreatePackageFromPath(string path) @@ -737,14 +716,12 @@ public void CreatePackage(string packagePath, string inputPath, PackageCreationO package.Metadata.Priority = options.Priority; ProgressUpdate("Creating archive ...", 0, 1, null); - using (var writer = new PackageWriter(package, packagePath)) - { - writer.WriteProgress += WriteProgressUpdate; - writer.Version = options.Version; - writer.Compression = options.Compression; - writer.CompressionLevel = options.FastCompression ? CompressionLevel.FastCompression : CompressionLevel.DefaultCompression; - writer.Write(); - } + using var writer = new PackageWriter(package, packagePath); + writer.WriteProgress += WriteProgressUpdate; + writer.Version = options.Version; + writer.Compression = options.Compression; + writer.LSCompressionLevel = options.FastCompression ? LSCompressionLevel.FastCompression : LSCompressionLevel.DefaultCompression; + writer.Write(); } } } diff --git a/LSLib/LS/PackageReader.cs b/LSLib/LS/PackageReader.cs index d30fcd1b..2d235663 100644 --- a/LSLib/LS/PackageReader.cs +++ b/LSLib/LS/PackageReader.cs @@ -4,7 +4,6 @@ using System.Runtime.InteropServices; using System.Text; using LZ4; -using File = Alphaleonis.Win32.Filesystem.File; using LSLib.LS.Enums; namespace LSLib.LS @@ -24,29 +23,15 @@ public NotAPackageException(string message, Exception innerException) : base(mes } } - public class PackageReader : IDisposable + public class PackageReader(string path, bool metadataOnly = false) : IDisposable { - private readonly String _path; - private readonly bool _metadataOnly; private Stream[] _streams; - public PackageReader(string path, bool metadataOnly = false) - { - this._path = path; - this._metadataOnly = metadataOnly; - } - public void Dispose() { - if (_streams != null) + foreach (Stream stream in _streams ?? []) { - foreach (Stream stream in _streams) - { - if (stream != null) - { - stream.Dispose(); - } - } + stream?.Dispose(); } } @@ -58,7 +43,7 @@ private void OpenStreams(FileStream mainStream, int numParts) for (var part = 1; part < numParts; part++) { - string partPath = Package.MakePartFilename(_path, part); + string partPath = Package.MakePartFilename(path, part); _streams[part] = File.Open(partPath, FileMode.Open, FileAccess.Read, FileShare.Read); } } @@ -73,7 +58,7 @@ private Package ReadPackageV7(FileStream mainStream, BinaryReader reader) package.Metadata.Priority = 0; package.Version = PackageVersion.V7; - if (_metadataOnly) return package; + if (metadataOnly) return package; OpenStreams(mainStream, (int) header.NumParts); for (uint i = 0; i < header.NumFiles; i++) @@ -99,7 +84,7 @@ private Package ReadPackageV10(FileStream mainStream, BinaryReader reader) package.Metadata.Priority = header.Priority; package.Version = PackageVersion.V10; - if (_metadataOnly) return package; + if (metadataOnly) return package; OpenStreams(mainStream, header.NumParts); for (uint i = 0; i < header.NumFiles; i++) @@ -133,7 +118,7 @@ private Package ReadPackageV13(FileStream mainStream, BinaryReader reader) package.Metadata.Priority = header.Priority; package.Version = PackageVersion.V13; - if (_metadataOnly) return package; + if (metadataOnly) return package; OpenStreams(mainStream, header.NumParts); mainStream.Seek(header.FileListOffset, SeekOrigin.Begin); @@ -288,7 +273,7 @@ private Package ReadPackageV15(FileStream mainStream, BinaryReader reader) package.Metadata.Priority = header.Priority; package.Version = PackageVersion.V15; - if (_metadataOnly) return package; + if (metadataOnly) return package; OpenStreams(mainStream, 1); mainStream.Seek((long)header.FileListOffset, SeekOrigin.Begin); @@ -312,7 +297,7 @@ private Package ReadPackageV16(FileStream mainStream, BinaryReader reader) package.Metadata.Priority = header.Priority; package.Version = PackageVersion.V16; - if (_metadataOnly) return package; + if (metadataOnly) return package; OpenStreams(mainStream, header.NumParts); mainStream.Seek((long)header.FileListOffset, SeekOrigin.Begin); @@ -336,7 +321,7 @@ private Package ReadPackageV18(FileStream mainStream, BinaryReader reader) package.Metadata.Priority = header.Priority; package.Version = PackageVersion.V18; - if (_metadataOnly) return package; + if (metadataOnly) return package; OpenStreams(mainStream, header.NumParts); mainStream.Seek((long)header.FileListOffset, SeekOrigin.Begin); @@ -347,62 +332,60 @@ private Package ReadPackageV18(FileStream mainStream, BinaryReader reader) public Package Read() { - var mainStream = File.Open(_path, FileMode.Open, FileAccess.Read, FileShare.Read); + var mainStream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Read); + using var reader = new BinaryReader(mainStream, new UTF8Encoding(), true); + + // Check for v13 package headers + mainStream.Seek(-8, SeekOrigin.End); + Int32 headerSize = reader.ReadInt32(); + byte[] signature = reader.ReadBytes(4); + if (Package.Signature.SequenceEqual(signature)) + { + mainStream.Seek(-headerSize, SeekOrigin.End); + return ReadPackageV13(mainStream, reader); + } - using (var reader = new BinaryReader(mainStream, new UTF8Encoding(), true)) + // Check for v10 package headers + mainStream.Seek(0, SeekOrigin.Begin); + signature = reader.ReadBytes(4); + Int32 version; + if (Package.Signature.SequenceEqual(signature)) { - // Check for v13 package headers - mainStream.Seek(-8, SeekOrigin.End); - Int32 headerSize = reader.ReadInt32(); - byte[] signature = reader.ReadBytes(4); - if (Package.Signature.SequenceEqual(signature)) + version = reader.ReadInt32(); + if (version == 10) { - mainStream.Seek(-headerSize, SeekOrigin.End); - return ReadPackageV13(mainStream, reader); + return ReadPackageV10(mainStream, reader); } - - // Check for v10 package headers - mainStream.Seek(0, SeekOrigin.Begin); - signature = reader.ReadBytes(4); - Int32 version; - if (Package.Signature.SequenceEqual(signature)) + else if (version == 15) { - version = reader.ReadInt32(); - if (version == 10) - { - return ReadPackageV10(mainStream, reader); - } - else if (version == 15) - { - mainStream.Seek(4, SeekOrigin.Begin); - return ReadPackageV15(mainStream, reader); - } - else if (version == 16) - { - mainStream.Seek(4, SeekOrigin.Begin); - return ReadPackageV16(mainStream, reader); - } - else if (version == 18) - { - mainStream.Seek(4, SeekOrigin.Begin); - return ReadPackageV18(mainStream, reader); - } - else - { - throw new InvalidDataException($"Package version v{version} not supported"); - } + mainStream.Seek(4, SeekOrigin.Begin); + return ReadPackageV15(mainStream, reader); } - - // Check for v9 and v7 package headers - mainStream.Seek(0, SeekOrigin.Begin); - version = reader.ReadInt32(); - if (version == 7 || version == 9) + else if (version == 16) { - return ReadPackageV7(mainStream, reader); + mainStream.Seek(4, SeekOrigin.Begin); + return ReadPackageV16(mainStream, reader); } + else if (version == 18) + { + mainStream.Seek(4, SeekOrigin.Begin); + return ReadPackageV18(mainStream, reader); + } + else + { + throw new InvalidDataException($"Package version v{version} not supported"); + } + } - throw new NotAPackageException("No valid signature found in package file"); + // Check for v9 and v7 package headers + mainStream.Seek(0, SeekOrigin.Begin); + version = reader.ReadInt32(); + if (version == 7 || version == 9) + { + return ReadPackageV7(mainStream, reader); } + + throw new NotAPackageException("No valid signature found in package file"); } } } diff --git a/LSLib/LS/PackageWriter.cs b/LSLib/LS/PackageWriter.cs index 82db1c09..8ba81383 100644 --- a/LSLib/LS/PackageWriter.cs +++ b/LSLib/LS/PackageWriter.cs @@ -8,32 +8,21 @@ using LSLib.LS.Enums; using LSLib.Native; using LZ4; -using Alphaleonis.Win32.Filesystem; -using File = Alphaleonis.Win32.Filesystem.File; namespace LSLib.LS { - public class PackageWriter : IDisposable + public class PackageWriter(Package package, string path) : IDisposable { public delegate void WriteProgressDelegate(AbstractFileInfo abstractFile, long numerator, long denominator); private const long MaxPackageSizeDOS = 0x40000000; private const long MaxPackageSizeBG3 = 0x100000000; public CompressionMethod Compression = CompressionMethod.None; - public CompressionLevel CompressionLevel = CompressionLevel.DefaultCompression; - - private readonly Package _package; - private readonly String _path; - private readonly List _streams = new List(); + public LSCompressionLevel LSCompressionLevel = LSCompressionLevel.DefaultCompression; + private readonly List _streams = []; public PackageVersion Version = Package.CurrentVersion; public WriteProgressDelegate WriteProgress = delegate { }; - public PackageWriter(Package package, string path) - { - this._package = package; - this._path = path; - } - public void Dispose() { foreach (Stream stream in _streams) @@ -52,11 +41,20 @@ public PackagedFileInfo WriteFile(AbstractFileInfo info) || (Version >= PackageVersion.V16 && _streams.Last().Position + size > MaxPackageSizeBG3)) { // Start a new package file if the current one is full. - string partPath = Package.MakePartFilename(_path, _streams.Count); + string partPath = Package.MakePartFilename(path, _streams.Count); var nextPart = File.Open(partPath, FileMode.Create, FileAccess.Write); _streams.Add(nextPart); } + var compression = Compression; + var compressionLevel = LSCompressionLevel; + + if (info.Name.EndsWith(".gts") || info.Name.EndsWith(".gtp")) + { + compression = CompressionMethod.None; + compressionLevel = LSCompressionLevel.FastCompression; + } + Stream stream = _streams.Last(); var packaged = new PackagedFileInfo { @@ -65,19 +63,17 @@ public PackagedFileInfo WriteFile(AbstractFileInfo info) UncompressedSize = (ulong)size, ArchivePart = (UInt32) (_streams.Count - 1), OffsetInFile = (UInt32) stream.Position, - Flags = BinUtils.MakeCompressionFlags(Compression, CompressionLevel) + Flags = BinUtils.MakeCompressionFlags(compression, compressionLevel) }; Stream packagedStream = info.MakeStream(); byte[] compressed; try { - using (var reader = new BinaryReader(packagedStream, Encoding.UTF8, true)) - { - byte[] uncompressed = reader.ReadBytes((int) reader.BaseStream.Length); - compressed = BinUtils.Compress(uncompressed, Compression, CompressionLevel); - stream.Write(compressed, 0, compressed.Length); - } + using var reader = new BinaryReader(packagedStream, Encoding.UTF8, true); + byte[] uncompressed = reader.ReadBytes((int)reader.BaseStream.Length); + compressed = BinUtils.Compress(uncompressed, compression, compressionLevel); + stream.Write(compressed, 0, compressed.Length); } finally { @@ -87,7 +83,7 @@ public PackagedFileInfo WriteFile(AbstractFileInfo info) packaged.SizeOnDisk = (UInt64) (stream.Position - (long)packaged.OffsetInFile); packaged.Crc = Crc32.Compute(compressed, 0); - if ((_package.Metadata.Flags & PackageFlags.Solid) == 0) + if ((package.Metadata.Flags & PackageFlags.Solid) == 0) { int padLength = PaddingLength(); long alignTo; @@ -121,164 +117,158 @@ public void WriteV7(FileStream mainStream) throw new ArgumentException("LZ4 compression is only supported by V10 and later package versions"); } - using (var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true)) + using var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true); + var header = new LSPKHeader7 { - var header = new LSPKHeader7 - { - Version = (uint) Version, - NumFiles = (UInt32) _package.Files.Count, - FileListSize = (UInt32) (Marshal.SizeOf(typeof(FileEntry7)) * _package.Files.Count) - }; - header.DataOffset = (UInt32) Marshal.SizeOf(typeof(LSPKHeader7)) + header.FileListSize; - int paddingLength = PaddingLength(); - if (header.DataOffset % paddingLength > 0) - { - header.DataOffset += (UInt32) (paddingLength - header.DataOffset % paddingLength); - } + Version = (uint)Version, + NumFiles = (UInt32)package.Files.Count, + FileListSize = (UInt32)(Marshal.SizeOf(typeof(FileEntry7)) * package.Files.Count) + }; + header.DataOffset = (UInt32)Marshal.SizeOf(typeof(LSPKHeader7)) + header.FileListSize; + int paddingLength = PaddingLength(); + if (header.DataOffset % paddingLength > 0) + { + header.DataOffset += (UInt32)(paddingLength - header.DataOffset % paddingLength); + } - // Write a placeholder instead of the actual headers; we'll write them after we - // compressed and flushed all files to disk - var placeholder = new byte[header.DataOffset]; - writer.Write(placeholder); + // Write a placeholder instead of the actual headers; we'll write them after we + // compressed and flushed all files to disk + var placeholder = new byte[header.DataOffset]; + writer.Write(placeholder); - long totalSize = _package.Files.Sum(p => (long) p.Size()); - long currentSize = 0; - var writtenFiles = new List(); - foreach (AbstractFileInfo file in _package.Files) - { - WriteProgress(file, currentSize, totalSize); - writtenFiles.Add(WriteFile(file)); - currentSize += (long)file.Size(); - } + long totalSize = package.Files.Sum(p => (long)p.Size()); + long currentSize = 0; + var writtenFiles = new List(); + foreach (AbstractFileInfo file in package.Files) + { + WriteProgress(file, currentSize, totalSize); + writtenFiles.Add(WriteFile(file)); + currentSize += (long)file.Size(); + } - mainStream.Seek(0, SeekOrigin.Begin); - header.LittleEndian = 0; - header.NumParts = (UInt16) _streams.Count; - BinUtils.WriteStruct(writer, ref header); + mainStream.Seek(0, SeekOrigin.Begin); + header.LittleEndian = 0; + header.NumParts = (UInt16)_streams.Count; + BinUtils.WriteStruct(writer, ref header); - foreach (PackagedFileInfo file in writtenFiles) + foreach (PackagedFileInfo file in writtenFiles) + { + FileEntry7 entry = file.MakeEntryV7(); + if (entry.ArchivePart == 0) { - FileEntry7 entry = file.MakeEntryV7(); - if (entry.ArchivePart == 0) - { - entry.OffsetInFile -= header.DataOffset; - } - - BinUtils.WriteStruct(writer, ref entry); + entry.OffsetInFile -= header.DataOffset; } + + BinUtils.WriteStruct(writer, ref entry); } } public void WriteV10(FileStream mainStream) { - using (var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true)) + using var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true); + var header = new LSPKHeader10 { - var header = new LSPKHeader10 - { - Version = (uint) Version, - NumFiles = (UInt32) _package.Files.Count, - FileListSize = (UInt32) (Marshal.SizeOf(typeof(FileEntry13)) * _package.Files.Count) - }; - header.DataOffset = (UInt32) Marshal.SizeOf(typeof(LSPKHeader10)) + 4 + header.FileListSize; - int paddingLength = PaddingLength(); - if (header.DataOffset % paddingLength > 0) - { - header.DataOffset += (UInt32) (paddingLength - header.DataOffset % paddingLength); - } + Version = (uint)Version, + NumFiles = (UInt32)package.Files.Count, + FileListSize = (UInt32)(Marshal.SizeOf(typeof(FileEntry13)) * package.Files.Count) + }; + header.DataOffset = (UInt32)Marshal.SizeOf(typeof(LSPKHeader10)) + 4 + header.FileListSize; + int paddingLength = PaddingLength(); + if (header.DataOffset % paddingLength > 0) + { + header.DataOffset += (UInt32)(paddingLength - header.DataOffset % paddingLength); + } - // Write a placeholder instead of the actual headers; we'll write them after we - // compressed and flushed all files to disk - var placeholder = new byte[header.DataOffset]; - writer.Write(placeholder); + // Write a placeholder instead of the actual headers; we'll write them after we + // compressed and flushed all files to disk + var placeholder = new byte[header.DataOffset]; + writer.Write(placeholder); - long totalSize = _package.Files.Sum(p => (long) p.Size()); - long currentSize = 0; - var writtenFiles = new List(); - foreach (AbstractFileInfo file in _package.Files) - { - WriteProgress(file, currentSize, totalSize); - writtenFiles.Add(WriteFile(file)); - currentSize += (long)file.Size(); - } + long totalSize = package.Files.Sum(p => (long)p.Size()); + long currentSize = 0; + var writtenFiles = new List(); + foreach (AbstractFileInfo file in package.Files) + { + WriteProgress(file, currentSize, totalSize); + writtenFiles.Add(WriteFile(file)); + currentSize += (long)file.Size(); + } - mainStream.Seek(0, SeekOrigin.Begin); - writer.Write(Package.Signature); - header.NumParts = (UInt16) _streams.Count; - header.Priority = _package.Metadata.Priority; - header.Flags = (byte)_package.Metadata.Flags; - BinUtils.WriteStruct(writer, ref header); + mainStream.Seek(0, SeekOrigin.Begin); + writer.Write(Package.Signature); + header.NumParts = (UInt16)_streams.Count; + header.Priority = package.Metadata.Priority; + header.Flags = (byte)package.Metadata.Flags; + BinUtils.WriteStruct(writer, ref header); - foreach (PackagedFileInfo file in writtenFiles) + foreach (PackagedFileInfo file in writtenFiles) + { + FileEntry13 entry = file.MakeEntryV13(); + if (entry.ArchivePart == 0) { - FileEntry13 entry = file.MakeEntryV13(); - if (entry.ArchivePart == 0) - { - entry.OffsetInFile -= header.DataOffset; - } - - // v10 packages don't support compression level in the flags field - entry.Flags &= 0x0f; - BinUtils.WriteStruct(writer, ref entry); + entry.OffsetInFile -= header.DataOffset; } + + // v10 packages don't support compression level in the flags field + entry.Flags &= 0x0f; + BinUtils.WriteStruct(writer, ref entry); } } public void WriteV13(FileStream mainStream) { - long totalSize = _package.Files.Sum(p => (long) p.Size()); + long totalSize = package.Files.Sum(p => (long) p.Size()); long currentSize = 0; var writtenFiles = new List(); - foreach (AbstractFileInfo file in _package.Files) + foreach (AbstractFileInfo file in package.Files) { WriteProgress(file, currentSize, totalSize); writtenFiles.Add(WriteFile(file)); currentSize += (long)file.Size(); } - using (var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true)) + using var writer = new BinaryWriter(mainStream, new UTF8Encoding(), true); + var header = new LSPKHeader13 { - var header = new LSPKHeader13 - { - Version = (uint) Version, - FileListOffset = (UInt32) mainStream.Position - }; + Version = (uint)Version, + FileListOffset = (UInt32)mainStream.Position + }; - writer.Write((UInt32) writtenFiles.Count); + writer.Write((UInt32)writtenFiles.Count); - var fileList = new MemoryStream(); - var fileListWriter = new BinaryWriter(fileList); - foreach (PackagedFileInfo file in writtenFiles) - { - FileEntry13 entry = file.MakeEntryV13(); - BinUtils.WriteStruct(fileListWriter, ref entry); - } + var fileList = new MemoryStream(); + var fileListWriter = new BinaryWriter(fileList); + foreach (PackagedFileInfo file in writtenFiles) + { + FileEntry13 entry = file.MakeEntryV13(); + BinUtils.WriteStruct(fileListWriter, ref entry); + } - byte[] fileListBuf = fileList.ToArray(); - fileListWriter.Dispose(); - byte[] compressedFileList = LZ4Codec.EncodeHC(fileListBuf, 0, fileListBuf.Length); + byte[] fileListBuf = fileList.ToArray(); + fileListWriter.Dispose(); + byte[] compressedFileList = LZ4Codec.EncodeHC(fileListBuf, 0, fileListBuf.Length); - writer.Write(compressedFileList); + writer.Write(compressedFileList); - header.FileListSize = (UInt32) mainStream.Position - header.FileListOffset; - header.NumParts = (UInt16) _streams.Count; - header.Priority = _package.Metadata.Priority; - header.Flags = (byte)_package.Metadata.Flags; - header.Md5 = ComputeArchiveHash(); - BinUtils.WriteStruct(writer, ref header); + header.FileListSize = (UInt32)mainStream.Position - header.FileListOffset; + header.NumParts = (UInt16)_streams.Count; + header.Priority = package.Metadata.Priority; + header.Flags = (byte)package.Metadata.Flags; + header.Md5 = ComputeArchiveHash(); + BinUtils.WriteStruct(writer, ref header); - writer.Write((UInt32) (8 + Marshal.SizeOf(typeof(LSPKHeader13)))); - writer.Write(Package.Signature); - } + writer.Write((UInt32)(8 + Marshal.SizeOf(typeof(LSPKHeader13)))); + writer.Write(Package.Signature); } private List PackFiles() { - long totalSize = _package.Files.Sum(p => (long)p.Size()); + long totalSize = package.Files.Sum(p => (long)p.Size()); long currentSize = 0; var writtenFiles = new List(); - foreach (AbstractFileInfo file in _package.Files) + foreach (AbstractFileInfo file in package.Files) { WriteProgress(file, currentSize, totalSize); writtenFiles.Add(WriteFile(file)); @@ -331,8 +321,8 @@ public void WriteV15(FileStream mainStream) WriteFileListV15(writer, writtenFiles); header.FileListSize = (UInt32)(mainStream.Position - (long)header.FileListOffset); - header.Priority = _package.Metadata.Priority; - header.Flags = (byte)_package.Metadata.Flags; + header.Priority = package.Metadata.Priority; + header.Flags = (byte)package.Metadata.Flags; header.Md5 = ComputeArchiveHash(); mainStream.Seek(4, SeekOrigin.Begin); BinUtils.WriteStruct(writer, ref header); @@ -360,8 +350,8 @@ public void WriteV16(FileStream mainStream) WriteFileListV15(writer, writtenFiles); header.FileListSize = (UInt32)(mainStream.Position - (long)header.FileListOffset); - header.Priority = _package.Metadata.Priority; - header.Flags = (byte)_package.Metadata.Flags; + header.Priority = package.Metadata.Priority; + header.Flags = (byte)package.Metadata.Flags; header.Md5 = ComputeArchiveHash(); header.NumParts = (UInt16)_streams.Count; mainStream.Seek(4, SeekOrigin.Begin); @@ -412,8 +402,8 @@ public void WriteV18(FileStream mainStream) WriteFileListV18(writer, writtenFiles); header.FileListSize = (UInt32)(mainStream.Position - (long)header.FileListOffset); - header.Priority = _package.Metadata.Priority; - header.Flags = (byte)_package.Metadata.Flags; + header.Priority = package.Metadata.Priority; + header.Flags = (byte)package.Metadata.Flags; header.Md5 = ComputeArchiveHash(); header.NumParts = (UInt16)_streams.Count; mainStream.Seek(4, SeekOrigin.Begin); @@ -424,47 +414,45 @@ public void WriteV18(FileStream mainStream) public byte[] ComputeArchiveHash() { // MD5 is computed over the contents of all files in an alphabetically sorted order - List orderedFileList = _package.Files.Select(item => item).ToList(); + List orderedFileList = package.Files.Select(item => item).ToList(); if (Version < PackageVersion.V15) { orderedFileList.Sort((a, b) => String.CompareOrdinal(a.Name, b.Name)); } - using (MD5 md5 = MD5.Create()) + using MD5 md5 = MD5.Create(); + foreach (AbstractFileInfo file in orderedFileList) { - foreach (AbstractFileInfo file in orderedFileList) + Stream packagedStream = file.MakeStream(); + try { - Stream packagedStream = file.MakeStream(); - try - { - using (var reader = new BinaryReader(packagedStream)) - { - byte[] uncompressed = reader.ReadBytes((int) reader.BaseStream.Length); - md5.TransformBlock(uncompressed, 0, uncompressed.Length, uncompressed, 0); - } - } - finally + using (var reader = new BinaryReader(packagedStream)) { - file.ReleaseStream(); + byte[] uncompressed = reader.ReadBytes((int)reader.BaseStream.Length); + md5.TransformBlock(uncompressed, 0, uncompressed.Length, uncompressed, 0); } } - - md5.TransformFinalBlock(new byte[0], 0, 0); - byte[] hash = md5.Hash; - - // All hash bytes are incremented by 1 - for (var i = 0; i < hash.Length; i++) + finally { - hash[i] += 1; + file.ReleaseStream(); } + } + + md5.TransformFinalBlock(new byte[0], 0, 0); + byte[] hash = md5.Hash; - return hash; + // All hash bytes are incremented by 1 + for (var i = 0; i < hash.Length; i++) + { + hash[i] += 1; } + + return hash; } public void Write() { - var mainStream = File.Open(_path, FileMode.Create, FileAccess.Write); + var mainStream = File.Open(path, FileMode.Create, FileAccess.Write); _streams.Add(mainStream); switch (Version) diff --git a/LSLib/LS/Resource.cs b/LSLib/LS/Resource.cs index 3846b635..5d6837d3 100644 --- a/LSLib/LS/Resource.cs +++ b/LSLib/LS/Resource.cs @@ -5,11 +5,8 @@ namespace LSLib.LS { - public class InvalidFormatException : Exception + public class InvalidFormatException(string message) : Exception(message) { - public InvalidFormatException(string message) - : base(message) - { } } public struct PackedVersion @@ -41,7 +38,7 @@ public static PackedVersion FromInt32(Int32 packed) }; } - public Int32 ToVersion32() + public readonly Int32 ToVersion32() { return (Int32)((Major & 0x0f) << 28 | (Minor & 0x0f) << 24 | @@ -49,7 +46,7 @@ public Int32 ToVersion32() (Build & 0xffff) << 0); } - public Int64 ToVersion64() + public readonly Int64 ToVersion64() { return (Int64)(((Int64)Major & 0x7f) << 55 | ((Int64)Minor & 0xff) << 47 | @@ -76,7 +73,7 @@ public struct LSBHeader /// /// LSB file signature since BG3 /// - public static byte[] SignatureBG3 = new byte[] { 0x4C, 0x53, 0x46, 0x4D }; + public readonly static byte[] SignatureBG3 = "LSFM"u8.ToArray(); /// /// LSB signature up to FW3 (DOS2 DE) @@ -92,7 +89,7 @@ public struct LSBHeader public static class AttributeTypeMaps { - public static Dictionary TypeToId = new Dictionary + public readonly static Dictionary TypeToId = new() { { "None", NodeAttribute.DataType.DT_None }, { "uint8", NodeAttribute.DataType.DT_Byte }, @@ -130,7 +127,7 @@ public static class AttributeTypeMaps { "TranslatedFSString", NodeAttribute.DataType.DT_TranslatedFSString }, }; - public static Dictionary IdToType = new Dictionary + public readonly static Dictionary IdToType = new() { { NodeAttribute.DataType.DT_None, "None" }, { NodeAttribute.DataType.DT_Byte, "uint8" }, @@ -172,7 +169,7 @@ public static class AttributeTypeMaps public class Resource { public LSMetadata Metadata; - public Dictionary Regions = new Dictionary(); + public Dictionary Regions = []; public Resource() { @@ -189,8 +186,8 @@ public class Node { public string Name; public Node Parent; - public Dictionary Attributes = new Dictionary(); - public Dictionary> Children = new Dictionary>(); + public Dictionary Attributes = []; + public Dictionary> Children = []; public int ChildCount { @@ -218,10 +215,9 @@ public int TotalChildCount() public void AppendChild(Node child) { - List children; - if (!Children.TryGetValue(child.Name, out children)) + if (!Children.TryGetValue(child.Name, out List children)) { - children = new List(); + children = []; Children.Add(child.Name, children); } diff --git a/LSLib/LS/ResourceUtils.cs b/LSLib/LS/ResourceUtils.cs index 90aa5832..1a0584c8 100644 --- a/LSLib/LS/ResourceUtils.cs +++ b/LSLib/LS/ResourceUtils.cs @@ -2,10 +2,6 @@ using System.Collections.Generic; using System.IO; using LSLib.LS.Enums; -using Alphaleonis.Win32.Filesystem; -using Path = Alphaleonis.Win32.Filesystem.Path; -using Directory = Alphaleonis.Win32.Filesystem.Directory; -using File = Alphaleonis.Win32.Filesystem.File; namespace LSLib.LS { @@ -64,7 +60,7 @@ public class ResourceConversionParameters /// /// LSF/LSB compression level (i.e. size/compression time tradeoff) /// - public CompressionLevel CompressionLevel = CompressionLevel.DefaultCompression; + public LSCompressionLevel LSCompressionLevel = LSCompressionLevel.DefaultCompression; /// /// Byte-swap the last 8 bytes of GUIDs when serializing to/from string @@ -73,11 +69,12 @@ public class ResourceConversionParameters public static ResourceConversionParameters FromGameVersion(Game game) { - var p = new ResourceConversionParameters(); - p.PAKVersion = game.PAKVersion(); - p.LSF = game.LSFVersion(); - p.LSX = game.LSXVersion(); - return p; + return new ResourceConversionParameters + { + PAKVersion = game.PAKVersion(), + LSF = game.LSFVersion(), + LSX = game.LSXVersion() + }; } public void ToSerializationSettings(NodeSerializationSettings settings) @@ -98,26 +95,14 @@ public static ResourceFormat ExtensionToResourceFormat(string path) { var extension = Path.GetExtension(path).ToLower(); - switch (extension) + return extension switch { - case ".lsx": - return ResourceFormat.LSX; - - case ".lsb": - return ResourceFormat.LSB; - - case ".lsf": - case ".lsfx": - case ".lsbc": - case ".lsbs": - return ResourceFormat.LSF; - - case ".lsj": - return ResourceFormat.LSJ; - - default: - throw new ArgumentException("Unrecognized file extension: " + extension); - } + ".lsx" => ResourceFormat.LSX, + ".lsb" => ResourceFormat.LSB, + ".lsf" or ".lsfx" or ".lsbc" or ".lsbs" => ResourceFormat.LSF, + ".lsj" => ResourceFormat.LSJ, + _ => throw new ArgumentException("Unrecognized file extension: " + extension), + }; } public static Resource LoadResource(string inputPath, ResourceLoadParameters loadParams) @@ -127,10 +112,8 @@ public static Resource LoadResource(string inputPath, ResourceLoadParameters loa public static Resource LoadResource(string inputPath, ResourceFormat format, ResourceLoadParameters loadParams) { - using (var stream = File.Open(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read)) - { - return LoadResource(stream, format, loadParams); - } + using var stream = File.Open(inputPath, FileMode.Open, FileAccess.Read, FileShare.Read); + return LoadResource(stream, format, loadParams); } public static Resource LoadResource(Stream stream, ResourceFormat format, ResourceLoadParameters loadParams) @@ -139,36 +122,28 @@ public static Resource LoadResource(Stream stream, ResourceFormat format, Resour { case ResourceFormat.LSX: { - using (var reader = new LSXReader(stream)) - { - loadParams.ToSerializationSettings(reader.SerializationSettings); - return reader.Read(); - } + using var reader = new LSXReader(stream); + loadParams.ToSerializationSettings(reader.SerializationSettings); + return reader.Read(); } case ResourceFormat.LSB: { - using (var reader = new LSBReader(stream)) - { - return reader.Read(); - } + using var reader = new LSBReader(stream); + return reader.Read(); } case ResourceFormat.LSF: { - using (var reader = new LSFReader(stream)) - { - return reader.Read(); - } + using var reader = new LSFReader(stream); + return reader.Read(); } case ResourceFormat.LSJ: { - using (var reader = new LSJReader(stream)) - { - loadParams.ToSerializationSettings(reader.SerializationSettings); - return reader.Read(); - } + using var reader = new LSJReader(stream); + loadParams.ToSerializationSettings(reader.SerializationSettings); + return reader.Read(); } default: @@ -185,64 +160,68 @@ public static void SaveResource(Resource resource, string outputPath, ResourceFo { FileManager.TryToCreateDirectory(outputPath); - using (var file = File.Open(outputPath, FileMode.Create, FileAccess.Write)) + using var file = File.Open(outputPath, FileMode.Create, FileAccess.Write); + switch (format) { - switch (format) - { - case ResourceFormat.LSX: - { - var writer = new LSXWriter(file); - writer.Version = conversionParams.LSX; - writer.PrettyPrint = conversionParams.PrettyPrint; - conversionParams.ToSerializationSettings(writer.SerializationSettings); - writer.Write(resource); - break; - } - - case ResourceFormat.LSB: + case ResourceFormat.LSX: + { + var writer = new LSXWriter(file) { - var writer = new LSBWriter(file); - writer.Write(resource); - break; - } + Version = conversionParams.LSX, + PrettyPrint = conversionParams.PrettyPrint + }; + conversionParams.ToSerializationSettings(writer.SerializationSettings); + writer.Write(resource); + break; + } + + case ResourceFormat.LSB: + { + var writer = new LSBWriter(file); + writer.Write(resource); + break; + } - case ResourceFormat.LSF: + case ResourceFormat.LSF: + { + var writer = new LSFWriter(file) { - var writer = new LSFWriter(file); - writer.Version = conversionParams.LSF; - writer.EncodeSiblingData = conversionParams.LSFEncodeSiblingData; - writer.Compression = conversionParams.Compression; - writer.CompressionLevel = conversionParams.CompressionLevel; - writer.Write(resource); - break; - } - - case ResourceFormat.LSJ: + Version = conversionParams.LSF, + EncodeSiblingData = conversionParams.LSFEncodeSiblingData, + Compression = conversionParams.Compression, + LSCompressionLevel = conversionParams.LSCompressionLevel + }; + writer.Write(resource); + break; + } + + case ResourceFormat.LSJ: + { + var writer = new LSJWriter(file) { - var writer = new LSJWriter(file); - writer.PrettyPrint = conversionParams.PrettyPrint; - conversionParams.ToSerializationSettings(writer.SerializationSettings); - writer.Write(resource); - break; - } - - default: - throw new ArgumentException("Invalid resource format"); - } + PrettyPrint = conversionParams.PrettyPrint + }; + conversionParams.ToSerializationSettings(writer.SerializationSettings); + writer.Write(resource); + break; + } + + default: + throw new ArgumentException("Invalid resource format"); } } private bool IsA(string path, ResourceFormat format) { var extension = Path.GetExtension(path).ToLower(); - switch (format) + return format switch { - case ResourceFormat.LSX: return extension == ".lsx"; - case ResourceFormat.LSB: return extension == ".lsb"; - case ResourceFormat.LSF: return extension == ".lsf" || extension == ".lsbc" || extension == ".lsfx"; - case ResourceFormat.LSJ: return extension == ".lsj"; - default: return false; - } + ResourceFormat.LSX => extension == ".lsx", + ResourceFormat.LSB => extension == ".lsb", + ResourceFormat.LSF => extension == ".lsf" || extension == ".lsbc" || extension == ".lsfx", + ResourceFormat.LSJ => extension == ".lsj", + _ => false, + }; } private void EnumerateFiles(List paths, string rootPath, string currentPath, ResourceFormat format) @@ -251,10 +230,10 @@ private void EnumerateFiles(List paths, string rootPath, string currentP { if (IsA(filePath, format)) { - var relativePath = filePath.Substring(rootPath.Length); + var relativePath = filePath[rootPath.Length..]; if (relativePath[0] == '/' || relativePath[0] == '\\') { - relativePath = relativePath.Substring(1); + relativePath = relativePath[1..]; } paths.Add(relativePath); diff --git a/LSLib/LS/Resources/LSB/LSBReader.cs b/LSLib/LS/Resources/LSB/LSBReader.cs index ffa651ad..9df8ab78 100644 --- a/LSLib/LS/Resources/LSB/LSBReader.cs +++ b/LSLib/LS/Resources/LSB/LSBReader.cs @@ -4,18 +4,12 @@ namespace LSLib.LS { - public class LSBReader : IDisposable + public class LSBReader(Stream stream) : IDisposable { - private Stream stream; private BinaryReader reader; - private Dictionary staticStrings = new Dictionary(); + private Dictionary staticStrings = []; private bool IsBG3; - public LSBReader(Stream stream) - { - this.stream = stream; - } - public void Dispose() { stream.Dispose(); @@ -40,8 +34,10 @@ public Resource Read() IsBG3 = (header.Signature == BitConverter.ToUInt32(LSBHeader.SignatureBG3, 0)); ReadStaticStrings(); - Resource rsrc = new Resource(); - rsrc.Metadata = header.Metadata; + Resource rsrc = new Resource + { + Metadata = header.Metadata + }; ReadRegions(rsrc); return rsrc; } @@ -55,8 +51,10 @@ private void ReadRegions(Resource rsrc) UInt32 regionNameId = reader.ReadUInt32(); UInt32 regionOffset = reader.ReadUInt32(); - Region rgn = new Region(); - rgn.RegionName = staticStrings[regionNameId]; + Region rgn = new Region + { + RegionName = staticStrings[regionNameId] + }; var lastRegionPos = stream.Position; stream.Seek(regionOffset, SeekOrigin.Begin); @@ -85,8 +83,10 @@ private void ReadNode(Node node) for (UInt32 i = 0; i < childCount; i++) { - Node child = new Node(); - child.Parent = node; + Node child = new Node + { + Parent = node + }; ReadNode(child); node.AppendChild(child); } @@ -101,16 +101,20 @@ private NodeAttribute ReadAttribute(NodeAttribute.DataType type) case NodeAttribute.DataType.DT_FixedString: case NodeAttribute.DataType.DT_LSString: { - var attr = new NodeAttribute(type); - attr.Value = ReadString(true); + var attr = new NodeAttribute(type) + { + Value = ReadString(true) + }; return attr; } case NodeAttribute.DataType.DT_WString: case NodeAttribute.DataType.DT_LSWString: { - var attr = new NodeAttribute(type); - attr.Value = ReadWideString(true); + var attr = new NodeAttribute(type) + { + Value = ReadWideString(true) + }; return attr; } diff --git a/LSLib/LS/Resources/LSB/LSBWriter.cs b/LSLib/LS/Resources/LSB/LSBWriter.cs index ad9cab83..c45e7903 100644 --- a/LSLib/LS/Resources/LSB/LSBWriter.cs +++ b/LSLib/LS/Resources/LSB/LSBWriter.cs @@ -4,19 +4,13 @@ namespace LSLib.LS { - public class LSBWriter + public class LSBWriter(Stream stream) { - private Stream stream; private BinaryWriter writer; - private Dictionary staticStrings = new Dictionary(); + private Dictionary staticStrings = []; private UInt32 nextStaticStringId = 0; private UInt32 Version; - public LSBWriter(Stream stream) - { - this.stream = stream; - } - public void Write(Resource rsrc) { Version = rsrc.Metadata.MajorVersion; @@ -62,7 +56,7 @@ private void WriteRegions(Resource rsrc) writer.Write((UInt32)0); // Offset of region, will be updater after we finished serializing } - List regionPositions = new List(); + List regionPositions = []; foreach (var rgn in rsrc.Regions) { regionPositions.Add((UInt32)stream.Position); diff --git a/LSLib/LS/Resources/LSF/LSFCommon.cs b/LSLib/LS/Resources/LSF/LSFCommon.cs index 1de8bc1a..70141db9 100644 --- a/LSLib/LS/Resources/LSF/LSFCommon.cs +++ b/LSLib/LS/Resources/LSF/LSFCommon.cs @@ -9,7 +9,7 @@ internal struct LSFMagic /// /// LSOF file signature /// - public static byte[] Signature = new byte[] { 0x4C, 0x53, 0x4F, 0x46 }; + public readonly static byte[] Signature = "LSOF"u8.ToArray(); /// /// LSOF file signature; should be the same as LSFHeader.Signature diff --git a/LSLib/LS/Resources/LSF/LSFReader.cs b/LSLib/LS/Resources/LSF/LSFReader.cs index c095c0e6..20c53190 100644 --- a/LSLib/LS/Resources/LSF/LSFReader.cs +++ b/LSLib/LS/Resources/LSF/LSFReader.cs @@ -9,12 +9,12 @@ namespace LSLib.LS { - public class LSFReader : IDisposable + public class LSFReader(Stream stream) : IDisposable { /// /// Input stream /// - private Stream Stream; + private readonly Stream Stream = stream; /// /// Static string hash map @@ -46,11 +46,6 @@ public class LSFReader : IDisposable private PackedVersion GameVersion; private LSFMetadataV6 Metadata; - public LSFReader(Stream stream) - { - this.Stream = stream; - } - public void Dispose() { Stream.Dispose(); @@ -72,25 +67,23 @@ private void ReadNames(Stream s) // L x 16-bit string length (S) // [S bytes of UTF-8 string data] - using (var reader = new BinaryReader(s)) + using var reader = new BinaryReader(s); + var numHashEntries = reader.ReadUInt32(); + while (numHashEntries-- > 0) { - var numHashEntries = reader.ReadUInt32(); - while (numHashEntries-- > 0) - { - var hash = new List(); - Names.Add(hash); + var hash = new List(); + Names.Add(hash); - var numStrings = reader.ReadUInt16(); - while (numStrings-- > 0) - { - var nameLen = reader.ReadUInt16(); - byte[] bytes = reader.ReadBytes(nameLen); - var name = System.Text.Encoding.UTF8.GetString(bytes); - hash.Add(name); + var numStrings = reader.ReadUInt16(); + while (numStrings-- > 0) + { + var nameLen = reader.ReadUInt16(); + byte[] bytes = reader.ReadBytes(nameLen); + var name = System.Text.Encoding.UTF8.GetString(bytes); + hash.Add(name); #if DEBUG_LSF_SERIALIZATION - Console.WriteLine(String.Format("{0,3:X}/{1}: {2}", Names.Count - 1, hash.Count - 1, name)); + Console.WriteLine(String.Format("{0,3:X}/{1}: {2}", Names.Count - 1, hash.Count - 1, name)); #endif - } } } } @@ -106,44 +99,42 @@ private void ReadNodes(Stream s, bool longNodes) Console.WriteLine(" ----- DUMP OF NODE TABLE -----"); #endif - using (var reader = new BinaryReader(s)) + using var reader = new BinaryReader(s); + Int32 index = 0; + while (s.Position < s.Length) { - Int32 index = 0; - while (s.Position < s.Length) - { - var resolved = new LSFNodeInfo(); + var resolved = new LSFNodeInfo(); #if DEBUG_LSF_SERIALIZATION var pos = s.Position; #endif - if (longNodes) - { - var item = BinUtils.ReadStruct(reader); - resolved.ParentIndex = item.ParentIndex; - resolved.NameIndex = item.NameIndex; - resolved.NameOffset = item.NameOffset; - resolved.FirstAttributeIndex = item.FirstAttributeIndex; - } - else - { - var item = BinUtils.ReadStruct(reader); - resolved.ParentIndex = item.ParentIndex; - resolved.NameIndex = item.NameIndex; - resolved.NameOffset = item.NameOffset; - resolved.FirstAttributeIndex = item.FirstAttributeIndex; - } + if (longNodes) + { + var item = BinUtils.ReadStruct(reader); + resolved.ParentIndex = item.ParentIndex; + resolved.NameIndex = item.NameIndex; + resolved.NameOffset = item.NameOffset; + resolved.FirstAttributeIndex = item.FirstAttributeIndex; + } + else + { + var item = BinUtils.ReadStruct(reader); + resolved.ParentIndex = item.ParentIndex; + resolved.NameIndex = item.NameIndex; + resolved.NameOffset = item.NameOffset; + resolved.FirstAttributeIndex = item.FirstAttributeIndex; + } #if DEBUG_LSF_SERIALIZATION - Console.WriteLine(String.Format( - "{0}: {1} @ {2:X} (parent {3}, firstAttribute {4})", - index, Names[resolved.NameIndex][resolved.NameOffset], pos, resolved.ParentIndex, - resolved.FirstAttributeIndex - )); + Console.WriteLine(String.Format( + "{0}: {1} @ {2:X} (parent {3}, firstAttribute {4})", + index, Names[resolved.NameIndex][resolved.NameOffset], pos, resolved.ParentIndex, + resolved.FirstAttributeIndex + )); #endif - Nodes.Add(resolved); - index++; - } + Nodes.Add(resolved); + index++; } } @@ -153,79 +144,79 @@ private void ReadNodes(Stream s, bool longNodes) /// Stream to read the attribute headers from private void ReadAttributesV2(Stream s) { - using (var reader = new BinaryReader(s)) - { + using var reader = new BinaryReader(s); #if DEBUG_LSF_SERIALIZATION - var rawAttributes = new List(); + var rawAttributes = new List(); #endif - var prevAttributeRefs = new List(); - UInt32 dataOffset = 0; - Int32 index = 0; - while (s.Position < s.Length) + var prevAttributeRefs = new List(); + UInt32 dataOffset = 0; + Int32 index = 0; + while (s.Position < s.Length) + { + var attribute = BinUtils.ReadStruct(reader); + + var resolved = new LSFAttributeInfo { - var attribute = BinUtils.ReadStruct(reader); - - var resolved = new LSFAttributeInfo(); - resolved.NameIndex = attribute.NameIndex; - resolved.NameOffset = attribute.NameOffset; - resolved.TypeId = attribute.TypeId; - resolved.Length = attribute.Length; - resolved.DataOffset = dataOffset; - resolved.NextAttributeIndex = -1; - - var nodeIndex = attribute.NodeIndex + 1; - if (prevAttributeRefs.Count > nodeIndex) - { - if (prevAttributeRefs[nodeIndex] != -1) - { - Attributes[prevAttributeRefs[nodeIndex]].NextAttributeIndex = index; - } + NameIndex = attribute.NameIndex, + NameOffset = attribute.NameOffset, + TypeId = attribute.TypeId, + Length = attribute.Length, + DataOffset = dataOffset, + NextAttributeIndex = -1 + }; - prevAttributeRefs[nodeIndex] = index; - } - else + var nodeIndex = attribute.NodeIndex + 1; + if (prevAttributeRefs.Count > nodeIndex) + { + if (prevAttributeRefs[nodeIndex] != -1) { - while (prevAttributeRefs.Count < nodeIndex) - { - prevAttributeRefs.Add(-1); - } + Attributes[prevAttributeRefs[nodeIndex]].NextAttributeIndex = index; + } - prevAttributeRefs.Add(index); + prevAttributeRefs[nodeIndex] = index; + } + else + { + while (prevAttributeRefs.Count < nodeIndex) + { + prevAttributeRefs.Add(-1); } + prevAttributeRefs.Add(index); + } + #if DEBUG_LSF_SERIALIZATION rawAttributes.Add(attribute); #endif - dataOffset += resolved.Length; - Attributes.Add(resolved); - index++; - } + dataOffset += resolved.Length; + Attributes.Add(resolved); + index++; + } #if DEBUG_LSF_SERIALIZATION - Console.WriteLine(" ----- DUMP OF ATTRIBUTE REFERENCES -----"); - for (int i = 0; i < prevAttributeRefs.Count; i++) - { - Console.WriteLine(String.Format("Node {0}: last attribute {1}", i, prevAttributeRefs[i])); - } + Console.WriteLine(" ----- DUMP OF ATTRIBUTE REFERENCES -----"); + for (int i = 0; i < prevAttributeRefs.Count; i++) + { + Console.WriteLine(String.Format("Node {0}: last attribute {1}", i, prevAttributeRefs[i])); + } - Console.WriteLine(" ----- DUMP OF V2 ATTRIBUTE TABLE -----"); - for (int i = 0; i < Attributes.Count; i++) - { - var resolved = Attributes[i]; - var attribute = rawAttributes[i]; - - var debug = String.Format( - "{0}: {1} (offset {2:X}, typeId {3}, nextAttribute {4}, node {5})", - i, Names[resolved.NameIndex][resolved.NameOffset], resolved.DataOffset, - resolved.TypeId, resolved.NextAttributeIndex, attribute.NodeIndex - ); - Console.WriteLine(debug); - } -#endif + Console.WriteLine(" ----- DUMP OF V2 ATTRIBUTE TABLE -----"); + for (int i = 0; i < Attributes.Count; i++) + { + var resolved = Attributes[i]; + var attribute = rawAttributes[i]; + + var debug = String.Format( + "{0}: {1} (offset {2:X}, typeId {3}, nextAttribute {4}, node {5})", + i, Names[resolved.NameIndex][resolved.NameOffset], resolved.DataOffset, + resolved.TypeId, resolved.NextAttributeIndex, attribute.NodeIndex + ); + Console.WriteLine(debug); } +#endif } /// @@ -234,38 +225,38 @@ private void ReadAttributesV2(Stream s) /// Stream to read the attribute headers from private void ReadAttributesV3(Stream s) { - using (var reader = new BinaryReader(s)) + using var reader = new BinaryReader(s); + while (s.Position < s.Length) { - while (s.Position < s.Length) - { - var attribute = BinUtils.ReadStruct(reader); + var attribute = BinUtils.ReadStruct(reader); - var resolved = new LSFAttributeInfo(); - resolved.NameIndex = attribute.NameIndex; - resolved.NameOffset = attribute.NameOffset; - resolved.TypeId = attribute.TypeId; - resolved.Length = attribute.Length; - resolved.DataOffset = attribute.Offset; - resolved.NextAttributeIndex = attribute.NextAttributeIndex; + var resolved = new LSFAttributeInfo + { + NameIndex = attribute.NameIndex, + NameOffset = attribute.NameOffset, + TypeId = attribute.TypeId, + Length = attribute.Length, + DataOffset = attribute.Offset, + NextAttributeIndex = attribute.NextAttributeIndex + }; - Attributes.Add(resolved); - } + Attributes.Add(resolved); + } #if DEBUG_LSF_SERIALIZATION - Console.WriteLine(" ----- DUMP OF V3 ATTRIBUTE TABLE -----"); - for (int i = 0; i < Attributes.Count; i++) - { - var resolved = Attributes[i]; - - var debug = String.Format( - "{0}: {1} (offset {2:X}, typeId {3}, nextAttribute {4})", - i, Names[resolved.NameIndex][resolved.NameOffset], resolved.DataOffset, - resolved.TypeId, resolved.NextAttributeIndex - ); - Console.WriteLine(debug); - } -#endif + Console.WriteLine(" ----- DUMP OF V3 ATTRIBUTE TABLE -----"); + for (int i = 0; i < Attributes.Count; i++) + { + var resolved = Attributes[i]; + + var debug = String.Format( + "{0}: {1} (offset {2:X}, typeId {3}, nextAttribute {4})", + i, Names[resolved.NameIndex][resolved.NameOffset], resolved.DataOffset, + resolved.TypeId, resolved.NextAttributeIndex + ); + Console.WriteLine(debug); } +#endif } private MemoryStream Decompress(BinaryReader reader, uint sizeOnDisk, uint uncompressedSize, string debugDumpTo, bool allowChunked) @@ -370,60 +361,58 @@ private void ReadHeaders(BinaryReader reader) public Resource Read() { - using (var reader = new BinaryReader(Stream)) + using var reader = new BinaryReader(Stream); + ReadHeaders(reader); + + Names = []; + var namesStream = Decompress(reader, Metadata.StringsSizeOnDisk, Metadata.StringsUncompressedSize, "strings.bin", false); + using (namesStream) { - ReadHeaders(reader); + ReadNames(namesStream); + } - Names = new List>(); - var namesStream = Decompress(reader, Metadata.StringsSizeOnDisk, Metadata.StringsUncompressedSize, "strings.bin", false); - using (namesStream) - { - ReadNames(namesStream); - } + Nodes = []; + var nodesStream = Decompress(reader, Metadata.NodesSizeOnDisk, Metadata.NodesUncompressedSize, "nodes.bin", true); + using (nodesStream) + { + var longNodes = Version >= LSFVersion.VerExtendedNodes + && Metadata.HasSiblingData == 1; + ReadNodes(nodesStream, longNodes); + } - Nodes = new List(); - var nodesStream = Decompress(reader, Metadata.NodesSizeOnDisk, Metadata.NodesUncompressedSize, "nodes.bin", true); - using (nodesStream) + Attributes = []; + var attributesStream = Decompress(reader, Metadata.AttributesSizeOnDisk, Metadata.AttributesUncompressedSize, "attributes.bin", true); + using (attributesStream) + { + var hasSiblingData = Version >= LSFVersion.VerExtendedNodes + && Metadata.HasSiblingData == 1; + if (hasSiblingData) { - var longNodes = Version >= LSFVersion.VerExtendedNodes - && Metadata.HasSiblingData == 1; - ReadNodes(nodesStream, longNodes); + ReadAttributesV3(attributesStream); } - - Attributes = new List(); - var attributesStream = Decompress(reader, Metadata.AttributesSizeOnDisk, Metadata.AttributesUncompressedSize, "attributes.bin", true); - using (attributesStream) + else { - var hasSiblingData = Version >= LSFVersion.VerExtendedNodes - && Metadata.HasSiblingData == 1; - if (hasSiblingData) - { - ReadAttributesV3(attributesStream); - } - else - { - ReadAttributesV2(attributesStream); - } + ReadAttributesV2(attributesStream); } + } - this.Values = Decompress(reader, Metadata.ValuesSizeOnDisk, Metadata.ValuesUncompressedSize, "values.bin", true); + this.Values = Decompress(reader, Metadata.ValuesSizeOnDisk, Metadata.ValuesUncompressedSize, "values.bin", true); - Resource resource = new Resource(); - ReadRegions(resource); + Resource resource = new(); + ReadRegions(resource); - resource.Metadata.MajorVersion = GameVersion.Major; - resource.Metadata.MinorVersion = GameVersion.Minor; - resource.Metadata.Revision = GameVersion.Revision; - resource.Metadata.BuildNumber = GameVersion.Build; + resource.Metadata.MajorVersion = GameVersion.Major; + resource.Metadata.MinorVersion = GameVersion.Minor; + resource.Metadata.Revision = GameVersion.Revision; + resource.Metadata.BuildNumber = GameVersion.Build; - return resource; - } + return resource; } private void ReadRegions(Resource resource) { var attrReader = new BinaryReader(Values); - NodeInstances = new List(); + NodeInstances = []; for (int i = 0; i < Nodes.Count; i++) { var defn = Nodes[i]; @@ -493,8 +482,10 @@ private NodeAttribute ReadAttribute(NodeAttribute.DataType type, BinaryReader re case NodeAttribute.DataType.DT_WString: case NodeAttribute.DataType.DT_LSWString: { - var attr = new NodeAttribute(type); - attr.Value = ReadString(reader, (int)length); + var attr = new NodeAttribute(type) + { + Value = ReadString(reader, (int)length) + }; return attr; } @@ -526,15 +517,19 @@ private NodeAttribute ReadAttribute(NodeAttribute.DataType type, BinaryReader re case NodeAttribute.DataType.DT_TranslatedFSString: { - var attr = new NodeAttribute(type); - attr.Value = ReadTranslatedFSString(reader); + var attr = new NodeAttribute(type) + { + Value = ReadTranslatedFSString(reader) + }; return attr; } case NodeAttribute.DataType.DT_ScratchBuffer: { - var attr = new NodeAttribute(type); - attr.Value = reader.ReadBytes((int)length); + var attr = new NodeAttribute(type) + { + Value = reader.ReadBytes((int)length) + }; return attr; } @@ -600,7 +595,7 @@ private string ReadString(BinaryReader reader, int length) private string ReadString(BinaryReader reader) { - List bytes = new List(); + List bytes = []; while (true) { var b = reader.ReadByte(); diff --git a/LSLib/LS/Resources/LSF/LSFWriter.cs b/LSLib/LS/Resources/LSF/LSFWriter.cs index 477d3fd6..ae4df84f 100644 --- a/LSLib/LS/Resources/LSF/LSFWriter.cs +++ b/LSLib/LS/Resources/LSF/LSFWriter.cs @@ -6,11 +6,11 @@ namespace LSLib.LS { - public class LSFWriter + public class LSFWriter(Stream stream) { - private static int StringHashMapSize = 0x200; + private readonly static int StringHashMapSize = 0x200; - private Stream Stream; + private readonly Stream Stream = stream; private BinaryWriter Writer; private LSMetadata Meta; @@ -32,12 +32,7 @@ public class LSFWriter public LSFVersion Version = LSFVersion.MaxWriteVersion; public bool EncodeSiblingData = false; public CompressionMethod Compression = CompressionMethod.LZ4; - public CompressionLevel CompressionLevel = CompressionLevel.DefaultCompression; - - public LSFWriter(Stream stream) - { - this.Stream = stream; - } + public LSCompressionLevel LSCompressionLevel = LSCompressionLevel.DefaultCompression; public void Write(Resource resource) { @@ -59,12 +54,12 @@ public void Write(Resource resource) { NextNodeIndex = 0; NextAttributeIndex = 0; - NodeIndices = new Dictionary(); + NodeIndices = []; NextSiblingIndices = null; StringHashMap = new List>(StringHashMapSize); while (StringHashMap.Count < StringHashMapSize) { - StringHashMap.Add(new List()); + StringHashMap.Add([]); } if (EncodeSiblingData) @@ -86,12 +81,14 @@ public void Write(Resource resource) var attributeBuffer = AttributeStream.ToArray(); var valueBuffer = ValueStream.ToArray(); - var magic = new LSFMagic(); - magic.Magic = BitConverter.ToUInt32(LSFMagic.Signature, 0); - magic.Version = (uint)Version; + var magic = new LSFMagic + { + Magic = BitConverter.ToUInt32(LSFMagic.Signature, 0), + Version = (uint)Version + }; BinUtils.WriteStruct(Writer, ref magic); - PackedVersion gameVersion = new PackedVersion + PackedVersion gameVersion = new() { Major = resource.Metadata.MajorVersion, Minor = resource.Metadata.MinorVersion, @@ -101,30 +98,36 @@ public void Write(Resource resource) if (Version < LSFVersion.VerBG3ExtendedHeader) { - var header = new LSFHeader(); - header.EngineVersion = gameVersion.ToVersion32(); + var header = new LSFHeader + { + EngineVersion = gameVersion.ToVersion32() + }; BinUtils.WriteStruct(Writer, ref header); } else { - var header = new LSFHeaderV5(); - header.EngineVersion = gameVersion.ToVersion64(); + var header = new LSFHeaderV5 + { + EngineVersion = gameVersion.ToVersion64() + }; BinUtils.WriteStruct(Writer, ref header); } bool chunked = Version >= LSFVersion.VerChunkedCompress; - byte[] stringsCompressed = BinUtils.Compress(stringBuffer, Compression, CompressionLevel); - byte[] nodesCompressed = BinUtils.Compress(nodeBuffer, Compression, CompressionLevel, chunked); - byte[] attributesCompressed = BinUtils.Compress(attributeBuffer, Compression, CompressionLevel, chunked); - byte[] valuesCompressed = BinUtils.Compress(valueBuffer, Compression, CompressionLevel, chunked); + byte[] stringsCompressed = BinUtils.Compress(stringBuffer, Compression, LSCompressionLevel); + byte[] nodesCompressed = BinUtils.Compress(nodeBuffer, Compression, LSCompressionLevel, chunked); + byte[] attributesCompressed = BinUtils.Compress(attributeBuffer, Compression, LSCompressionLevel, chunked); + byte[] valuesCompressed = BinUtils.Compress(valueBuffer, Compression, LSCompressionLevel, chunked); if (Version < LSFVersion.VerBG3AdditionalBlob) { - var meta = new LSFMetadataV5(); - meta.StringsUncompressedSize = (UInt32)stringBuffer.Length; - meta.NodesUncompressedSize = (UInt32)nodeBuffer.Length; - meta.AttributesUncompressedSize = (UInt32)attributeBuffer.Length; - meta.ValuesUncompressedSize = (UInt32)valueBuffer.Length; + var meta = new LSFMetadataV5 + { + StringsUncompressedSize = (UInt32)stringBuffer.Length, + NodesUncompressedSize = (UInt32)nodeBuffer.Length, + AttributesUncompressedSize = (UInt32)attributeBuffer.Length, + ValuesUncompressedSize = (UInt32)valueBuffer.Length + }; if (Compression == CompressionMethod.None) { @@ -141,7 +144,7 @@ public void Write(Resource resource) meta.ValuesSizeOnDisk = (UInt32)valuesCompressed.Length; } - meta.CompressionFlags = BinUtils.MakeCompressionFlags(Compression, CompressionLevel); + meta.CompressionFlags = BinUtils.MakeCompressionFlags(Compression, LSCompressionLevel); meta.Unknown2 = 0; meta.Unknown3 = 0; meta.HasSiblingData = EncodeSiblingData ? 1u : 0u; @@ -150,11 +153,13 @@ public void Write(Resource resource) } else { - var meta = new LSFMetadataV6(); - meta.StringsUncompressedSize = (UInt32)stringBuffer.Length; - meta.NodesUncompressedSize = (UInt32)nodeBuffer.Length; - meta.AttributesUncompressedSize = (UInt32)attributeBuffer.Length; - meta.ValuesUncompressedSize = (UInt32)valueBuffer.Length; + var meta = new LSFMetadataV6 + { + StringsUncompressedSize = (UInt32)stringBuffer.Length, + NodesUncompressedSize = (UInt32)nodeBuffer.Length, + AttributesUncompressedSize = (UInt32)attributeBuffer.Length, + ValuesUncompressedSize = (UInt32)valueBuffer.Length + }; if (Compression == CompressionMethod.None) { @@ -172,7 +177,7 @@ public void Write(Resource resource) } meta.Unknown = 0; - meta.CompressionFlags = BinUtils.MakeCompressionFlags(Compression, CompressionLevel); + meta.CompressionFlags = BinUtils.MakeCompressionFlags(Compression, LSCompressionLevel); meta.Unknown2 = 0; meta.Unknown3 = 0; meta.HasSiblingData = EncodeSiblingData ? 1u : 0u; @@ -214,7 +219,7 @@ private int ComputeSiblingIndices(Node node) private void ComputeSiblingIndices(Resource resource) { NextNodeIndex = 0; - NextSiblingIndices = new List(); + NextSiblingIndices = []; int lastRegionIndex = -1; foreach (var region in resource.Regions) @@ -484,14 +489,14 @@ private void WriteStaticStrings(BinaryWriter writer) private void WriteStaticString(BinaryWriter writer, string s) { - byte[] utf = System.Text.Encoding.UTF8.GetBytes(s); + byte[] utf = Encoding.UTF8.GetBytes(s); writer.Write((UInt16)utf.Length); writer.Write(utf); } private void WriteStringWithLength(BinaryWriter writer, string s) { - byte[] utf = System.Text.Encoding.UTF8.GetBytes(s); + byte[] utf = Encoding.UTF8.GetBytes(s); writer.Write((Int32)(utf.Length + 1)); writer.Write(utf); writer.Write((Byte)0); @@ -499,7 +504,7 @@ private void WriteStringWithLength(BinaryWriter writer, string s) private void WriteString(BinaryWriter writer, string s) { - byte[] utf = System.Text.Encoding.UTF8.GetBytes(s); + byte[] utf = Encoding.UTF8.GetBytes(s); writer.Write(utf); writer.Write((Byte)0); } diff --git a/LSLib/LS/Resources/LSJ/LSJReader.cs b/LSLib/LS/Resources/LSJ/LSJReader.cs index 12b6f6cc..1d89c98c 100644 --- a/LSLib/LS/Resources/LSJ/LSJReader.cs +++ b/LSLib/LS/Resources/LSJ/LSJReader.cs @@ -4,16 +4,10 @@ namespace LSLib.LS { - public class LSJReader : IDisposable + public class LSJReader(Stream stream) : IDisposable { - private Stream stream; - private JsonTextReader reader; - public NodeSerializationSettings SerializationSettings = new NodeSerializationSettings(); - - public LSJReader(Stream stream) - { - this.stream = stream; - } + private readonly Stream stream = stream; + public NodeSerializationSettings SerializationSettings = new(); public void Dispose() { @@ -26,11 +20,9 @@ public Resource Read() settings.Converters.Add(new LSJResourceConverter(SerializationSettings)); var serializer = JsonSerializer.Create(settings); - using (var streamReader = new StreamReader(stream)) - using (this.reader = new JsonTextReader(streamReader)) - { - return serializer.Deserialize(this.reader); - } + using var streamReader = new StreamReader(stream); + using var reader = new JsonTextReader(streamReader); + return serializer.Deserialize(reader); } } } diff --git a/LSLib/LS/Resources/LSJ/LSJResourceConverter.cs b/LSLib/LS/Resources/LSJ/LSJResourceConverter.cs index bcd1ebde..d3739b82 100644 --- a/LSLib/LS/Resources/LSJ/LSJResourceConverter.cs +++ b/LSLib/LS/Resources/LSJ/LSJResourceConverter.cs @@ -4,20 +4,13 @@ using System.Text.RegularExpressions; using System.Numerics; using System.Collections.Generic; -using LSLib.LS.Story; -using System.Runtime; namespace LSLib.LS { - public class LSJResourceConverter : JsonConverter + public class LSJResourceConverter(NodeSerializationSettings settings) : JsonConverter { private LSMetadata Metadata; - private NodeSerializationSettings SerializationSettings; - - public LSJResourceConverter(NodeSerializationSettings settings) - { - SerializationSettings = settings; - } + private readonly NodeSerializationSettings SerializationSettings = settings; public override bool CanConvert(Type objectType) { @@ -163,8 +156,7 @@ private NodeAttribute ReadAttribute(JsonReader reader) { if (key == "type") { - uint type; - if (!UInt32.TryParse((string)reader.Value, out type)) + if (!UInt32.TryParse((string)reader.Value, out uint type)) { type = (uint)AttributeTypeMaps.TypeToId[(string)reader.Value]; } @@ -256,10 +248,7 @@ private NodeAttribute ReadAttribute(JsonReader reader) case NodeAttribute.DataType.DT_TranslatedString: { - if (attribute.Value == null) - { - attribute.Value = new TranslatedString(); - } + attribute.Value ??= new TranslatedString(); var ts = (TranslatedString)attribute.Value; ts.Value = reader.Value.ToString(); @@ -269,13 +258,10 @@ private NodeAttribute ReadAttribute(JsonReader reader) case NodeAttribute.DataType.DT_TranslatedFSString: { - if (attribute.Value == null) - { - attribute.Value = new TranslatedFSString(); - } + attribute.Value ??= new TranslatedFSString(); var fsString = (TranslatedFSString)attribute.Value; - fsString.Value = reader.Value != null ? reader.Value.ToString() : null; + fsString.Value = reader.Value?.ToString(); fsString.Handle = handle; fsString.Arguments = fsStringArguments; attribute.Value = fsString; @@ -349,19 +335,13 @@ private NodeAttribute ReadAttribute(JsonReader reader) { if (attribute.Type == NodeAttribute.DataType.DT_TranslatedString) { - if (attribute.Value == null) - { - attribute.Value = new TranslatedString(); - } + attribute.Value ??= new TranslatedString(); ((TranslatedString)attribute.Value).Handle = reader.Value.ToString(); } else if (attribute.Type == NodeAttribute.DataType.DT_TranslatedFSString) { - if (attribute.Value == null) - { - attribute.Value = new TranslatedFSString(); - } + attribute.Value ??= new TranslatedFSString(); ((TranslatedFSString)attribute.Value).Handle = reader.Value.ToString(); } @@ -373,10 +353,7 @@ private NodeAttribute ReadAttribute(JsonReader reader) } else if (key == "version") { - if (attribute.Value == null) - { - attribute.Value = new TranslatedString(); - } + attribute.Value ??= new TranslatedString(); var ts = (TranslatedString)attribute.Value; ts.Version = UInt16.Parse(reader.Value.ToString()); @@ -437,8 +414,10 @@ private Node ReadNode(JsonReader reader, Node node) } else if (reader.TokenType == JsonToken.StartObject) { - var childNode = new Node(); - childNode.Name = key; + var childNode = new Node + { + Name = key + }; ReadNode(reader, childNode); node.AppendChild(childNode); childNode.Parent = node; @@ -460,7 +439,7 @@ private Node ReadNode(JsonReader reader, Node node) private Resource ReadResource(JsonReader reader, Resource resource) { - if (resource == null) resource = new Resource(); + resource ??= new Resource(); if (!reader.Read() || reader.TokenType != JsonToken.PropertyName || !reader.Value.Equals("save")) { diff --git a/LSLib/LS/Resources/LSJ/LSJWriter.cs b/LSLib/LS/Resources/LSJ/LSJWriter.cs index 575616d6..64ca368f 100644 --- a/LSLib/LS/Resources/LSJ/LSJWriter.cs +++ b/LSLib/LS/Resources/LSJ/LSJWriter.cs @@ -3,32 +3,26 @@ namespace LSLib.LS { - public class LSJWriter + public class LSJWriter(Stream stream) { - private Stream stream; - private JsonTextWriter writer; + private readonly Stream stream = stream; public bool PrettyPrint = false; - public NodeSerializationSettings SerializationSettings = new NodeSerializationSettings(); - - public LSJWriter(Stream stream) - { - this.stream = stream; - } + public NodeSerializationSettings SerializationSettings = new(); public void Write(Resource rsrc) { - var settings = new JsonSerializerSettings(); - settings.Formatting = Newtonsoft.Json.Formatting.Indented; + var settings = new JsonSerializerSettings + { + Formatting = Formatting.Indented + }; settings.Converters.Add(new LSJResourceConverter(SerializationSettings)); var serializer = JsonSerializer.Create(settings); - using (var streamWriter = new StreamWriter(stream)) - using (this.writer = new JsonTextWriter(streamWriter)) - { - writer.IndentChar = '\t'; - writer.Indentation = 1; - serializer.Serialize(writer, rsrc); - } + using var streamWriter = new StreamWriter(stream); + using var writer = new JsonTextWriter(streamWriter); + writer.IndentChar = '\t'; + writer.Indentation = 1; + serializer.Serialize(writer, rsrc); } } } diff --git a/LSLib/LS/Resources/LSX/LSXReader.cs b/LSLib/LS/Resources/LSX/LSXReader.cs index 22f9e5f9..c8d495f0 100644 --- a/LSLib/LS/Resources/LSX/LSXReader.cs +++ b/LSLib/LS/Resources/LSX/LSXReader.cs @@ -8,21 +8,16 @@ namespace LSLib.LS { - public class LSXReader : IDisposable + public class LSXReader(Stream stream) : IDisposable { - private Stream stream; + private Stream stream = stream; private XmlReader reader; private Resource resource; private Region currentRegion; private List stack; private int lastLine, lastColumn; private LSXVersion Version = LSXVersion.V3; - public NodeSerializationSettings SerializationSettings = new NodeSerializationSettings(); - - public LSXReader(Stream stream) - { - this.stream = stream; - } + public NodeSerializationSettings SerializationSettings = new(); public void Dispose() { @@ -55,9 +50,11 @@ private void ReadTranslatedFSString(TranslatedFSString fs) throw new InvalidFormatException(String.Format("Expected : {0}", reader.Name)); } - var arg = new TranslatedFSStringArgument(); - arg.Key = reader["key"]; - arg.Value = reader["value"]; + var arg = new TranslatedFSStringArgument + { + Key = reader["key"], + Value = reader["value"] + }; while (reader.Read() && reader.NodeType != XmlNodeType.Element); if (reader.Name != "string") @@ -88,7 +85,7 @@ private void ReadElement() { case "save": // Root element - if (stack.Count() > 0) + if (stack.Count > 0) throw new InvalidFormatException("Node was unexpected."); break; @@ -125,7 +122,7 @@ private void ReadElement() throw new InvalidFormatException("A must be located inside a region."); Node node; - if (stack.Count() == 0) + if (stack.Count == 0) { // The node is the root node of the region node = currentRegion; @@ -133,14 +130,15 @@ private void ReadElement() else { // New node under the current parent - node = new Node(); - node.Parent = stack.Last(); + node = new Node + { + Parent = stack.Last() + }; } node.Name = reader["id"]; Debug.Assert(node.Name != null); - if (node.Parent != null) - node.Parent.AppendChild(node); + node.Parent?.AppendChild(node); if (!reader.IsEmptyElement) stack.Add(node); @@ -168,10 +166,7 @@ private void ReadElement() if (attr.Type == NodeAttribute.DataType.DT_TranslatedString) { - if (attr.Value == null) - { - attr.Value = new TranslatedString(); - } + attr.Value ??= new TranslatedString(); var ts = ((TranslatedString)attr.Value); ts.Handle = reader["handle"]; @@ -258,7 +253,7 @@ public Resource Read() { resource = new Resource(); currentRegion = null; - stack = new List(); + stack = []; lastLine = lastColumn = 0; var resultResource = resource; diff --git a/LSLib/LS/Resources/LSX/LSXWriter.cs b/LSLib/LS/Resources/LSX/LSXWriter.cs index e765ec52..49488ae4 100644 --- a/LSLib/LS/Resources/LSX/LSXWriter.cs +++ b/LSLib/LS/Resources/LSX/LSXWriter.cs @@ -5,19 +5,14 @@ namespace LSLib.LS { - public class LSXWriter + public class LSXWriter(Stream stream) { - private Stream stream; + private readonly Stream stream = stream; private XmlWriter writer; public bool PrettyPrint = false; public LSXVersion Version = LSXVersion.V3; - public NodeSerializationSettings SerializationSettings = new NodeSerializationSettings(); - - public LSXWriter(Stream stream) - { - this.stream = stream; - } + public NodeSerializationSettings SerializationSettings = new(); public void Write(Resource rsrc) { @@ -26,9 +21,11 @@ public void Write(Resource rsrc) throw new InvalidDataException("Cannot resave a BG3 (v4.x) resource in D:OS2 (v3.x) file format, maybe you have the wrong game selected?"); } - var settings = new XmlWriterSettings(); - settings.Indent = PrettyPrint; - settings.IndentChars = "\t"; + var settings = new XmlWriterSettings + { + Indent = PrettyPrint, + IndentChars = "\t" + }; using (this.writer = XmlWriter.Create(stream, settings)) { diff --git a/LSLib/LS/Save/SavegameHelpers.cs b/LSLib/LS/Save/SavegameHelpers.cs index 58985ce5..938a8c43 100644 --- a/LSLib/LS/Save/SavegameHelpers.cs +++ b/LSLib/LS/Save/SavegameHelpers.cs @@ -10,8 +10,8 @@ namespace LSLib.LS.Save { public class SavegameHelpers : IDisposable { - private PackageReader Reader; - private Package Package; + private readonly PackageReader Reader; + private readonly Package Package; public SavegameHelpers(string path) { @@ -36,10 +36,8 @@ public Resource LoadGlobals() Stream rsrcStream = globalsInfo.MakeStream(); try { - using (var rsrcReader = new LSFReader(rsrcStream)) - { - resource = rsrcReader.Read(); - } + using var rsrcReader = new LSFReader(rsrcStream); + resource = rsrcReader.Read(); } finally { @@ -96,9 +94,11 @@ public MemoryStream ResaveStoryToGlobals(Story.Story story, ResourceConversionPa // Save globals.lsf var rewrittenStream = new MemoryStream(); - var rsrcWriter = new LSFWriter(rewrittenStream); - rsrcWriter.Version = conversionParams.LSF; - rsrcWriter.EncodeSiblingData = false; + var rsrcWriter = new LSFWriter(rewrittenStream) + { + Version = conversionParams.LSF, + EncodeSiblingData = false + }; rsrcWriter.Write(globals); rewrittenStream.Seek(0, SeekOrigin.Begin); return rewrittenStream; @@ -141,7 +141,7 @@ public void ResaveStory(Story.Story story, Game game, string path) { packageWriter.Version = conversionParams.PAKVersion; packageWriter.Compression = CompressionMethod.Zlib; - packageWriter.CompressionLevel = CompressionLevel.DefaultCompression; + packageWriter.LSCompressionLevel = LSCompressionLevel.DefaultCompression; packageWriter.Write(); } } diff --git a/LSLib/LS/Save/VariableManager.cs b/LSLib/LS/Save/VariableManager.cs index 4e91e49a..bbc3476b 100644 --- a/LSLib/LS/Save/VariableManager.cs +++ b/LSLib/LS/Save/VariableManager.cs @@ -1,19 +1,17 @@ -using OpenTK; +using OpenTK.Mathematics; using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Runtime.InteropServices; using System.Text; -using System.Threading.Tasks; namespace LSLib.LS.Save { public class OsirisVariableHelper { private Int32 NumericStringId; - private Dictionary IdentifierToKey = new Dictionary(); - private Dictionary KeyToIdentifier = new Dictionary(); + private Dictionary IdentifierToKey = []; + private Dictionary KeyToIdentifier = []; public void Load(Node helper) { @@ -41,14 +39,14 @@ public string GetName(Int32 variableIndex) abstract public class VariableHolder { - protected List Values = new List(); - private List Remaps = new List(); + protected List Values = []; + private List Remaps = []; public TValue GetRaw(int index) { if (index == 0) { - return default(TValue); + return default; } var valueSlot = Remaps[index - 1]; @@ -64,13 +62,11 @@ public void Load(Node variableList) Remaps.Clear(); Remaps.Capacity = remaps.Length / 2; - using (var ms = new MemoryStream(remaps)) - using (var reader = new BinaryReader(ms)) + using var ms = new MemoryStream(remaps); + using var reader = new BinaryReader(ms); + for (var i = 0; i < remaps.Length / 2; i++) { - for (var i = 0; i < remaps.Length/2; i++) - { - Remaps.Add(reader.ReadUInt16()); - } + Remaps.Add(reader.ReadUInt16()); } } @@ -100,13 +96,11 @@ override protected void LoadVariables(Node variableList) Values.Clear(); Values.Capacity = numVars; - using (var ms = new MemoryStream(variables)) - using (var reader = new BinaryReader(ms)) + using var ms = new MemoryStream(variables); + using var reader = new BinaryReader(ms); + for (var i = 0; i < numVars; i++) { - for (var i = 0; i < numVars; i++) - { - Values.Add(reader.ReadInt32()); - } + Values.Add(reader.ReadInt32()); } } } @@ -134,13 +128,11 @@ override protected void LoadVariables(Node variableList) Values.Clear(); Values.Capacity = numVars; - using (var ms = new MemoryStream(variables)) - using (var reader = new BinaryReader(ms)) + using var ms = new MemoryStream(variables); + using var reader = new BinaryReader(ms); + for (var i = 0; i < numVars; i++) { - for (var i = 0; i < numVars; i++) - { - Values.Add(reader.ReadInt64()); - } + Values.Add(reader.ReadInt64()); } } } @@ -169,13 +161,11 @@ override protected void LoadVariables(Node variableList) Values.Clear(); Values.Capacity = numVars; - using (var ms = new MemoryStream(variables)) - using (var reader = new BinaryReader(ms)) + using var ms = new MemoryStream(variables); + using var reader = new BinaryReader(ms); + for (var i = 0; i < numVars; i++) { - for (var i = 0; i < numVars; i++) - { - Values.Add(reader.ReadSingle()); - } + Values.Add(reader.ReadSingle()); } } } @@ -199,21 +189,19 @@ override protected void LoadVariables(Node variableList) { var variables = (byte[])variableList.Attributes["Variables"].Value; - using (var ms = new MemoryStream(variables)) - using (var reader = new BinaryReader(ms)) - { - var numVars = reader.ReadInt32(); + using var ms = new MemoryStream(variables); + using var reader = new BinaryReader(ms); + var numVars = reader.ReadInt32(); - Values.Clear(); - Values.Capacity = numVars; + Values.Clear(); + Values.Capacity = numVars; - for (var i = 0; i < numVars; i++) - { - var length = reader.ReadUInt16(); - var bytes = reader.ReadBytes(length); - var str = Encoding.UTF8.GetString(bytes); - Values.Add(str); - } + for (var i = 0; i < numVars; i++) + { + var length = reader.ReadUInt16(); + var bytes = reader.ReadBytes(length); + var str = Encoding.UTF8.GetString(bytes); + Values.Add(str); } } } @@ -242,19 +230,17 @@ override protected void LoadVariables(Node variableList) Values.Clear(); Values.Capacity = numVars; - using (var ms = new MemoryStream(variables)) - using (var reader = new BinaryReader(ms)) + using var ms = new MemoryStream(variables); + using var reader = new BinaryReader(ms); + for (var i = 0; i < numVars; i++) { - for (var i = 0; i < numVars; i++) + Vector3 vec = new() { - Vector3 vec = new Vector3 - { - X = reader.ReadSingle(), - Y = reader.ReadSingle(), - Z = reader.ReadSingle() - }; - Values.Add(vec); - } + X = reader.ReadSingle(), + Y = reader.ReadSingle(), + Z = reader.ReadSingle() + }; + Values.Add(vec); } } } @@ -305,28 +291,22 @@ public VariableType ValueType } }; - public class VariableManager + public class VariableManager(OsirisVariableHelper variableHelper) { - private readonly OsirisVariableHelper VariableHelper; - private readonly Dictionary Keys = new Dictionary(); - private readonly IntVariableHolder IntList = new IntVariableHolder(); - private readonly Int64VariableHolder Int64List = new Int64VariableHolder(); - private readonly FloatVariableHolder FloatList = new FloatVariableHolder(); - private readonly StringVariableHolder StringList = new StringVariableHolder(); - private readonly StringVariableHolder FixedStringList = new StringVariableHolder(); - private readonly Float3VariableHolder Float3List = new Float3VariableHolder(); - - public VariableManager(OsirisVariableHelper variableHelper) - { - VariableHelper = variableHelper; - } + private readonly Dictionary Keys = []; + private readonly IntVariableHolder IntList = new(); + private readonly Int64VariableHolder Int64List = new(); + private readonly FloatVariableHolder FloatList = new(); + private readonly StringVariableHolder StringList = new(); + private readonly StringVariableHolder FixedStringList = new(); + private readonly Float3VariableHolder Float3List = new(); public Dictionary GetAll(bool includeDeleted = false) { var variables = new Dictionary(); foreach (var key in Keys.Values) { - var name = VariableHelper.GetName((int)key.NameIndex); + var name = variableHelper.GetName((int)key.NameIndex); var value = includeDeleted ? GetRaw(key.ValueType, key.ValueIndex) : Get(key.ValueType, key.ValueIndex); if (value != null) { @@ -339,59 +319,57 @@ public Dictionary GetAll(bool includeDeleted = false) public object Get(string name) { - var index = VariableHelper.GetKey(name); + var index = variableHelper.GetKey(name); var key = Keys[index]; return Get(key.ValueType, key.ValueIndex); } private object Get(VariableType type, int index) { - switch (type) + return type switch { - case VariableType.Int: return IntList.Get(index); - case VariableType.Int64: return Int64List.Get(index); - case VariableType.Float: return FloatList.Get(index); - case VariableType.String: return StringList.Get(index); - case VariableType.FixedString: return FixedStringList.Get(index); - case VariableType.Float3: return Float3List.Get(index); - default: throw new ArgumentException("Unsupported variable type"); - } + VariableType.Int => IntList.Get(index), + VariableType.Int64 => Int64List.Get(index), + VariableType.Float => FloatList.Get(index), + VariableType.String => StringList.Get(index), + VariableType.FixedString => FixedStringList.Get(index), + VariableType.Float3 => Float3List.Get(index), + _ => throw new ArgumentException("Unsupported variable type"), + }; } public object GetRaw(string name) { - var index = VariableHelper.GetKey(name); + var index = variableHelper.GetKey(name); var key = Keys[index]; return GetRaw(key.ValueType, key.ValueIndex); } private object GetRaw(VariableType type, int index) { - switch (type) + return type switch { - case VariableType.Int: return IntList.GetRaw(index); - case VariableType.Int64: return Int64List.GetRaw(index); - case VariableType.Float: return FloatList.GetRaw(index); - case VariableType.String: return StringList.GetRaw(index); - case VariableType.FixedString: return FixedStringList.GetRaw(index); - case VariableType.Float3: return Float3List.GetRaw(index); - default: throw new ArgumentException("Unsupported variable type"); - } + VariableType.Int => IntList.GetRaw(index), + VariableType.Int64 => Int64List.GetRaw(index), + VariableType.Float => FloatList.GetRaw(index), + VariableType.String => StringList.GetRaw(index), + VariableType.FixedString => FixedStringList.GetRaw(index), + VariableType.Float3 => Float3List.GetRaw(index), + _ => throw new ArgumentException("Unsupported variable type"), + }; } private void LoadKeys(byte[] handleList) { Keys.Clear(); - using (var ms = new MemoryStream(handleList)) - using (var reader = new BinaryReader(ms)) + using var ms = new MemoryStream(handleList); + using var reader = new BinaryReader(ms); + var numHandles = reader.ReadInt32(); + for (var i = 0; i < numHandles; i++) { - var numHandles = reader.ReadInt32(); - for (var i = 0; i < numHandles; i++) - { - var entry = BinUtils.ReadStruct(reader); - Keys.Add((int)entry.NameIndex, entry); - } + var entry = BinUtils.ReadStruct(reader); + Keys.Add((int)entry.NameIndex, entry); } } diff --git a/LSLib/LS/Stats/ShiftReduceParser.cs b/LSLib/LS/Stats/ShiftReduceParser.cs new file mode 100644 index 00000000..f6aa09cf --- /dev/null +++ b/LSLib/LS/Stats/ShiftReduceParser.cs @@ -0,0 +1,923 @@ +// Gardens Point Parser Generator +// Copyright (c) Wayne Kelly, QUT 2005-2014 +// (see accompanying GPPGcopyright.rtf) + +using System; +using System.Text; +using System.Globalization; +using System.Collections.Generic; +using System.Runtime.Serialization; +using System.Diagnostics.CodeAnalysis; + +namespace QUT.Gppg +{ + /// + /// Abstract class for GPPG shift-reduce parsers. + /// Parsers generated by GPPG derive from this base + /// class, overriding the abstract Initialize() and + /// DoAction() methods. + /// + /// Semantic value type + /// Location type +#if EXPORT_GPPG + public abstract class ShiftReduceParser +#else + internal abstract class ShiftReduceParser +#endif + where TSpan : IMerge, new() + { + private AbstractScanner scanner; + /// + /// The abstract scanner for this parser. + /// + protected AbstractScanner Scanner + { + get { return scanner; } + set { scanner = value; } + } + + /// + /// Constructor for base class + /// + /// Scanner instance for this parser + protected ShiftReduceParser(AbstractScanner scanner) + { + this.scanner = scanner; + } + + // ============================================================== + // TECHNICAL EXPLANATION. + // Why the next two fields are not exposed via properties. + // ============================================================== + // These fields are of the generic parameter types, and are + // frequently instantiated as struct types in derived classes. + // Semantic actions are defined in the derived classes and refer + // to instance fields of these structs. In such cases the code + // "get_CurrentSemanticValue().myField = blah;" will fail since + // the getter pushes the value of the field, not the reference. + // So, in the presence of properties, gppg would need to encode + // such field accesses as ... + // "tmp = get_CurrentSemanticValue(); // Fetch value + // tmp.myField = blah; // update + // set_CurrentSemanticValue(tmp); " // Write update back. + // There is no issue if TValue is restricted to be a ref type. + // The same explanation applies to scanner.yylval. + // ============================================================== + /// + /// The current value of the "$$" symbolic variable in the parser + /// + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + protected TValue CurrentSemanticValue; + + /// + /// The current value of the "@$" symbolic variable in the parser + /// + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + protected TSpan CurrentLocationSpan; + protected int NextToken; + + private TSpan LastSpan; + private State FsaState; + private bool recovering; + private int tokensSinceLastError; + + private PushdownPrefixState StateStack = new PushdownPrefixState(); + private PushdownPrefixState valueStack = new PushdownPrefixState(); + private PushdownPrefixState locationStack = new PushdownPrefixState(); + + /// + /// The stack of semantic value (YYSTYPE) values. + /// + protected PushdownPrefixState ValueStack { get { return valueStack; } } + + /// + /// The stack of location value (YYLTYPE) varlues. + /// + protected PushdownPrefixState LocationStack { get { return locationStack; } } + + private int errorToken; + private int endOfFileToken; + private string[] nonTerminals; + private State[] states; + private Rule[] rules; + + /// + /// Initialization method to allow derived classes + /// to insert the rule list into this base class. + /// + /// The array of Rule objects + protected void InitRules(Rule[] rules) { this.rules = rules; } + + /// + /// Initialization method to allow derived classes to + /// insert the states table into this base class. + /// + /// The pre-initialized states table + protected void InitStates(State[] states) { this.states = states; } + + /// + /// OBSOLETE FOR VERSION 1.4.0 + /// + /// + protected void InitStateTable(int size) { states = new State[size]; } + + /// + /// Initialization method to allow derived classes + /// to insert the special value for the error and EOF tokens. + /// + /// The error state ordinal + /// The EOF stat ordinal + protected void InitSpecialTokens(int err, int end) + { + errorToken = err; + endOfFileToken = end; + } + + /// + /// Initialization method to allow derived classes to + /// insert the non-terminal symbol names into this base class. + /// + /// Non-terminal symbol names + protected void InitNonTerminals(string[] names) { nonTerminals = names; } + + #region YYAbort, YYAccept etcetera. + [Serializable] + [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")] + // Reason for FxCop message suppression - + // This exception cannot escape from the local context + private class AcceptException : Exception + { + internal AcceptException() { } + } + [Serializable] + [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")] + // Reason for FxCop message suppression - + // This exception cannot escape from the local context + private class AbortException : Exception + { + internal AbortException() { } + } + [Serializable] + [SuppressMessage("Microsoft.Design", "CA1064:ExceptionsShouldBePublic")] + // Reason for FxCop message suppression - + // This exception cannot escape from the local context + private class ErrorException : Exception + { + internal ErrorException() { } + } + + // The following methods are only called from within + // a semantic action. The thrown exceptions can never + // propagate outside the ShiftReduceParser class in + // which they are nested. + + /// + /// Force parser to terminate, returning "true" + /// + protected static void YYAccept() { throw new AcceptException(); } + + /// + /// Force parser to terminate, returning "false" + /// + protected static void YYAbort() { throw new AbortException(); } + + /// + /// Force parser to terminate, returning + /// "false" if error recovery fails. + /// + protected static void YYError() { throw new ErrorException(); } + + /// + /// Check if parser in error recovery state. + /// + protected bool YYRecovering { get { return recovering; } } + #endregion + + /// + /// Abstract base method. ShiftReduceParser calls this + /// to initialize the base class data structures. Concrete + /// parser classes must override this method. + /// + protected abstract void Initialize(); + + /// + /// Main entry point of the Shift-Reduce Parser. + /// + /// True if parse succeeds, else false for + /// unrecoverable errors + public bool Parse() + { + Initialize(); // allow derived classes to instantiate rules, states and nonTerminals + + NextToken = 0; + FsaState = states[0]; + + StateStack.Push(FsaState); + valueStack.Push(CurrentSemanticValue); + LocationStack.Push(CurrentLocationSpan); + + while (true) + { +#if TRACE_ACTIONS + Console.Error.WriteLine("Entering state {0} ", FsaState.number); + DisplayStack(); +#endif + int action = FsaState.defaultAction; + + if (FsaState.ParserTable != null) + { + if (NextToken == 0) + { + // We save the last token span, so that the location span + // of production right hand sides that begin or end with a + // nullable production will be correct. + LastSpan = scanner.yylloc; + NextToken = scanner.yylex(); +#if TRACE_ACTIONS + Console.Error.WriteLine( "Reading: Next token is {0}", TerminalToString( NextToken ) ); +#endif + } +#if TRACE_ACTIONS + else + Console.Error.WriteLine( "Next token is still {0}", TerminalToString( NextToken ) ); +#endif + if (FsaState.ParserTable.ContainsKey(NextToken)) + action = FsaState.ParserTable[NextToken]; + } + + if (action > 0) // shift + { + Shift(action); + } + else if (action < 0) // reduce + { + try + { + Reduce(-action); + if (action == -1) // accept + return true; + } + catch (Exception x) + { + if (x is AbortException) + return false; + else if (x is AcceptException) + return true; + else if (x is ErrorException && !ErrorRecovery()) + return false; + else + throw; // Rethrow x, preserving information. + + } + } + else if (action == 0) // error + if (!ErrorRecovery()) + return false; + } + } + + private void Shift(int stateIndex) + { +#if TRACE_ACTIONS + Console.Error.Write("Shifting token {0}, ", TerminalToString(NextToken)); +#endif + FsaState = states[stateIndex]; + + valueStack.Push(scanner.yylval); + StateStack.Push(FsaState); + LocationStack.Push(scanner.yylloc); + + if (recovering) + { + if (NextToken != errorToken) + tokensSinceLastError++; + + if (tokensSinceLastError > 5) + recovering = false; + } + + if (NextToken != endOfFileToken) + NextToken = 0; + } + + private void Reduce(int ruleNumber) + { +#if TRACE_ACTIONS + DisplayRule(ruleNumber); +#endif + Rule rule = rules[ruleNumber]; + int rhLen = rule.RightHandSide.Length; + // + // Default actions for unit productions. + // + if (rhLen == 1) + { + CurrentSemanticValue = valueStack.TopElement(); // Default action: $$ = $1; + CurrentLocationSpan = LocationStack.TopElement(); // Default action "@$ = @1; + } + else if (rhLen == 0) + { + // Create a new blank value. + // Explicit semantic action may mutate this value + CurrentSemanticValue = default(TValue); + // The location span for an empty production will start with the + // beginning of the next lexeme, and end with the finish of the + // previous lexeme. This gives the correct behaviour when this + // nonsense value is used in later Merge operations. + CurrentLocationSpan = (scanner.yylloc != null && LastSpan != null ? + scanner.yylloc.Merge(LastSpan) : + default(TSpan)); + } + else + { + // Default action: $$ = $1; + CurrentSemanticValue = valueStack[LocationStack.Depth - rhLen]; + // Default action "@$ = @1.Merge(@N)" for location info. + TSpan at1 = LocationStack[LocationStack.Depth - rhLen]; + TSpan atN = LocationStack[LocationStack.Depth - 1]; + CurrentLocationSpan = + ((at1 != null && atN != null) ? at1.Merge(atN) : default(TSpan)); + } + + DoAction(ruleNumber); + + for (int i = 0; i < rule.RightHandSide.Length; i++) + { + StateStack.Pop(); + valueStack.Pop(); + LocationStack.Pop(); + } + FsaState = StateStack.TopElement(); + + if (FsaState.Goto.ContainsKey(rule.LeftHandSide)) + FsaState = states[FsaState.Goto[rule.LeftHandSide]]; + + StateStack.Push(FsaState); + valueStack.Push(CurrentSemanticValue); + LocationStack.Push(CurrentLocationSpan); + } + + /// + /// Execute the selected action from array. + /// Must be overriden in derived classes. + /// + /// Index of the action to perform + protected abstract void DoAction(int actionNumber); + + private bool ErrorRecovery() + { + bool discard; + + if (!recovering) // if not recovering from previous error + ReportError(); + + if (!FindErrorRecoveryState()) + return false; + // + // The interim fix for the "looping in error recovery" + // artifact involved moving the setting of the recovering + // bool until after invalid tokens have been discarded. + // + ShiftErrorToken(); + discard = DiscardInvalidTokens(); + recovering = true; + tokensSinceLastError = 0; + return discard; + } + + private void ReportError() + { + StringBuilder errorMsg = new StringBuilder(); + errorMsg.AppendFormat("Syntax error, unexpected {0}", TerminalToString(NextToken)); + + if (FsaState.ParserTable.Count < 7) + { + bool first = true; + foreach (int terminal in FsaState.ParserTable.Keys) + { + if (first) + errorMsg.Append(", expecting "); + else + errorMsg.Append(", or "); + + errorMsg.Append(TerminalToString(terminal)); + first = false; + } + } + scanner.yyerror(errorMsg.ToString()); + } + + private void ShiftErrorToken() + { + int old_next = NextToken; + NextToken = errorToken; + + Shift(FsaState.ParserTable[NextToken]); + +#if TRACE_ACTIONS + Console.Error.WriteLine("Entering state {0} ", FsaState.number); +#endif + NextToken = old_next; + } + + private bool FindErrorRecoveryState() + { + while (true) // pop states until one found that accepts error token + { + if (FsaState.ParserTable != null && + FsaState.ParserTable.ContainsKey(errorToken) && + FsaState.ParserTable[errorToken] > 0) // shift + return true; + +#if TRACE_ACTIONS + Console.Error.WriteLine("Error: popping state {0}", StateStack.TopElement().number); +#endif + StateStack.Pop(); + valueStack.Pop(); + LocationStack.Pop(); + +#if TRACE_ACTIONS + DisplayStack(); +#endif + if (StateStack.IsEmpty()) + { +#if TRACE_ACTIONS + Console.Error.WriteLine("Aborting: didn't find a state that accepts error token"); +#endif + return false; + } + else + FsaState = StateStack.TopElement(); + } + } + + private bool DiscardInvalidTokens() + { + + int action = FsaState.defaultAction; + + if (FsaState.ParserTable != null) + { + // Discard tokens until find one that works ... + while (true) + { + if (NextToken == 0) + { +#if TRACE_ACTIONS + Console.Error.Write("Reading a token: "); +#endif + NextToken = scanner.yylex(); + } +#if TRACE_ACTIONS + Console.Error.WriteLine("Next token is {0}", TerminalToString(NextToken)); +#endif + if (NextToken == endOfFileToken) + return false; + + if (FsaState.ParserTable.ContainsKey(NextToken)) + action = FsaState.ParserTable[NextToken]; + + if (action != 0) + return true; + else + { +#if TRACE_ACTIONS + Console.Error.WriteLine("Error: Discarding {0}", TerminalToString(NextToken)); +#endif + NextToken = 0; + } + } + } + else if (recovering && tokensSinceLastError == 0) + { + // + // Boolean recovering is not set until after the first + // error token has been shifted. Thus if we get back + // here with recovering set and no tokens read we are + // looping on the same error recovery action. This + // happens if current_state.ParserTable is null because + // the state has an LR(0) reduction, but not all + // lookahead tokens are valid. This only occurs for + // error productions that *end* on "error". + // + // This action discards tokens one at a time until + // the looping stops. Another attack would be to always + // use the LALR(1) table if a production ends on "error" + // +#if TRACE_ACTIONS + Console.Error.WriteLine("Error: panic discard of {0}", TerminalToString(NextToken)); +#endif + if (NextToken == endOfFileToken) + return false; + NextToken = 0; + return true; + } + else + return true; + } + + /// + /// Traditional YACC method. Discards the next input token. + /// + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyclearin")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyclearin")] + // Reason for FxCop message suppression - + // This is a traditional name for YACC-like functionality + protected void yyclearin() { NextToken = 0; } + + /// + /// Tradional YACC method. Clear the "recovering" flag. + /// + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerrok")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerrok")] + // Reason for FxCop message suppression - + // This is a traditional name for YACC-like functionality + protected void yyerrok() { recovering = false; } + + /// + /// OBSOLETE FOR VERSION 1.4.0 + /// Method used by derived types to insert new + /// state instances in the "states" array. + /// + /// index of the state + /// data for the state + protected void AddState(int stateNumber, State state) + { + states[stateNumber] = state; + state.number = stateNumber; + } + + private void DisplayStack() + { + Console.Error.Write("State stack is now:"); + for (int i = 0; i < StateStack.Depth; i++) + Console.Error.Write(" {0}", StateStack[i].number); + Console.Error.WriteLine(); + } + + private void DisplayRule(int ruleNumber) + { + Console.Error.Write("Reducing stack by rule {0}, ", ruleNumber); + DisplayProduction(rules[ruleNumber]); + } + + private void DisplayProduction(Rule rule) + { + if (rule.RightHandSide.Length == 0) + Console.Error.Write("/* empty */ "); + else + foreach (int symbol in rule.RightHandSide) + Console.Error.Write("{0} ", SymbolToString(symbol)); + + Console.Error.WriteLine("-> {0}", SymbolToString(rule.LeftHandSide)); + } + + /// + /// Abstract state class naming terminal symbols. + /// This is overridden by derived classes with the + /// name (or alias) to be used in error messages. + /// + /// The terminal ordinal + /// + protected abstract string TerminalToString(int terminal); + + private string SymbolToString(int symbol) + { + if (symbol < 0) + return nonTerminals[-symbol - 1]; + else + return TerminalToString(symbol); + } + + /// + /// Return text representation of argument character + /// + /// The character to convert + /// String representation of the character + protected static string CharToString(char input) + { + switch (input) + { + case '\a': return @"'\a'"; + case '\b': return @"'\b'"; + case '\f': return @"'\f'"; + case '\n': return @"'\n'"; + case '\r': return @"'\r'"; + case '\t': return @"'\t'"; + case '\v': return @"'\v'"; + case '\0': return @"'\0'"; + default: return string.Format(CultureInfo.InvariantCulture, "'{0}'", input); + } + } + } + + /// + /// Classes implementing this interface must supply a + /// method that merges two location objects to return + /// a new object of the same type. + /// GPPG-generated parsers have the default location + /// action equivalent to "@$ = @1.Merge(@N);" where N + /// is the right-hand-side length of the production. + /// + /// The Location type +#if EXPORT_GPPG + public interface IMerge +#else + internal interface IMerge +#endif + { + /// + /// Interface method that creates a location object from + /// the current and last object. Typically used to create + /// a location object extending from the start of the @1 + /// object to the end of the @N object. + /// + /// The lexically last object to merge + /// The merged location object + TSpan Merge(TSpan last); + } + + /// + /// This is the default class that carries location + /// information from the scanner to the parser. + /// If you don't declare "%YYLTYPE Foo" the parser + /// will expect to deal with this type. + /// +#if EXPORT_GPPG + public class LexLocation : IMerge +#else + [SuppressMessage( "Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses" )] + internal class LexLocation : IMerge +#endif + { + private int startLine; // start line + private int startColumn; // start column + private int endLine; // end line + private int endColumn; // end column + + /// + /// The line at which the text span starts. + /// + public int StartLine { get { return startLine; } } + + /// + /// The column at which the text span starts. + /// + public int StartColumn { get { return startColumn; } } + + /// + /// The line on which the text span ends. + /// + public int EndLine { get { return endLine; } } + + /// + /// The column of the first character + /// beyond the end of the text span. + /// + public int EndColumn { get { return endColumn; } } + + /// + /// Default no-arg constructor. + /// + public LexLocation() { } + + /// + /// Constructor for text-span with given start and end. + /// + /// start line + /// start column + /// end line + /// end column + public LexLocation(int sl, int sc, int el, int ec) { startLine = sl; startColumn = sc; endLine = el; endColumn = ec; } + + /// + /// Create a text location which spans from the + /// start of "this" to the end of the argument "last" + /// + /// The last location in the result span + /// The merged span + public LexLocation Merge(LexLocation last) { return new LexLocation(this.startLine, this.startColumn, last.endLine, last.endColumn); } + } + + /// + /// Abstract scanner class that GPPG expects its scanners to + /// extend. + /// + /// Semantic value type YYSTYPE + /// Source location type YYLTYPE +#if EXPORT_GPPG + public abstract class AbstractScanner +#else + internal abstract class AbstractScanner +#endif + where TSpan : IMerge + { + /// + /// Lexical value optionally set by the scanner. The value + /// is of the %YYSTYPE type declared in the parser spec. + /// + [SuppressMessage("Microsoft.Design", "CA1051:DoNotDeclareVisibleInstanceFields")] + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylval")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylval")] + // Reason for FxCop message suppression - + // This is a traditional name for YACC-like functionality + // A field must be declared for this value of parametric type, + // since it may be instantiated by a value struct. If it were + // implemented as a property, machine generated code in derived + // types would not be able to select on the returned value. +#pragma warning disable 649 + public TValue yylval; // Lexical value: set by scanner +#pragma warning restore 649 + + /// + /// Current scanner location property. The value is of the + /// type declared by %YYLTYPE in the parser specification. + /// + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylloc")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylloc")] + // Reason for FxCop message suppression - + // This is a traditional name for YACC-like functionality + public virtual TSpan yylloc + { + get { return default(TSpan); } // Empty implementation allowing + set { /* skip */ } // yylloc to be ignored entirely. + } + + /// + /// Main call point for LEX-like scanners. Returns an int + /// corresponding to the token recognized by the scanner. + /// + /// An int corresponding to the token + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yylex")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yylex")] + // Reason for FxCop message suppression - + // This is a traditional name for YACC-like functionality + public abstract int yylex(); + + /// + /// Traditional error reporting provided by LEX-like scanners + /// to their YACC-like clients. + /// + /// Message format string + /// Optional array of args + [SuppressMessage("Microsoft.Naming", "CA1709:IdentifiersShouldBeCasedCorrectly", MessageId = "yyerror")] + [SuppressMessage("Microsoft.Naming", "CA1704:IdentifiersShouldBeSpelledCorrectly", MessageId = "yyerror")] + // Reason for FxCop message suppression - + // This is a traditional name for YACC-like functionality + public virtual void yyerror(string format, params object[] args) { } + } + + /// + /// Encapsulated state for the parser. + /// Opaque to users, visible to the tool-generated code. + /// +#if EXPORT_GPPG + public class State + { + /// + /// The number of states in the automaton. + /// + public int number; +#else + internal class State { + /// + /// The index of this state in the states array. + /// + internal int number; +#endif + internal Dictionary ParserTable; // Terminal -> ParseAction + internal Dictionary Goto; // NonTerminal -> State; + internal int defaultAction; // = 0; // ParseAction + + /// + /// State transition data for this state. Pairs of elements of the + /// goto array associate symbol ordinals with next state indices. + /// The actions array is passed to another constructor. + /// + /// The action listc + /// Next state data + public State(int[] actions, int[] goToList) + : this(actions) + { + Goto = new Dictionary(); + for (int i = 0; i < goToList.Length; i += 2) + Goto.Add(goToList[i], goToList[i + 1]); + } + + /// + /// Action data for this state. Pairs of elements of the + /// action array associate action ordinals with each of + /// those symbols that have actions in the current state. + /// + /// The action array + public State(int[] actions) + { + ParserTable = new Dictionary(); + for (int i = 0; i < actions.Length; i += 2) + ParserTable.Add(actions[i], actions[i + 1]); + } + + /// + /// Set the default action for this state. + /// + /// Ordinal of the default action + public State(int defaultAction) + { + this.defaultAction = defaultAction; + } + + /// + /// Set the default action and the state transition table. + /// + /// The default action + /// Transitions from this state + public State(int defaultAction, int[] goToList) + : this(defaultAction) + { + Goto = new Dictionary(); + for (int i = 0; i < goToList.Length; i += 2) + Goto.Add(goToList[i], goToList[i + 1]); + } + } + + /// + /// Rule representation at runtime. + /// +#if EXPORT_GPPG + public class Rule +#else + internal class Rule +#endif + { + internal int LeftHandSide; // symbol + internal int[] RightHandSide; // symbols + + /// + /// Rule constructor. This holds the ordinal of + /// the left hand side symbol, and the list of + /// right hand side symbols, in lexical order. + /// + /// The LHS non-terminal + /// The RHS symbols, in lexical order + public Rule(int left, int[] right) + { + this.LeftHandSide = left; + this.RightHandSide = right; + } + } + + /// + /// Stack utility for the shift-reduce parser. + /// GPPG parsers have three instances: + /// (1) The parser state stack, T = QUT.Gppg.State, + /// (2) The semantic value stack, T = TValue, + /// (3) The location stack, T = TSpan. + /// + /// +#if EXPORT_GPPG + public class PushdownPrefixState +#else + internal class PushdownPrefixState +#endif + { + // Note that we cannot use the BCL Stack class + // here as derived types need to index into stacks. + // + private T[] array = new T[8]; + private int tos = 0; + + /// + /// Indexer for values of the stack below the top. + /// + /// index of the element, starting from the bottom + /// the selected element + public T this[int index] { get { return array[index]; } } + + /// + /// The current depth of the stack. + /// + public int Depth { get { return tos; } } + + internal void Push(T value) + { + if (tos >= array.Length) + { + T[] newarray = new T[array.Length * 2]; + System.Array.Copy(array, newarray, tos); + array = newarray; + } + array[tos++] = value; + } + + internal T Pop() + { + T rslt = array[--tos]; + array[tos] = default(T); + return rslt; + } + + internal T TopElement() { return array[tos - 1]; } + + internal bool IsEmpty() { return tos == 0; } + } +} diff --git a/LSLib/LS/Stats/StatDefinitions.cs b/LSLib/LS/Stats/StatDefinitions.cs index 51046ec8..3feddf40 100644 --- a/LSLib/LS/Stats/StatDefinitions.cs +++ b/LSLib/LS/Stats/StatDefinitions.cs @@ -1,26 +1,15 @@ -using LSLib.LS.Enums; -using OpenTK; -using System; +using System; using System.Collections.Generic; using System.IO; using System.Linq; -using System.Runtime.InteropServices; -using System.Xml.Linq; namespace LSLib.LS.Stats { - public class StatEnumeration + public class StatEnumeration(string name) { - public readonly string Name; - public readonly List Values; - public readonly Dictionary ValueToIndexMap; - - public StatEnumeration(string name) - { - Name = name; - Values = new List(); - ValueToIndexMap = new Dictionary(); - } + public readonly string Name = name; + public readonly List Values = []; + public readonly Dictionary ValueToIndexMap = []; public void AddItem(int index, string value) { @@ -32,10 +21,7 @@ public void AddItem(int index, string value) Values.Add(value); // Some vanilla enums are bogus and contain names multiple times - if (!ValueToIndexMap.ContainsKey(value)) - { - ValueToIndexMap.Add(value, index); - } + ValueToIndexMap.TryAdd(value, index); } public void AddItem(string value) @@ -55,29 +41,17 @@ public class StatField public IStatValueParser GetParser(StatValueParserFactory factory, StatDefinitionRepository definitions) { - if (parser == null) - { - parser = factory.CreateParser(this, definitions); - } - + parser ??= factory.CreateParser(this, definitions); return parser; } } - public class StatEntryType + public class StatEntryType(string name, string nameProperty, string basedOnProperty) { - public readonly string Name; - public readonly string NameProperty; - public readonly string BasedOnProperty; - public readonly Dictionary Fields; - - public StatEntryType(string name, string nameProperty, string basedOnProperty) - { - Name = name; - NameProperty = nameProperty; - BasedOnProperty = basedOnProperty; - Fields = new Dictionary(); - } + public readonly string Name = name; + public readonly string NameProperty = nameProperty; + public readonly string BasedOnProperty = basedOnProperty; + public readonly Dictionary Fields = []; } public class StatFunctorArgumentType @@ -98,11 +72,11 @@ public class StatDefinitionRepository // Version of modified Enumerations.xml and StatObjectDefinitions.sod we expect public const string CustomizationsVersion = "1"; - public readonly Dictionary Enumerations = new Dictionary(); - public readonly Dictionary Types = new Dictionary(); - public readonly Dictionary Functors = new Dictionary(); - public readonly Dictionary Boosts = new Dictionary(); - public readonly Dictionary DescriptionParams = new Dictionary(); + public readonly Dictionary Enumerations = []; + public readonly Dictionary Types = []; + public readonly Dictionary Functors = []; + public readonly Dictionary Boosts = []; + public readonly Dictionary DescriptionParams = []; private StatField AddField(StatEntryType defn, string name, string typeName) { @@ -191,23 +165,23 @@ public void LoadDefinitions(Stream stream) { if (trimmed.StartsWith("modifier type ")) { - var name = trimmed.Substring(15, trimmed.Length - 16); + var name = trimmed[15..^1]; defn = new StatEntryType(name, "Name", "Using"); Types.Add(defn.Name, defn); AddField(defn, "Name", "FixedString"); var usingRef = AddField(defn, "Using", "StatReference"); - usingRef.ReferenceTypes = new List - { + usingRef.ReferenceTypes = + [ new StatReferenceConstraint { StatType = name } - }; + ]; } else if (trimmed.StartsWith("modifier \"")) { var nameEnd = trimmed.IndexOf('"', 10); - var name = trimmed.Substring(10, nameEnd - 10); + var name = trimmed[10..nameEnd]; var typeName = trimmed.Substring(nameEnd + 3, trimmed.Length - nameEnd - 4); AddField(defn, name, typeName); } @@ -240,31 +214,31 @@ public void LoadDefinitions(Stream stream) AddField(dataType, "Key", "FixedString"); AddField(dataType, "Value", "FixedString"); - AddEnumeration("ResurrectType", new List - { + AddEnumeration("ResurrectType", + [ "Living", "Guaranteed", "Construct", "Undead" - }); + ]); - AddEnumeration("SetStatusDurationType", new List - { + AddEnumeration("SetStatusDurationType", + [ "SetMinimum", "ForceSet", "Add", "Multiply" - }); + ]); - AddEnumeration("ExecuteWeaponFunctorsType", new List - { + AddEnumeration("ExecuteWeaponFunctorsType", + [ "MainHand", "OffHand", "BothHands" - }); + ]); - AddEnumeration("SpellCooldownType", new List - { + AddEnumeration("SpellCooldownType", + [ "Default", "OncePerTurn", "OncePerCombat", @@ -273,30 +247,30 @@ public void LoadDefinitions(Stream stream) "UntilShortRest", "UntilPerRestPerItem", "OncePerShortRestPerItem" - }); + ]); - AddEnumeration("SummonDuration", new List - { + AddEnumeration("SummonDuration", + [ "UntilLongRest", "Permanent" - }); + ]); - AddEnumeration("ForceFunctorOrigin", new List - { + AddEnumeration("ForceFunctorOrigin", + [ "OriginToEntity", "OriginToTarget", "TargetToEntity" - }); + ]); - AddEnumeration("ForceFunctorAggression", new List - { + AddEnumeration("ForceFunctorAggression", + [ "Aggressive", "Friendly", "Neutral" - }); + ]); - AddEnumeration("StatItemSlot", new List - { + AddEnumeration("StatItemSlot", + [ "Helmet", "Breast", "Cloak", @@ -318,45 +292,45 @@ public void LoadDefinitions(Stream stream) "VanityBoots", "MainHand", "OffHand" - }); + ]); - AddEnumeration("Magical", new List - { + AddEnumeration("Magical", + [ "Magical", "Nonmagical" - }); + ]); - AddEnumeration("Nonlethal", new List - { + AddEnumeration("Nonlethal", + [ "Lethal", "Nonlethal" - }); + ]); - AddEnumeration("AllEnum", new List - { + AddEnumeration("AllEnum", + [ "All" - }); + ]); - AddEnumeration("ZoneShape", new List - { + AddEnumeration("ZoneShape", + [ "Cone", "Square", - }); + ]); - AddEnumeration("SurfaceLayer", new List - { + AddEnumeration("SurfaceLayer", + [ "Ground", "Cloud", - }); + ]); - AddEnumeration("RollAdjustmentType", new List - { + AddEnumeration("RollAdjustmentType", + [ "All", "Distribute", - }); + ]); - AddEnumeration("StatsRollType", new List - { + AddEnumeration("StatsRollType", + [ "Attack", "MeleeWeaponAttack", "RangedWeaponAttack", @@ -377,10 +351,10 @@ public void LoadDefinitions(Stream stream) "RangedSpellDamage", "MeleeUnarmedDamage", "RangedUnarmedDamage", - }); + ]); - AddEnumeration("AdvantageType", new List - { + AddEnumeration("AdvantageType", + [ "AttackRoll", "AttackTarget", "SavingThrow", @@ -392,10 +366,10 @@ public void LoadDefinitions(Stream stream) "SourceDialogue", "DeathSavingThrow", "Concentration", - }); + ]); - AddEnumeration("SkillType", new List - { + AddEnumeration("SkillType", + [ "Deception", "Intimidation", "Performance", @@ -414,63 +388,63 @@ public void LoadDefinitions(Stream stream) "Medicine", "Perception", "Survival", - }); + ]); - AddEnumeration("CriticalHitType", new List - { + AddEnumeration("CriticalHitType", + [ "AttackTarget", "AttackRoll" - }); + ]); - AddEnumeration("Result", new List - { + AddEnumeration("Result", + [ "Success", "Failure" - }); + ]); - AddEnumeration("CriticalHitResult", new List - { + AddEnumeration("CriticalHitResult", + [ "Success", "Failure" - }); + ]); - AddEnumeration("CriticalHitWhen", new List - { + AddEnumeration("CriticalHitWhen", + [ "Never", "Always", "ForcedAlways" - }); + ]); - AddEnumeration("MovementSpeedType", new List - { + AddEnumeration("MovementSpeedType", + [ "Stroll", "Walk", "Run", "Sprint", - }); + ]); - AddEnumeration("DamageReductionType", new List - { + AddEnumeration("DamageReductionType", + [ "Half", "Flat", "Threshold" - }); + ]); - AddEnumeration("AttackRollAbility", new List - { + AddEnumeration("AttackRollAbility", + [ "SpellCastingAbility", "UnarmedMeleeAbility", "AttackAbility" - }); + ]); - AddEnumeration("HealingDirection", new List - { + AddEnumeration("HealingDirection", + [ "Incoming", "Outgoing" - }); + ]); - AddEnumeration("ResistanceBoostFlags", new List - { + AddEnumeration("ResistanceBoostFlags", + [ "None", "Resistant", "Immune", @@ -482,17 +456,17 @@ public void LoadDefinitions(Stream stream) "ResistantToNonMagical", "ImmuneToNonMagical", "VulnerableToNonMagical", - }); + ]); - AddEnumeration("UnlockSpellType", new List - { + AddEnumeration("UnlockSpellType", + [ "Singular", "AddChildren", "MostPowerful" - }); + ]); - AddEnumeration("ProficiencyBonusBoostType", new List - { + AddEnumeration("ProficiencyBonusBoostType", + [ "AttackRoll", "AttackTarget", "SavingThrow", @@ -503,10 +477,10 @@ public void LoadDefinitions(Stream stream) "AllSkills", "SourceDialogue", "WeaponActionDC" - }); + ]); - AddEnumeration("ResourceReplenishType", new List - { + AddEnumeration("ResourceReplenishType", + [ "Never", "Default", "Combat", @@ -514,10 +488,10 @@ public void LoadDefinitions(Stream stream) "ShortRest", "FullRest", "ExhaustedRest" - }); + ]); - AddEnumeration("AttackType", new List - { + AddEnumeration("AttackType", + [ "DirectHit", "MeleeWeaponAttack", "RangedWeaponAttack", @@ -527,10 +501,10 @@ public void LoadDefinitions(Stream stream) "RangedSpellAttack", "MeleeUnarmedAttack", "RangedUnarmedAttack" - }); + ]); - AddEnumeration("DealDamageWeaponDamageType", new List - { + AddEnumeration("DealDamageWeaponDamageType", + [ "MainWeaponDamageType", "OffhandWeaponDamageType", "MainMeleeWeaponDamageType", @@ -539,10 +513,10 @@ public void LoadDefinitions(Stream stream) "OffhandRangedWeaponDamageType", "SourceWeaponDamageType", "ThrownWeaponDamageType", - }); + ]); - AddEnumeration("EngineStatusType", new List - { + AddEnumeration("EngineStatusType", + [ "DYING", "HEAL", "KNOCKED_DOWN", @@ -564,11 +538,11 @@ public void LoadDefinitions(Stream stream) "EFFECT", "DEACTIVATED", "DOWNED", - }); + ]); // Add functors - AddFunctor("ApplyStatus", 1, new List { + AddFunctor("ApplyStatus", 1, [ "StatusId", "StatusId", "Chance", "Int", "Duration", "Lua", @@ -577,23 +551,23 @@ public void LoadDefinitions(Stream stream) "StatusSpecificParam3", "Int", "StatsConditions", "Conditions", "RequiresConcentration", "Boolean" - }); - AddFunctor("SurfaceChange", 1, new List { + ]); + AddFunctor("SurfaceChange", 1, [ "SurfaceChange", "Surface Change", "Chance", "Float", "Arg3", "Float", "Arg4", "Float", "Arg5", "Float" - }); - AddFunctor("Resurrect", 0, new List { + ]); + AddFunctor("Resurrect", 0, [ "Chance", "Float", "HealthPercentage", "Float", "Type", "ResurrectType" - }); - AddFunctor("Sabotage", 0, new List { + ]); + AddFunctor("Sabotage", 0, [ "Amount", "Int" - }); - AddFunctor("Summon", 1, new List { + ]); + AddFunctor("Summon", 1, [ "Template", "Guid", // Root template GUID "Duration", "SummonDurationOrInt", "AIHelper", "SpellId", @@ -604,46 +578,46 @@ public void LoadDefinitions(Stream stream) "StatusToApply3", "StatusId", "StatusToApply4", "StatusId", "Arg10", "Boolean", - }); - AddFunctor("Force", 1, new List { + ]); + AddFunctor("Force", 1, [ "Distance", "Lua", "Origin", "ForceFunctorOrigin", "Aggression", "ForceFunctorAggression", "Arg4", "Boolean", "Arg5", "Boolean", - }); - AddFunctor("Douse", 0, new List { + ]); + AddFunctor("Douse", 0, [ "Arg1", "Float", "Arg2", "Float" - }); - AddFunctor("SwapPlaces", 0, new List { + ]); + AddFunctor("SwapPlaces", 0, [ "Animation", "String", "Arg2", "Boolean", "Arg3", "Boolean" - }); - AddFunctor("Pickup", 0, new List { + ]); + AddFunctor("Pickup", 0, [ "Arg1", "String" - }); - AddFunctor("CreateSurface", 3, new List { + ]); + AddFunctor("CreateSurface", 3, [ "Radius", "Float", "Duration", "Float", "SurfaceType", "Surface Type", "IsControlledByConcentration", "Boolean", "Arg5", "Float", "Arg6", "Boolean" - }); - AddFunctor("CreateConeSurface", 3, new List { + ]); + AddFunctor("CreateConeSurface", 3, [ "Radius", "Float", "Duration", "Float", "SurfaceType", "Surface Type", "IsControlledByConcentration", "Boolean", "Arg5", "Float", "Arg6", "Boolean" - }); - AddFunctor("RemoveStatus", 1, new List { + ]); + AddFunctor("RemoveStatus", 1, [ "StatusId", "StatusIdOrGroup" - }); - AddFunctor("DealDamage", 1, new List { + ]); + AddFunctor("DealDamage", 1, [ "Damage", "Lua", "DamageType", "DamageTypeOrDealDamageWeaponDamageType", "Magical", "Magical", @@ -654,44 +628,44 @@ public void LoadDefinitions(Stream stream) "Arg8", "Boolean", "Arg9", "Boolean", "Arg10", "Boolean", - }); - AddFunctor("ExecuteWeaponFunctors", 0, new List { + ]); + AddFunctor("ExecuteWeaponFunctors", 0, [ "WeaponType", "ExecuteWeaponFunctorsType" - }); - AddFunctor("RegainHitPoints", 1, new List { + ]); + AddFunctor("RegainHitPoints", 1, [ "HitPoints", "Lua", "Type", "ResurrectType" - }); - AddFunctor("TeleportSource", 0, new List { + ]); + AddFunctor("TeleportSource", 0, [ "Arg1", "Boolean", "Arg2", "Boolean", - }); - AddFunctor("SetStatusDuration", 2, new List { + ]); + AddFunctor("SetStatusDuration", 2, [ "StatusId", "StatusId", "Duration", "Float", "ChangeType", "SetStatusDurationType", - }); - AddFunctor("UseSpell", 1, new List { + ]); + AddFunctor("UseSpell", 1, [ "SpellId", "SpellId", "IgnoreHasSpell", "Boolean", "IgnoreChecks", "Boolean", "Arg4", "Boolean", "SpellCastGuid", "Guid", - }); - AddFunctor("UseActionResource", 1, new List { + ]); + AddFunctor("UseActionResource", 1, [ "ActionResource", "String", // Action resource name "Amount", "String", // Float or percentage "Level", "Int", "Arg4", "Boolean" - }); - AddFunctor("UseAttack", 0, new List { + ]); + AddFunctor("UseAttack", 0, [ "IgnoreChecks", "Boolean" - }); - AddFunctor("CreateExplosion", 0, new List { + ]); + AddFunctor("CreateExplosion", 0, [ "SpellId", "SpellId" - }); - AddFunctor("BreakConcentration", 0, new List {}); - AddFunctor("ApplyEquipmentStatus", 2, new List { + ]); + AddFunctor("BreakConcentration", 0, []); + AddFunctor("ApplyEquipmentStatus", 2, [ "ItemSlot", "StatItemSlot", "StatusId", "StatusId", "Chance", "Int", @@ -701,13 +675,13 @@ public void LoadDefinitions(Stream stream) "StatusSpecificParam3", "Int", "StatsConditions", "Conditions", "RequiresConcentration", "Boolean" - }); - AddFunctor("RestoreResource", 2, new List { + ]); + AddFunctor("RestoreResource", 2, [ "ActionResource", "String", // Action resource name "Amount", "Lua", // or percentage? "Level", "Int" - }); - AddFunctor("Spawn", 1, new List { + ]); + AddFunctor("Spawn", 1, [ "TemplateId", "Guid", // Root template Guid "AiHelper", "String", // Should be SpellId, but seemingly defunct? "StatusToApply1", "StatusId", @@ -715,14 +689,14 @@ public void LoadDefinitions(Stream stream) "StatusToApply3", "StatusId", "StatusToApply4", "StatusId", "Arg7", "Boolean" - }); - AddFunctor("Stabilize", 0, new List{}); - AddFunctor("Unlock", 0, new List{}); - AddFunctor("ResetCombatTurn", 0, new List{}); - AddFunctor("RemoveAuraByChildStatus", 1, new List { + ]); + AddFunctor("Stabilize", 0, []); + AddFunctor("Unlock", 0, []); + AddFunctor("ResetCombatTurn", 0, []); + AddFunctor("RemoveAuraByChildStatus", 1, [ "StatusId", "StatusId" - }); - AddFunctor("SummonInInventory", 1, new List { + ]); + AddFunctor("SummonInInventory", 1, [ "TemplateId", "Guid", // Root template Guid "Duration", "SummonDurationOrInt", "Arg3", "Int", @@ -734,8 +708,8 @@ public void LoadDefinitions(Stream stream) "Arg9", "String", "Arg10", "String", "Arg11", "String", // etc. - }); - AddFunctor("SpawnInInventory", 1, new List { + ]); + AddFunctor("SpawnInInventory", 1, [ "TemplateId", "Guid", // Root template Guid "Arg2", "Int", "Arg3", "Boolean", @@ -744,117 +718,117 @@ public void LoadDefinitions(Stream stream) "Arg6", "String", "Arg7", "String", "Arg8", "String", // etc. - }); - AddFunctor("RemoveUniqueStatus", 1, new List { + ]); + AddFunctor("RemoveUniqueStatus", 1, [ "StatusId", "StatusId" - }); - AddFunctor("DisarmWeapon", 0, new List { }); - AddFunctor("DisarmAndStealWeapon", 0, new List { }); - AddFunctor("SwitchDeathType", 1, new List { + ]); + AddFunctor("DisarmWeapon", 0, []); + AddFunctor("DisarmAndStealWeapon", 0, []); + AddFunctor("SwitchDeathType", 1, [ "DeathType", "Death Type" - }); - AddFunctor("TriggerRandomCast", 2, new List { + ]); + AddFunctor("TriggerRandomCast", 2, [ "Arg1", "Int", "Arg2", "Float", "Arg3", "String", // RandomCastOutcomesID resource "Arg4", "String", // RandomCastOutcomesID resource "Arg5", "String", // RandomCastOutcomesID resource "Arg6", "String", // RandomCastOutcomesID resource - }); - AddFunctor("GainTemporaryHitPoints", 1, new List { + ]); + AddFunctor("GainTemporaryHitPoints", 1, [ "Amount", "Lua" - }); - AddFunctor("FireProjectile", 1, new List { + ]); + AddFunctor("FireProjectile", 1, [ "Arg1", "String" - }); - AddFunctor("ShortRest", 0, new List {}); - AddFunctor("CreateZone", 0, new List { + ]); + AddFunctor("ShortRest", 0, []); + AddFunctor("CreateZone", 0, [ "Shape", "ZoneShape", "Arg2", "Float", "Duration", "Float", "Arg4", "String", "Arg5", "Boolean", - }); - AddFunctor("DoTeleport", 0, new List { + ]); + AddFunctor("DoTeleport", 0, [ "Arg1", "Float" - }); - AddFunctor("RegainTemporaryHitPoints", 1, new List { + ]); + AddFunctor("RegainTemporaryHitPoints", 1, [ "Amount", "Lua" - }); - AddFunctor("RemoveStatusByLevel", 1, new List { + ]); + AddFunctor("RemoveStatusByLevel", 1, [ "StatusId", "StatusIdOrGroup", "Arg2", "Int", "Arg3", "Ability" - }); - AddFunctor("SurfaceClearLayer", 0, new List { + ]); + AddFunctor("SurfaceClearLayer", 0, [ "Layer1", "SurfaceLayer", "Layer2", "SurfaceLayer", - }); - AddFunctor("Unsummon", 0, new List { }); - AddFunctor("CreateWall", 0, new List { }); - AddFunctor("Counterspell", 0, new List { }); - AddFunctor("AdjustRoll", 1, new List { + ]); + AddFunctor("Unsummon", 0, []); + AddFunctor("CreateWall", 0, []); + AddFunctor("Counterspell", 0, []); + AddFunctor("AdjustRoll", 1, [ "Amount", "Lua", "Type", "RollAdjustmentType", "DamageType", "Damage Type", - }); - AddFunctor("SpawnExtraProjectiles", 0, new List { + ]); + AddFunctor("SpawnExtraProjectiles", 0, [ "Arg1", "String", // ProjectileTypeId - }); - AddFunctor("Kill", 0, new List { }); - AddFunctor("TutorialEvent", 0, new List { + ]); + AddFunctor("Kill", 0, []); + AddFunctor("TutorialEvent", 0, [ "Event", "Guid", - }); - AddFunctor("Drop", 0, new List { + ]); + AddFunctor("Drop", 0, [ "Arg1", "String", - }); - AddFunctor("ResetCooldowns", 1, new List { + ]); + AddFunctor("ResetCooldowns", 1, [ "Type", "SpellCooldownType", - }); - AddFunctor("SetRoll", 1, new List { + ]); + AddFunctor("SetRoll", 1, [ "Roll", "Int", "DistributionOrDamageType", "RollAdjustmentTypeOrDamageType" - }); - AddFunctor("SetDamageResistance", 1, new List { + ]); + AddFunctor("SetDamageResistance", 1, [ "DamageType", "Damage Type", - }); - AddFunctor("SetReroll", 0, new List { + ]); + AddFunctor("SetReroll", 0, [ "Roll", "Int", "Arg2", "Boolean" - }); - AddFunctor("SetAdvantage", 0, new List { }); - AddFunctor("SetDisadvantage", 0, new List { }); - AddFunctor("MaximizeRoll", 1, new List { + ]); + AddFunctor("SetAdvantage", 0, []); + AddFunctor("SetDisadvantage", 0, []); + AddFunctor("MaximizeRoll", 1, [ "DamageType", "Damage Type" - }); - AddFunctor("CameraWait", 0, new List { + ]); + AddFunctor("CameraWait", 0, [ "Arg1", "Float" - }); + ]); - AddDescriptionParams("DealDamage", 1, new List { + AddDescriptionParams("DealDamage", 1, [ "Damage", "Lua", "DamageType", "DamageTypeOrDealDamageWeaponDamageType", "Magical", "Magical", "Nonlethal", "Nonlethal", "Arg5", "Int", "Tooltip", "Guid", - }); - AddDescriptionParams("RegainHitPoints", 1, new List { + ]); + AddDescriptionParams("RegainHitPoints", 1, [ "HitPoints", "Lua", "Tooltip", "Guid", - }); - AddDescriptionParams("Distance", 1, new List { + ]); + AddDescriptionParams("Distance", 1, [ "Distance", "Float" - }); - AddDescriptionParams("GainTemporaryHitPoints", 1, new List { + ]); + AddDescriptionParams("GainTemporaryHitPoints", 1, [ "Amount", "Lua" - }); - AddDescriptionParams("LevelMapValue", 1, new List { + ]); + AddDescriptionParams("LevelMapValue", 1, [ "LevelMap", "String" - }); - AddDescriptionParams("ApplyStatus", 1, new List { + ]); + AddDescriptionParams("ApplyStatus", 1, [ "StatusId", "StatusId", "Chance", "Int", "Duration", "Lua", @@ -863,284 +837,284 @@ public void LoadDefinitions(Stream stream) "StatusSpecificParam3", "Int", "StatsConditions", "Conditions", "RequiresConcentration", "Boolean" - }); + ]); - AddBoost("AC", 1, new List { + AddBoost("AC", 1, [ "AC", "Int" - }); - AddBoost("Ability", 2, new List { + ]); + AddBoost("Ability", 2, [ "Ability", "Ability", "Amount", "Int", "Arg3", "Int", - }); - AddBoost("RollBonus", 2, new List { + ]); + AddBoost("RollBonus", 2, [ "RollType", "StatsRollType", "Bonus", "Lua", "Arg3", "String", - }); - AddBoost("Advantage", 1, new List { + ]); + AddBoost("Advantage", 1, [ "Type", "AdvantageType", "Arg2", "String", // Depends on type "Tag1", "String", // TagManager resource "Tag2", "String", // TagManager resource "Tag3", "String", // TagManager resource - }); - AddBoost("Disadvantage", 1, new List { + ]); + AddBoost("Disadvantage", 1, [ "Type", "AdvantageType", "Arg2", "String", // Depends on type "Tag1", "String", // TagManager resource "Tag2", "String", // TagManager resource "Tag3", "String", // TagManager resource - }); - AddBoost("ActionResource", 2, new List { + ]); + AddBoost("ActionResource", 2, [ "Resource", "String", // Action resource name "Amount", "Float", "Level", "Int", "DieType", "DieType", - }); - AddBoost("CriticalHit", 3, new List { + ]); + AddBoost("CriticalHit", 3, [ "Type", "CriticalHitType", "Result", "CriticalHitResult", "When", "CriticalHitWhen", "Arg4", "Float", - }); - AddBoost("AbilityFailedSavingThrow", 1, new List { + ]); + AddBoost("AbilityFailedSavingThrow", 1, [ "Ability", "Ability" - }); - AddBoost("Resistance", 2, new List { + ]); + AddBoost("Resistance", 2, [ "DamageType", "AllOrDamageType", "ResistanceBoostFlags", "ResistanceBoostFlags" - }); - AddBoost("WeaponDamageResistance", 1, new List { + ]); + AddBoost("WeaponDamageResistance", 1, [ "DamageType1", "Damage Type", "DamageType2", "Damage Type", "DamageType3", "Damage Type", - }); - AddBoost("ProficiencyBonusOverride", 1, new List { + ]); + AddBoost("ProficiencyBonusOverride", 1, [ "Bonus", "Lua" - }); - AddBoost("ActionResourceOverride", 2, new List { + ]); + AddBoost("ActionResourceOverride", 2, [ "Resource", "String", // Action resource name "Amount", "Float", "Level", "Int", "DieType", "DieType", - }); - AddBoost("AddProficiencyToAC", 0, new List {}); - AddBoost("JumpMaxDistanceMultiplier", 1, new List { + ]); + AddBoost("AddProficiencyToAC", 0, []); + AddBoost("JumpMaxDistanceMultiplier", 1, [ "Multiplier", "Float" - }); - AddBoost("AddProficiencyToDamage", 0, new List {}); - AddBoost("ActionResourceConsumeMultiplier", 3, new List { + ]); + AddBoost("AddProficiencyToDamage", 0, []); + AddBoost("ActionResourceConsumeMultiplier", 3, [ "Resource", "String", // Action resource name "Multiplier", "Float", "Level", "Int", - }); - AddBoost("BlockVerbalComponent", 0, new List {}); - AddBoost("BlockSomaticComponent", 0, new List {}); - AddBoost("HalveWeaponDamage", 1, new List { + ]); + AddBoost("BlockVerbalComponent", 0, []); + AddBoost("BlockSomaticComponent", 0, []); + AddBoost("HalveWeaponDamage", 1, [ "Ability", "Ability" - }); - AddBoost("UnlockSpell", 1, new List { + ]); + AddBoost("UnlockSpell", 1, [ "SpellId", "SpellId", "Type", "UnlockSpellType", "SpellGuid", "String", // "None" or GUID or "" "Cooldown", "SpellCooldownType", "Ability", "Ability" - }); - AddBoost("SourceAdvantageOnAttack", 0, new List { + ]); + AddBoost("SourceAdvantageOnAttack", 0, [ "Arg1", "Float" - }); - AddBoost("ProficiencyBonus", 1, new List { + ]); + AddBoost("ProficiencyBonus", 1, [ "Type", "ProficiencyBonusBoostType", "Arg2", "String" - }); - AddBoost("BlockSpellCast", 0, new List { + ]); + AddBoost("BlockSpellCast", 0, [ "Arg1", "Float" - }); - AddBoost("Proficiency", 1, new List { + ]); + AddBoost("Proficiency", 1, [ "Arg1", "ProficiencyGroupFlags", "Arg2", "ProficiencyGroupFlags", "Arg3", "ProficiencyGroupFlags", - }); - AddBoost("SourceAllyAdvantageOnAttack", 0, new List {}); - AddBoost("IncreaseMaxHP", 1, new List { + ]); + AddBoost("SourceAllyAdvantageOnAttack", 0, []); + AddBoost("IncreaseMaxHP", 1, [ "Amount", "String" // Lua or % - }); - AddBoost("ActionResourceBlock", 1, new List { + ]); + AddBoost("ActionResourceBlock", 1, [ "Resource", "String", // Action resource name "Level", "Int", - }); - AddBoost("StatusImmunity", 1, new List { + ]); + AddBoost("StatusImmunity", 1, [ "StatusId", "StatusIdOrGroup", "Tag1", "String", // Tag resource name "Tag2", "String", // Tag resource name "Tag3", "String", // Tag resource name "Tag4", "String", // Tag resource name "Tag5", "String", // Tag resource name - }); - AddBoost("UseBoosts", 1, new List { + ]); + AddBoost("UseBoosts", 1, [ "Arg1", "StatsFunctors" - }); - AddBoost("CannotHarmCauseEntity", 1, new List { + ]); + AddBoost("CannotHarmCauseEntity", 1, [ "Arg1", "String" - }); - AddBoost("TemporaryHP", 1, new List { + ]); + AddBoost("TemporaryHP", 1, [ "Amount", "Lua" - }); - AddBoost("Weight", 1, new List { + ]); + AddBoost("Weight", 1, [ "Weight", "Float" - }); - AddBoost("WeightCategory", 1, new List { + ]); + AddBoost("WeightCategory", 1, [ "Category", "Int" - }); - AddBoost("FactionOverride", 1, new List { + ]); + AddBoost("FactionOverride", 1, [ "Faction", "String" // Faction resource GUID or "Source" - }); - AddBoost("ActionResourceMultiplier", 2, new List { + ]); + AddBoost("ActionResourceMultiplier", 2, [ "Resource", "String", // Action resource name "Multiplier", "Int", "Level", "Int", - }); - AddBoost("BlockRegainHP", 0, new List { + ]); + AddBoost("BlockRegainHP", 0, [ "Type", "ResurrectTypes" - }); - AddBoost("Initiative", 1, new List { + ]); + AddBoost("Initiative", 1, [ "Initiative", "Int" - }); - AddBoost("DarkvisionRange", 1, new List { + ]); + AddBoost("DarkvisionRange", 1, [ "Range", "Float" - }); - AddBoost("DarkvisionRangeMin", 1, new List { + ]); + AddBoost("DarkvisionRangeMin", 1, [ "Range", "Float" - }); - AddBoost("DarkvisionRangeOverride", 1, new List { + ]); + AddBoost("DarkvisionRangeOverride", 1, [ "Range", "Float" - }); - AddBoost("Tag", 1, new List { + ]); + AddBoost("Tag", 1, [ "Arg1", "String" // Tag resource name - }); - AddBoost("IgnoreDamageThreshold", 2, new List { + ]); + AddBoost("IgnoreDamageThreshold", 2, [ "DamageType", "AllOrDamageType", "Threshold", "Int" - }); - AddBoost("Skill", 2, new List { + ]); + AddBoost("Skill", 2, [ "Skill", "SkillType", "Amount", "Lua" - }); - AddBoost("WeaponDamage", 2, new List { + ]); + AddBoost("WeaponDamage", 2, [ "Amount", "Lua", "DamageType", "Damage Type", "Arg3", "Boolean" - }); - AddBoost("NullifyAbilityScore", 1, new List { + ]); + AddBoost("NullifyAbilityScore", 1, [ "Ability", "Ability" - }); - AddBoost("IgnoreFallDamage", 0, new List {}); - AddBoost("Reroll", 3, new List { + ]); + AddBoost("IgnoreFallDamage", 0, []); + AddBoost("Reroll", 3, [ "RollType", "StatsRollType", "RollBelow", "Int", "Arg3", "Boolean" - }); - AddBoost("DownedStatus", 1, new List { + ]); + AddBoost("DownedStatus", 1, [ "StatusId", "StatusId", "Arg2", "Int" - }); - AddBoost("Invulnerable", 0, new List {}); - AddBoost("WeaponEnchantment", 1, new List { + ]); + AddBoost("Invulnerable", 0, []); + AddBoost("WeaponEnchantment", 1, [ "Enchantment", "Int" - }); - AddBoost("GuaranteedChanceRollOutcome", 1, new List { + ]); + AddBoost("GuaranteedChanceRollOutcome", 1, [ "Arg1", "Boolean" - }); - AddBoost("Attribute", 1, new List { + ]); + AddBoost("Attribute", 1, [ "Flags", "AttributeFlags" - }); - AddBoost("IgnoreLeaveAttackRange", 0, new List {}); - AddBoost("GameplayLight", 2, new List { + ]); + AddBoost("IgnoreLeaveAttackRange", 0, []); + AddBoost("GameplayLight", 2, [ "Arg1", "Float", "Arg2", "Boolean", "Arg3", "Float", "Arg4", "Boolean" - }); - AddBoost("DialogueBlock", 0, new List {}); - AddBoost("DualWielding", 1, new List { + ]); + AddBoost("DialogueBlock", 0, []); + AddBoost("DualWielding", 1, [ "DW", "Boolean" - }); - AddBoost("Savant", 1, new List { + ]); + AddBoost("Savant", 1, [ "SpellSchool", "SpellSchool" - }); - AddBoost("MinimumRollResult", 2, new List { + ]); + AddBoost("MinimumRollResult", 2, [ "RollType", "StatsRollType", "MinResult", "Int" - }); - AddBoost("Lootable", 0, new List {}); - AddBoost("CharacterWeaponDamage", 1, new List { + ]); + AddBoost("Lootable", 0, []); + AddBoost("CharacterWeaponDamage", 1, [ "Amount", "Lua", "DamageType", "Damage Type" - }); - AddBoost("ProjectileDeflect", 0, new List { + ]); + AddBoost("ProjectileDeflect", 0, [ "Type1", "String", "Type2", "String", - }); - AddBoost("AbilityOverrideMinimum", 2, new List { + ]); + AddBoost("AbilityOverrideMinimum", 2, [ "Ability", "Ability", "Minimum", "Int" - }); - AddBoost("ACOverrideFormula", 2, new List { + ]); + AddBoost("ACOverrideFormula", 2, [ "AC", "Int", "Arg2", "Boolean", "Ability1", "Ability", "Ability2", "Ability", "Ability3", "Ability", - }); - AddBoost("FallDamageMultiplier", 1, new List { + ]); + AddBoost("FallDamageMultiplier", 1, [ "Multiplier", "Float" - }); - AddBoost("ActiveCharacterLight", 1, new List { + ]); + AddBoost("ActiveCharacterLight", 1, [ "Light", "String" - }); - AddBoost("Invisibility", 0, new List {}); - AddBoost("TwoWeaponFighting", 0, new List {}); - AddBoost("WeaponAttackTypeOverride", 1, new List { + ]); + AddBoost("Invisibility", 0, []); + AddBoost("TwoWeaponFighting", 0, []); + AddBoost("WeaponAttackTypeOverride", 1, [ "Type", "AttackType" - }); - AddBoost("WeaponDamageDieOverride", 1, new List { + ]); + AddBoost("WeaponDamageDieOverride", 1, [ "DamageDie", "String", // die, eg. 1d10 - }); - AddBoost("CarryCapacityMultiplier", 1, new List { + ]); + AddBoost("CarryCapacityMultiplier", 1, [ "Multiplier", "Float" - }); - AddBoost("WeaponProperty", 1, new List { + ]); + AddBoost("WeaponProperty", 1, [ "Flags1", "WeaponFlags" - }); - AddBoost("WeaponAttackRollAbilityOverride", 1, new List { + ]); + AddBoost("WeaponAttackRollAbilityOverride", 1, [ "Ability", "AbilityOrAttackRollAbility" - }); - AddBoost("BlockTravel", 0, new List {}); - AddBoost("BlockGatherAtCamp", 0, new List {}); - AddBoost("BlockAbilityModifierDamageBonus", 0, new List {}); - AddBoost("VoicebarkBlock", 0, new List {}); - AddBoost("HiddenDuringCinematic", 0, new List {}); - AddBoost("SightRangeAdditive", 1, new List { + ]); + AddBoost("BlockTravel", 0, []); + AddBoost("BlockGatherAtCamp", 0, []); + AddBoost("BlockAbilityModifierDamageBonus", 0, []); + AddBoost("VoicebarkBlock", 0, []); + AddBoost("HiddenDuringCinematic", 0, []); + AddBoost("SightRangeAdditive", 1, [ "Range", "Float" - }); - AddBoost("SightRangeMinimum", 1, new List { + ]); + AddBoost("SightRangeMinimum", 1, [ "Range", "Float" - }); - AddBoost("SightRangeMaximum", 1, new List { + ]); + AddBoost("SightRangeMaximum", 1, [ "Range", "Float" - }); - AddBoost("SightRangeOverride", 1, new List { + ]); + AddBoost("SightRangeOverride", 1, [ "Range", "Float" - }); - AddBoost("CannotBeDisarmed", 0, new List {}); - AddBoost("MovementSpeedLimit", 1, new List { + ]); + AddBoost("CannotBeDisarmed", 0, []); + AddBoost("MovementSpeedLimit", 1, [ "Type", "MovementSpeedType" - }); - AddBoost("NonLethal", 0, new List {}); - AddBoost("UnlockSpellVariant", 1, new List { + ]); + AddBoost("NonLethal", 0, []); + AddBoost("UnlockSpellVariant", 1, [ "Modification1", "Lua", // TODO - add Modification parser? "Modification2", "Lua", "Modification3", "Lua", @@ -1156,166 +1130,166 @@ public void LoadDefinitions(Stream stream) "Modification13", "Lua", "Modification14", "Lua", "Modification15", "Lua" - }); - AddBoost("DetectDisturbancesBlock", 1, new List { + ]); + AddBoost("DetectDisturbancesBlock", 1, [ "Arg1", "Boolean" - }); - AddBoost("BlockAbilityModifierFromAC", 1, new List { + ]); + AddBoost("BlockAbilityModifierFromAC", 1, [ "Ability", "Ability" - }); - AddBoost("ScaleMultiplier", 0, new List { + ]); + AddBoost("ScaleMultiplier", 0, [ "Multiplier", "Float" - }); - AddBoost("CriticalDamageOnHit", 0, new List {}); - AddBoost("DamageReduction", 2, new List { + ]); + AddBoost("CriticalDamageOnHit", 0, []); + AddBoost("DamageReduction", 2, [ "DamageType", "AllOrDamageType", "ReductionType", "DamageReductionType", "Amount", "Lua" - }); - AddBoost("ReduceCriticalAttackThreshold", 1, new List { + ]); + AddBoost("ReduceCriticalAttackThreshold", 1, [ "Threshold", "Int", "StatusId", "StatusIdOrGroup" - }); - AddBoost("PhysicalForceRangeBonus", 1, new List { + ]); + AddBoost("PhysicalForceRangeBonus", 1, [ "Arg1", "String" - }); - AddBoost("ObjectSize", 1, new List { + ]); + AddBoost("ObjectSize", 1, [ "Size", "Int" - }); - AddBoost("ObjectSizeOverride", 1, new List { + ]); + AddBoost("ObjectSizeOverride", 1, [ "Size", "String" - }); - AddBoost("ItemReturnToOwner", 0, new List {}); - AddBoost("AiArchetypeOverride", 1, new List { + ]); + AddBoost("ItemReturnToOwner", 0, []); + AddBoost("AiArchetypeOverride", 1, [ "Archetype", "String", "Arg2", "Int" - }); - AddBoost("ExpertiseBonus", 1, new List { + ]); + AddBoost("ExpertiseBonus", 1, [ "Skill", "SkillType" - }); - AddBoost("EntityThrowDamage", 1, new List { + ]); + AddBoost("EntityThrowDamage", 1, [ "Die", "String", "DamageType", "Damage Type" - }); - AddBoost("WeaponDamageTypeOverride", 1, new List { + ]); + AddBoost("WeaponDamageTypeOverride", 1, [ "DamageType", "Damage Type" - }); - AddBoost("MaximizeHealing", 1, new List { + ]); + AddBoost("MaximizeHealing", 1, [ "Direction", "HealingDirection", "Type", "ResurrectType" - }); - AddBoost("IgnoreEnterAttackRange", 0, new List {}); - AddBoost("DamageBonus", 1, new List { + ]); + AddBoost("IgnoreEnterAttackRange", 0, []); + AddBoost("DamageBonus", 1, [ "Amount", "Lua", "DamageType", "Damage Type", "Arg3", "Boolean" - }); - AddBoost("Detach", 0, new List {}); - AddBoost("ConsumeItemBlock", 0, new List {}); - AddBoost("AdvanceSpells", 1, new List { + ]); + AddBoost("Detach", 0, []); + AddBoost("ConsumeItemBlock", 0, []); + AddBoost("AdvanceSpells", 1, [ "SpellId", "SpellId", "Arg2", "Int" - }); - AddBoost("SpellResistance", 1, new List { + ]); + AddBoost("SpellResistance", 1, [ "Resistance", "ResistanceBoostFlags" - }); - AddBoost("WeaponAttackRollBonus", 1, new List { + ]); + AddBoost("WeaponAttackRollBonus", 1, [ "Amount", "Lua" - }); - AddBoost("SpellSaveDC", 1, new List { + ]); + AddBoost("SpellSaveDC", 1, [ "DC", "Int" - }); - AddBoost("RedirectDamage", 1, new List { + ]); + AddBoost("RedirectDamage", 1, [ "Arg1", "Float", "DamageType", "Damage Type", "DamageType2", "Damage Type", "Arg4", "Boolean" - }); - AddBoost("CanSeeThrough", 1, new List { + ]); + AddBoost("CanSeeThrough", 1, [ "CanSeeThrough", "Boolean" - }); - AddBoost("CanShootThrough", 1, new List { + ]); + AddBoost("CanShootThrough", 1, [ "CanShootThrough", "Boolean" - }); - AddBoost("CanWalkThrough", 1, new List { + ]); + AddBoost("CanWalkThrough", 1, [ "CanWalkThrough", "Boolean" - }); - AddBoost("MonkWeaponAttackOverride", 0, new List {}); - AddBoost("MonkWeaponDamageDiceOverride", 1, new List { + ]); + AddBoost("MonkWeaponAttackOverride", 0, []); + AddBoost("MonkWeaponDamageDiceOverride", 1, [ "Arg1", "Lua" - }); - AddBoost("IntrinsicSummonerProficiency", 0, new List {}); - AddBoost("HorizontalFOVOverride", 1, new List { + ]); + AddBoost("IntrinsicSummonerProficiency", 0, []); + AddBoost("HorizontalFOVOverride", 1, [ "FOV", "Float" - }); - AddBoost("CharacterUnarmedDamage", 1, new List { + ]); + AddBoost("CharacterUnarmedDamage", 1, [ "Damage", "Lua", "DamageType", "Damage Type" - }); - AddBoost("UnarmedMagicalProperty", 0, new List {}); - AddBoost("ActionResourceReplenishTypeOverride", 2, new List { + ]); + AddBoost("UnarmedMagicalProperty", 0, []); + AddBoost("ActionResourceReplenishTypeOverride", 2, [ "ActionResource", "String", // Action resource name "ReplenishType", "ResourceReplenishType" - }); - AddBoost("AreaDamageEvade", 0, new List {}); - AddBoost("ActionResourcePreventReduction", 1, new List { + ]); + AddBoost("AreaDamageEvade", 0, []); + AddBoost("ActionResourcePreventReduction", 1, [ "ActionResource", "String", // Action resource name "Level", "Int" - }); - AddBoost("AttackSpellOverride", 1, new List { + ]); + AddBoost("AttackSpellOverride", 1, [ "AttackSpell", "SpellId", "OriginalSpell", "SpellId" - }); - AddBoost("Lock", 0, new List { + ]); + AddBoost("Lock", 0, [ "DC", "Guid" - }); - AddBoost("NoAOEDamageOnLand", 0, new List {}); - AddBoost("IgnorePointBlankDisadvantage", 1, new List { + ]); + AddBoost("NoAOEDamageOnLand", 0, []); + AddBoost("IgnorePointBlankDisadvantage", 1, [ "Flags", "WeaponFlags" - }); - AddBoost("CriticalHitExtraDice", 1, new List { + ]); + AddBoost("CriticalHitExtraDice", 1, [ "ExtraDice", "Int", "AttackType", "AttackType" - }); - AddBoost("DodgeAttackRoll", 2, new List { + ]); + AddBoost("DodgeAttackRoll", 2, [ "Arg1", "Int", "Arg2", "Int", "Status", "StatusIdOrGroup" - }); - AddBoost("GameplayObscurity", 1, new List { + ]); + AddBoost("GameplayObscurity", 1, [ "Obscurity", "Float" - }); - AddBoost("MaximumRollResult", 2, new List { + ]); + AddBoost("MaximumRollResult", 2, [ "RollType", "StatsRollType", "MinResult", "Int" - }); - AddBoost("UnlockInterrupt", 1, new List { + ]); + AddBoost("UnlockInterrupt", 1, [ "Interrupt", "Interrupt" - }); - AddBoost("IntrinsicSourceProficiency", 0, new List {}); - AddBoost("JumpMaxDistanceBonus", 1, new List { + ]); + AddBoost("IntrinsicSourceProficiency", 0, []); + AddBoost("JumpMaxDistanceBonus", 1, [ "Bonus", "Float" - }); - AddBoost("ArmorAbilityModifierCapOverride", 2, new List { + ]); + AddBoost("ArmorAbilityModifierCapOverride", 2, [ "ArmorType", "ArmorType", "Cap", "Int" - }); - AddBoost("IgnoreResistance", 2, new List { + ]); + AddBoost("IgnoreResistance", 2, [ "DamageType", "Damage Type", "Flags", "ResistanceBoostFlags" - }); - AddBoost("ConcentrationIgnoreDamage", 1, new List { + ]); + AddBoost("ConcentrationIgnoreDamage", 1, [ "SpellSchool", "SpellSchool" - }); - AddBoost("LeaveTriggers", 0, new List {}); - AddBoost("IgnoreLowGroundPenalty", 1, new List { + ]); + AddBoost("LeaveTriggers", 0, []); + AddBoost("IgnoreLowGroundPenalty", 1, [ "RollType", "StatsRollType" - }); - AddBoost("IgnoreSurfaceCover", 1, new List { + ]); + AddBoost("IgnoreSurfaceCover", 1, [ "SurfaceType", "String" // Surface type - }); - AddBoost("EnableBasicItemInteractions", 0, new List {}); - AddBoost("SoundsBlocked", 0, new List {}); + ]); + AddBoost("EnableBasicItemInteractions", 0, []); + AddBoost("SoundsBlocked", 0, []); } public void LoadEnumerations(Stream stream) @@ -1324,7 +1298,7 @@ public void LoadEnumerations(Stream stream) string line; - using (var reader = new StreamReader(stream)) + using var reader = new StreamReader(stream); while ((line = reader.ReadLine()) != null) { var trimmed = line.Trim(); @@ -1332,13 +1306,13 @@ public void LoadEnumerations(Stream stream) { if (trimmed.StartsWith("valuelist ")) { - var name = trimmed.Substring(11, trimmed.Length - 12); + var name = trimmed[11..^1]; curEnum = new StatEnumeration(name); Enumerations.Add(curEnum.Name, curEnum); } else if (trimmed.StartsWith("value ")) { - var label = trimmed.Substring(7, trimmed.Length - 8); + var label = trimmed[7..^1]; curEnum.AddItem(label); } } diff --git a/LSLib/LS/Stats/StatFileParser.cs b/LSLib/LS/Stats/StatFileParser.cs index 9b8cd17e..bc72c6c5 100644 --- a/LSLib/LS/Stats/StatFileParser.cs +++ b/LSLib/LS/Stats/StatFileParser.cs @@ -15,8 +15,8 @@ public class StatEntry public StatEntryType Type; public StatEntry BasedOn; public CodeLocation Location; - public Dictionary Properties = new Dictionary(); - public Dictionary PropertyLocations = new Dictionary(); + public Dictionary Properties = []; + public Dictionary PropertyLocations = []; } /// @@ -71,10 +71,10 @@ public class StatLoadingError public class StatLoadingContext { public StatDefinitionRepository Definitions; - public List Errors = new List(); - public Dictionary> DeclarationsByType = new Dictionary>(); - public Dictionary> ResolvedDeclarationsByType = new Dictionary>(); - public Dictionary> GuidResources = new Dictionary>(); + public List Errors = []; + public Dictionary> DeclarationsByType = []; + public Dictionary> ResolvedDeclarationsByType = []; + public Dictionary> GuidResources = []; public void LogError(string code, string message, string path = null, int line = 0, string statObjectName = null) { @@ -89,9 +89,8 @@ public void LogError(string code, string message, string path = null, int line = } } - class StatEntryReferenceResolver + class StatEntryReferenceResolver(StatLoadingContext context) { - private readonly StatLoadingContext Context; public bool AllowMappingErrors = false; private class BaseClassMapping @@ -99,11 +98,6 @@ private class BaseClassMapping public StatDeclaration Declaration; public StatDeclaration BaseClass; } - - public StatEntryReferenceResolver(StatLoadingContext context) - { - Context = context; - } public bool ResolveUsageRef( StatEntryType type,StatDeclaration declaration, @@ -112,9 +106,9 @@ public bool ResolveUsageRef( { var props = declaration.Properties; var name = (string)props[type.NameProperty]; - if (type.BasedOnProperty != null && props.ContainsKey(type.BasedOnProperty)) + if (type.BasedOnProperty != null && props.TryGetValue(type.BasedOnProperty, out object value)) { - var baseClass = (string)props[type.BasedOnProperty]; + var baseClass = (string)value; if (declarations.TryGetValue(baseClass, out StatDeclaration baseDeclaration)) { @@ -123,7 +117,7 @@ public bool ResolveUsageRef( } else { - Context.LogError(DiagnosticCode.StatBaseClassNotKnown, $"Stats entry '{name}' references nonexistent base '{baseClass}'", + context.LogError(DiagnosticCode.StatBaseClassNotKnown, $"Stats entry '{name}' references nonexistent base '{baseClass}'", declaration.Location.FileName, declaration.Location.StartLine, name); basedOn = null; return false; @@ -188,20 +182,13 @@ public Dictionary ResolveUsageRefs(StatEntryType type, } } - class StatLoaderReferenceValidator : IStatReferenceValidator + class StatLoaderReferenceValidator(StatLoadingContext ctx) : IStatReferenceValidator { - private readonly StatLoadingContext Context; - - public StatLoaderReferenceValidator(StatLoadingContext ctx) - { - Context = ctx; - } - public bool IsValidReference(string reference, string statType) { - if (Context.DeclarationsByType.TryGetValue(statType, out var stats)) + if (ctx.DeclarationsByType.TryGetValue(statType, out var stats)) { - return stats.TryGetValue(reference, out var stat); + return stats.TryGetValue(reference, out _); } return false; @@ -209,9 +196,9 @@ public bool IsValidReference(string reference, string statType) public bool IsValidGuidResource(string name, string resourceType) { - if (Context.GuidResources.TryGetValue(resourceType, out var resources)) + if (ctx.GuidResources.TryGetValue(resourceType, out var resources)) { - return resources.TryGetValue(name, out var resource); + return resources.TryGetValue(name, out _); } return false; @@ -221,8 +208,8 @@ public bool IsValidGuidResource(string name, string resourceType) public class StatLoader { private readonly StatLoadingContext Context; - private StatValueParserFactory ParserFactory; - private StatLoaderReferenceValidator ReferenceValidator; + private readonly StatValueParserFactory ParserFactory; + private readonly StatLoaderReferenceValidator ReferenceValidator; public StatLoader(StatLoadingContext ctx) { @@ -246,7 +233,7 @@ private List ParseStatStream(string path, Stream stream) return parsed ? parser.GetDeclarations() : null; } - private void AddDeclarations(string path, List declarations) + private void AddDeclarations(List declarations) { foreach (var declaration in declarations) { @@ -270,11 +257,10 @@ private void AddDeclarations(string path, List declarations) Context.LogError(DiagnosticCode.StatNameMissing, $"Stat entry has no '{type.NameProperty}' property", declaration.Location.FileName, declaration.Location.StartLine); continue; } - - Dictionary declarationsByType; - if (!Context.DeclarationsByType.TryGetValue(statType, out declarationsByType)) + + if (!Context.DeclarationsByType.TryGetValue(statType, out Dictionary declarationsByType)) { - declarationsByType = new Dictionary(); + declarationsByType = []; Context.DeclarationsByType[statType] = declarationsByType; } @@ -289,7 +275,7 @@ public void LoadStatsFromStream(string path, Stream stream) var stats = ParseStatStream(path, stream); if (stats != null) { - AddDeclarations(path, stats); + AddDeclarations(stats); } } @@ -336,7 +322,7 @@ private object ParseProperty(StatEntryType type, string propertyName, object val if (errorText != null) { - if (value is string && ((string)value).Length > 500) + if (value is string v && v.Length > 500) { Context.LogError(DiagnosticCode.StatPropertyValueInvalid, $"{type.Name} '{declarationName}' has invalid {propertyName}: {errorText}", location?.FileName, location?.StartLine ?? 0, declarationName); @@ -373,7 +359,7 @@ private StatEntry InstantiateEntryInternal(StatEntryType type, string declaratio Type = type, BasedOn = null, // FIXME Location = location, - Properties = new Dictionary(), + Properties = [], PropertyLocations = propertyLocations }; @@ -431,10 +417,9 @@ private void LoadGuidResources(Dictionary guidResources, XmlNode public void LoadGuidResources(XmlDocument doc, string typeName, string regionName) { - Dictionary guidResources; - if (!Context.GuidResources.TryGetValue(typeName, out guidResources)) + if (!Context.GuidResources.TryGetValue(typeName, out Dictionary guidResources)) { - guidResources = new Dictionary(); + guidResources = []; Context.GuidResources[typeName] = guidResources; } diff --git a/LSLib/LS/Stats/StatValueParsers.cs b/LSLib/LS/Stats/StatValueParsers.cs index e36503e1..fce4b975 100644 --- a/LSLib/LS/Stats/StatValueParsers.cs +++ b/LSLib/LS/Stats/StatValueParsers.cs @@ -88,14 +88,9 @@ public object Parse(string value, ref bool succeeded, ref string errorText) } } - public class EnumParser : IStatValueParser + public class EnumParser(StatEnumeration enumeration) : IStatValueParser { - private readonly StatEnumeration Enumeration; - - public EnumParser(StatEnumeration enumeration) - { - Enumeration = enumeration ?? throw new ArgumentNullException(); - } + private readonly StatEnumeration Enumeration = enumeration ?? throw new ArgumentNullException(); public object Parse(string value, ref bool succeeded, ref string errorText) { @@ -125,14 +120,9 @@ public object Parse(string value, ref bool succeeded, ref string errorText) } } - public class MultiValueEnumParser : IStatValueParser + public class MultiValueEnumParser(StatEnumeration enumeration) : IStatValueParser { - private readonly EnumParser Parser; - - public MultiValueEnumParser(StatEnumeration enumeration) - { - Parser = new EnumParser(enumeration); - } + private readonly EnumParser Parser = new(enumeration); public object Parse(string value, ref bool succeeded, ref string errorText) { @@ -143,9 +133,9 @@ public object Parse(string value, ref bool succeeded, ref string errorText) return true; } - foreach (var item in value.Split(new char[] { ';' })) + foreach (var item in value.Split([';'])) { - Parser.Parse(item.Trim(new char[] { ' ' }), ref succeeded, ref errorText); + Parser.Parse(item.Trim([' ']), ref succeeded, ref errorText); if (!succeeded) { errorText = $"Value '{item}' not supported; {errorText}"; @@ -199,17 +189,8 @@ public object Parse(string value, ref bool succeeded, ref string errorText) } } - public class StatReferenceParser : IStatValueParser + public class StatReferenceParser(IStatReferenceValidator validator, List constraints) : IStatValueParser { - private IStatReferenceValidator Validator; - private List Constraints; - - public StatReferenceParser(IStatReferenceValidator validator, List constraints) - { - Validator = validator; - Constraints = constraints; - } - public object Parse(string value, ref bool succeeded, ref string errorText) { if (value == "") @@ -218,38 +199,33 @@ public object Parse(string value, ref bool succeeded, ref string errorText) return value; } - foreach (var constraint in Constraints) + foreach (var constraint in constraints) { - if (Validator.IsValidReference(value, constraint.StatType)) + if (validator.IsValidReference(value, constraint.StatType)) { succeeded = true; return value; } } - var refTypes = String.Join("/", Constraints.Select(c => c.StatType)); + var refTypes = String.Join("/", constraints.Select(c => c.StatType)); errorText = $"'{value}' is not a valid {refTypes} reference"; succeeded = false; return null; } } - public class MultiValueStatReferenceParser : IStatValueParser + public class MultiValueStatReferenceParser(IStatReferenceValidator validator, List constraints) : IStatValueParser { - private readonly StatReferenceParser Parser; - - public MultiValueStatReferenceParser(IStatReferenceValidator validator, List constraints) - { - Parser = new StatReferenceParser(validator, constraints); - } + private readonly StatReferenceParser Parser = new(validator, constraints); public object Parse(string value, ref bool succeeded, ref string errorText) { succeeded = true; - foreach (var item in value.Split(new char[] { ';' })) + foreach (var item in value.Split([';'])) { - var trimmed = item.Trim(new char[] { ' ' }); + var trimmed = item.Trim([' ']); if (trimmed.Length > 0) { Parser.Parse(trimmed, ref succeeded, ref errorText); @@ -271,52 +247,37 @@ public enum ExpressionType DescriptionParams }; - public class ExpressionParser : IStatValueParser + public class ExpressionParser(String validatorType, StatDefinitionRepository definitions, + StatValueParserFactory parserFactory, ExpressionType type) : IStatValueParser { - private readonly String ValidatorType; - private readonly StatDefinitionRepository Definitions; - private readonly StatValueParserFactory ParserFactory; - private readonly ExpressionType ExprType; - - public ExpressionParser(String validatorType, StatDefinitionRepository definitions, - StatValueParserFactory parserFactory, ExpressionType type) - { - ValidatorType = validatorType; - Definitions = definitions; - ParserFactory = parserFactory; - ExprType = type; - } - public virtual object Parse(string value, ref bool succeeded, ref string errorText) { - var valueBytes = Encoding.UTF8.GetBytes("__TYPE_" + ValidatorType + "__ " + value.TrimEnd()); - using (var buf = new MemoryStream(valueBytes)) + var valueBytes = Encoding.UTF8.GetBytes("__TYPE_" + validatorType + "__ " + value.TrimEnd()); + using var buf = new MemoryStream(valueBytes); + List errorTexts = []; + + var scanner = new StatPropertyScanner(); + scanner.SetSource(buf); + var parser = new StatPropertyParser(scanner, definitions, parserFactory, valueBytes, type); + parser.OnError += (string message) => errorTexts.Add(message); + succeeded = parser.Parse(); + if (!succeeded) + { + var location = scanner.LastLocation(); + var column = location.StartColumn - 10 - validatorType.Length + 1; + errorText = $"Syntax error at or near character {column}"; + return null; + } + else if (errorTexts.Count > 0) { - List errorTexts = new List(); - - var scanner = new StatPropertyScanner(); - scanner.SetSource(buf); - var parser = new StatPropertyParser(scanner, Definitions, ParserFactory, valueBytes, ExprType); - parser.OnError += (string message) => errorTexts.Add(message); - succeeded = parser.Parse(); - if (!succeeded) - { - var location = scanner.LastLocation(); - var column = location.StartColumn - 10 - ValidatorType.Length + 1; - errorText = $"Syntax error at or near character {column}"; - return null; - } - else if (errorTexts.Count > 0) - { - succeeded = false; - errorText = String.Join("; ", errorTexts); - return null; - } - else - { - succeeded = true; - return parser.GetParsedObject(); - } + succeeded = false; + errorText = String.Join("; ", errorTexts); + return null; + } + else + { + succeeded = true; + return parser.GetParsedObject(); } } } @@ -327,36 +288,27 @@ public virtual object Parse(string value, ref bool succeeded, ref string errorTe { value = "BHAALS_BOON_SLAYER.Duration-1"; var valueBytes = Encoding.UTF8.GetBytes(value); - using (var buf = new MemoryStream(valueBytes)) + using var buf = new MemoryStream(valueBytes); + var scanner = new Lua.StatLuaScanner(); + scanner.SetSource(buf); + var parser = new Lua.StatLuaParser(scanner); + succeeded = parser.Parse(); + if (!succeeded) + { + var location = scanner.LastLocation(); + errorText = $"Syntax error at or near character {location.StartColumn}"; + return null; + } + else { - var scanner = new Lua.StatLuaScanner(); - scanner.SetSource(buf); - var parser = new Lua.StatLuaParser(scanner); - succeeded = parser.Parse(); - if (!succeeded) - { - var location = scanner.LastLocation(); - errorText = $"Syntax error at or near character {location.StartColumn}"; - return null; - } - else - { - succeeded = true; - return null; - } + succeeded = true; + return null; } } } - public class UseCostsParser : IStatValueParser + public class UseCostsParser(IStatReferenceValidator validator) : IStatValueParser { - private readonly IStatReferenceValidator Validator; - - public UseCostsParser(IStatReferenceValidator validator) - { - Validator = validator; - } - public virtual object Parse(string value, ref bool succeeded, ref string errorText) { if (value.Length == 0) return value; @@ -373,7 +325,7 @@ public virtual object Parse(string value, ref bool succeeded, ref string errorTe return null; } - if (!Validator.IsValidGuidResource(parts[0], "ActionResource") && !Validator.IsValidGuidResource(parts[0], "ActionResourceGroup")) + if (!validator.IsValidGuidResource(parts[0], "ActionResource") && !validator.IsValidGuidResource(parts[0], "ActionResourceGroup")) { errorText = $"Nonexistent action resource or action resource group: {parts[0]}"; return null; @@ -439,20 +391,13 @@ public virtual object Parse(string value, ref bool succeeded, ref string errorTe } } - public class AnyParser : IStatValueParser + public class AnyParser(IEnumerable parsers, string message = null) : IStatValueParser { - private readonly List Parsers; - private readonly String Message; - - public AnyParser(IEnumerable parsers, string message = null) - { - Parsers = parsers.ToList(); - Message = message; - } + private readonly List Parsers = parsers.ToList(); public object Parse(string value, ref bool succeeded, ref string errorText) { - List errors = new List(); + List errors = []; foreach (var parser in Parsers) { succeeded = false; @@ -468,9 +413,9 @@ public object Parse(string value, ref bool succeeded, ref string errorText) } } - if (Message != null && Message.Length > 0) + if (message != null && message.Length > 0) { - errorText = $"'{value}': {Message}"; + errorText = $"'{value}': {message}"; } else { @@ -487,18 +432,11 @@ public class AnyType public string Message; } - public class StatValueParserFactory + public class StatValueParserFactory(IStatReferenceValidator referenceValidator) { - private readonly IStatReferenceValidator ReferenceValidator; - - public StatValueParserFactory(IStatReferenceValidator referenceValidator) - { - ReferenceValidator = referenceValidator; - } - public IStatValueParser CreateReferenceParser(List constraints) { - return new StatReferenceParser(ReferenceValidator, constraints); + return new StatReferenceParser(referenceValidator, constraints); } public IStatValueParser CreateParser(StatField field, StatDefinitionRepository definitions) @@ -528,38 +466,38 @@ public IStatValueParser CreateParser(StatField field, StatDefinitionRepository d case "SpellContainerID": case "FollowUpOriginalSpell": case "RootSpellID": - return new StatReferenceParser(ReferenceValidator, new List - { + return new StatReferenceParser(referenceValidator, + [ new StatReferenceConstraint{ StatType = "SpellData" } - }); + ]); case "ContainerSpells": - return new MultiValueStatReferenceParser(ReferenceValidator, new List - { + return new MultiValueStatReferenceParser(referenceValidator, + [ new StatReferenceConstraint{ StatType = "SpellData" } - }); + ]); case "InterruptPrototype": - return new StatReferenceParser(ReferenceValidator, new List - { + return new StatReferenceParser(referenceValidator, + [ new StatReferenceConstraint{ StatType = "InterruptData" } - }); + ]); case "Passives": case "PassivesOnEquip": case "PassivesMainHand": case "PassivesOffHand": - return new MultiValueStatReferenceParser(ReferenceValidator, new List - { + return new MultiValueStatReferenceParser(referenceValidator, + [ new StatReferenceConstraint{ StatType = "PassiveData" } - }); + ]); case "StatusOnEquip": case "StatusInInventory": - return new MultiValueStatReferenceParser(ReferenceValidator, new List - { + return new MultiValueStatReferenceParser(referenceValidator, + [ new StatReferenceConstraint{ StatType = "StatusData" } - }); + ]); case "Cost": case "UseCosts": @@ -568,7 +506,7 @@ public IStatValueParser CreateParser(StatField field, StatDefinitionRepository d case "TooltipUseCosts": case "RitualCosts": case "HitCosts": - return new UseCostsParser(ReferenceValidator); + return new UseCostsParser(referenceValidator); case "Damage": case "VersatileDamage": @@ -636,117 +574,66 @@ public IStatValueParser CreateParser(string type, StatEnumeration enumType, List } } - switch (type) + return type switch { - case "Boolean": - return new BooleanParser(); - - case "ConstantInt": - case "Int": - return new Int32Parser(); - - case "ConstantFloat": - case "Float": - return new FloatParser(); - - case "String": - case "FixedString": - // FIXME - add TranslatedStringParser "guid;ver" - case "TranslatedString": - return new StringParser(); - - case "Guid": - return new UUIDParser(); - - case "Requirements": - return new ExpressionParser("Requirements", definitions, this, ExpressionType.Functor); - - case "StatsFunctors": - return new ExpressionParser("Properties", definitions, this, ExpressionType.Functor); - - case "Lua": - case "RollConditions": - case "TargetConditions": - case "Conditions": - return new LuaExpressionParser(); - - case "UseCosts": - return new UseCostsParser(ReferenceValidator); - - case "StatReference": - return new StatReferenceParser(ReferenceValidator, constraints); - - case "StatusId": - return new AnyParser(new List { + "Boolean" => new BooleanParser(), + "ConstantInt" or "Int" => new Int32Parser(), + "ConstantFloat" or "Float" => new FloatParser(), + "String" or "FixedString" or "TranslatedString" => new StringParser(), + "Guid" => new UUIDParser(), + "Requirements" => new ExpressionParser("Requirements", definitions, this, ExpressionType.Functor), + "StatsFunctors" => new ExpressionParser("Properties", definitions, this, ExpressionType.Functor), + "Lua" or "RollConditions" or "TargetConditions" or "Conditions" => new LuaExpressionParser(), + "UseCosts" => new UseCostsParser(referenceValidator), + "StatReference" => new StatReferenceParser(referenceValidator, constraints), + "StatusId" => new AnyParser(new List { new EnumParser(definitions.Enumerations["EngineStatusType"]), - new StatReferenceParser(ReferenceValidator, new List - { + new StatReferenceParser(referenceValidator, + [ new StatReferenceConstraint{ StatType = "StatusData" } - }) - }, "Expected a status name"); - - case "ResurrectTypes": - return new MultiValueEnumParser(definitions.Enumerations["ResurrectType"]); - - case "StatusIdOrGroup": - return new AnyParser(new List { + ]) + }, "Expected a status name"), + "ResurrectTypes" => new MultiValueEnumParser(definitions.Enumerations["ResurrectType"]), + "StatusIdOrGroup" => new AnyParser(new List { new EnumParser(definitions.Enumerations["StatusGroupFlags"]), new EnumParser(definitions.Enumerations["EngineStatusType"]), - new StatReferenceParser(ReferenceValidator, new List - { + new StatReferenceParser(referenceValidator, + [ new StatReferenceConstraint{ StatType = "StatusData" } - }) - }, "Expected a status or StatusGroup name"); - - case "SummonDurationOrInt": - return new AnyParser(new List { + ]) + }, "Expected a status or StatusGroup name"), + "SummonDurationOrInt" => new AnyParser(new List { new EnumParser(definitions.Enumerations["SummonDuration"]), new Int32Parser() - }); - - case "AllOrDamageType": - return new AnyParser(new List { + }), + "AllOrDamageType" => new AnyParser(new List { new EnumParser(definitions.Enumerations["AllEnum"]), new EnumParser(definitions.Enumerations["Damage Type"]), - }); - - case "RollAdjustmentTypeOrDamageType": - return new AnyParser(new List { + }), + "RollAdjustmentTypeOrDamageType" => new AnyParser(new List { new EnumParser(definitions.Enumerations["RollAdjustmentType"]), new EnumParser(definitions.Enumerations["Damage Type"]), - }); - - case "AbilityOrAttackRollAbility": - return new AnyParser(new List { + }), + "AbilityOrAttackRollAbility" => new AnyParser(new List { new EnumParser(definitions.Enumerations["Ability"]), new EnumParser(definitions.Enumerations["AttackRollAbility"]), - }); - - case "DamageTypeOrDealDamageWeaponDamageType": - return new AnyParser(new List { + }), + "DamageTypeOrDealDamageWeaponDamageType" => new AnyParser(new List { new EnumParser(definitions.Enumerations["Damage Type"]), new EnumParser(definitions.Enumerations["DealDamageWeaponDamageType"]), - }); - - case "SpellId": - return new StatReferenceParser(ReferenceValidator, new List - { + }), + "SpellId" => new StatReferenceParser(referenceValidator, + [ new StatReferenceConstraint{ StatType = "SpellData" } - }); - - case "Interrupt": - return new StatReferenceParser(ReferenceValidator, new List - { + ]), + "Interrupt" => new StatReferenceParser(referenceValidator, + [ new StatReferenceConstraint{ StatType = "InterruptData" } - }); - + ]), // THESE NEED TO BE FIXED! - case "StatusIDs": - return new StringParser(); - - default: - throw new ArgumentException($"Could not create parser for type '{type}'"); - } + "StatusIDs" => new StringParser(), + _ => throw new ArgumentException($"Could not create parser for type '{type}'"), + }; } } -} \ No newline at end of file +} diff --git a/LSLib/LSLib.csproj b/LSLib/LSLib.csproj index 2f697402..ee8119d0 100644 --- a/LSLib/LSLib.csproj +++ b/LSLib/LSLib.csproj @@ -1,38 +1,16 @@ - - - + - Debug - AnyCPU - {46372C50-4288-4B8E-AF21-C934560600E0} + net8.0 Library - Properties - LSLib - LSLib - v4.7.2 - 512 - + false - true - full - false - bin\Debug\ TRACE;DEBUG;EXPORT_GPPG - prompt - 4 - false x64 true - pdbonly - true - bin\Release\ EXPORT_GPPG - prompt - 4 - false x64 true @@ -41,219 +19,40 @@ TRACE;EXPORT_GPPG true true - pdbonly x86 - prompt MinimumRecommendedRules.ruleset - - ..\packages\AlphaFS.2.2.6\lib\net452\AlphaFS.dll - - - ..\packages\lz4net.1.0.15.93\lib\net4-client\LZ4.dll - - - ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll - - - ..\external\gppg\binaries\QUT.ShiftReduceParser.dll - - - - - - - - - - - False - ..\packages\zlib.net.1.0.4.0\lib\zlib.net.dll - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + - - {d8b26b12-e45c-47ea-88f7-56628eb2ccd1} - LSLibNative - - - {abb9db44-14f2-46e0-a4b8-b46c300ca982} - OpenTK - + - - - - - - + - "$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(ProjectDir)\LS\Story\GoalParser\Goal.lex.cs" "$(ProjectDir)\LS\Story\GoalParser\Goal.lex" -"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(ProjectDir)\LS\Story\GoalParser\Goal.yy.cs" "$(ProjectDir)\LS\Story\GoalParser\Goal.yy" + "$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(SolutionDir)\LSLib\LS\Story\GoalParser\Goal.lex.cs" "$(SolutionDir)\LSLib\LS\Story\GoalParser\Goal.lex" +"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(SolutionDir)\LSLib\LS\Story\GoalParser\Goal.yy.cs" "$(SolutionDir)\LSLib\LS\Story\GoalParser\Goal.yy" -"$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(ProjectDir)\LS\Story\HeaderParser\StoryHeader.lex.cs" "$(ProjectDir)\LS\Story\HeaderParser\StoryHeader.lex" -"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(ProjectDir)\LS\Story\HeaderParser\StoryHeader.yy.cs" "$(ProjectDir)\LS\Story\HeaderParser\StoryHeader.yy" +"$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(SolutionDir)\LSLib\LS\Story\HeaderParser\StoryHeader.lex.cs" "$(SolutionDir)\LSLib\LS\Story\HeaderParser\StoryHeader.lex" +"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(SolutionDir)\LSLib\LS\Story\HeaderParser\StoryHeader.yy.cs" "$(SolutionDir)\LSLib\LS\Story\HeaderParser\StoryHeader.yy" -"$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(ProjectDir)\LS\Stats\Parser\Stat.lex.cs" "$(ProjectDir)\LS\Stats\Parser\Stat.lex" -"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(ProjectDir)\LS\Stats\Parser\Stat.yy.cs" "$(ProjectDir)\LS\Stats\Parser\Stat.yy" +"$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(SolutionDir)\LSLib\LS\Stats\Parser\Stat.lex.cs" "$(SolutionDir)\LSLib\LS\Stats\Parser\Stat.lex" +"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(SolutionDir)\LSLib\LS\Stats\Parser\Stat.yy.cs" "$(SolutionDir)\LSLib\LS\Stats\Parser\Stat.yy" -"$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(ProjectDir)\LS\Stats\Parser\StatProperty.lex.cs" "$(ProjectDir)\LS\Stats\Parser\StatProperty.lex" -"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(ProjectDir)\LS\Stats\Parser\StatProperty.yy.cs" "$(ProjectDir)\LS\Stats\Parser\StatProperty.yy" +"$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(SolutionDir)\LSLib\LS\Stats\Parser\StatProperty.lex.cs" "$(SolutionDir)\LSLib\LS\Stats\Parser\StatProperty.lex" +"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(SolutionDir)\LSLib\LS\Stats\Parser\StatProperty.yy.cs" "$(SolutionDir)\LSLib\LS\Stats\Parser\StatProperty.yy" -"$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(ProjectDir)\LS\Stats\Parser\StatLua.lex.cs" "$(ProjectDir)\LS\Stats\Parser\StatLua.lex" -"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(ProjectDir)\LS\Stats\Parser\StatLua.yy.cs" "$(ProjectDir)\LS\Stats\Parser\StatLua.yy" +"$(SolutionDir)\external\gppg\binaries\GpLex" /out:"$(SolutionDir)\LSLib\LS\Stats\Parser\StatLua.lex.cs" "$(SolutionDir)\LSLib\LS\Stats\Parser\StatLua.lex" +"$(SolutionDir)\external\gppg\binaries\Gppg" /out:"$(SolutionDir)\LSLib\LS\Stats\Parser\StatLua.yy.cs" "$(SolutionDir)\LSLib\LS\Stats\Parser\StatLua.yy" + LSLib + LSLib + Copyright © Norbyte 2012-2023 + 1.18.5.0 + 1.18.5.0 - \ No newline at end of file diff --git a/LSLib/Properties/AssemblyInfo.cs b/LSLib/Properties/AssemblyInfo.cs index b2be3572..91962f52 100644 --- a/LSLib/Properties/AssemblyInfo.cs +++ b/LSLib/Properties/AssemblyInfo.cs @@ -1,15 +1,6 @@ -using System.Reflection; +using System.Diagnostics.CodeAnalysis; +using System.Reflection; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("LSLib")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LSLib")] -[assembly: AssemblyCopyright("Copyright © Norbyte 2012-2023")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -20,16 +11,3 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("cfb98b54-f577-4855-86a3-0c3988b5df8f")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.18.5.0")] -[assembly: AssemblyFileVersion("1.18.5.0")] diff --git a/LSLib/VirtualTextures/BC5Image.cs b/LSLib/VirtualTextures/BC5Image.cs index da93f0d8..37b0aae1 100644 --- a/LSLib/VirtualTextures/BC5Image.cs +++ b/LSLib/VirtualTextures/BC5Image.cs @@ -71,28 +71,28 @@ public void CopyTo(BC5Image destination, int srcX, int srcY, int dstX, int dstY, public void SaveDDS(string path) { - var header = new DDSHeader(); - header.dwMagic = DDSHeader.DDSMagic; - header.dwSize = DDSHeader.HeaderSize; - header.dwFlags = 0x1007; - header.dwWidth = (uint)Width; - header.dwHeight = (uint)Height; - header.dwPitchOrLinearSize = (uint)(Width * Height); - header.dwDepth = 1; - header.dwMipMapCount = 1; - - header.dwPFSize = 32; - header.dwPFFlags = 0x04; - header.dwFourCC = DDSHeader.FourCC_DXT5; - - header.dwCaps = 0x1000; - - using (var pagef = new FileStream(path, FileMode.Create, FileAccess.Write)) - using (var bw = new BinaryWriter(pagef)) + var header = new DDSHeader { - BinUtils.WriteStruct(bw, ref header); - bw.Write(Data, 0, Data.Length); - } + dwMagic = DDSHeader.DDSMagic, + dwSize = DDSHeader.HeaderSize, + dwFlags = 0x1007, + dwWidth = (uint)Width, + dwHeight = (uint)Height, + dwPitchOrLinearSize = (uint)(Width * Height), + dwDepth = 1, + dwMipMapCount = 1, + + dwPFSize = 32, + dwPFFlags = 0x04, + dwFourCC = DDSHeader.FourCC_DXT5, + + dwCaps = 0x1000 + }; + + using var pagef = new FileStream(path, FileMode.Create, FileAccess.Write); + using var bw = new BinaryWriter(pagef); + BinUtils.WriteStruct(bw, ref header); + bw.Write(Data, 0, Data.Length); } } @@ -102,57 +102,55 @@ public class BC5Mips public void LoadDDS(string path) { - using (var f = new FileStream(path, FileMode.Open, FileAccess.Read)) - using (var reader = new BinaryReader(f)) - { - var header = BinUtils.ReadStruct(reader); - Mips = new List(); + using var f = new FileStream(path, FileMode.Open, FileAccess.Read); + using var reader = new BinaryReader(f); + var header = BinUtils.ReadStruct(reader); + Mips = []; - if (header.dwMagic != DDSHeader.DDSMagic) - { - throw new InvalidDataException($"{path}: Incorrect DDS signature, or file is not a DDS file"); - } + if (header.dwMagic != DDSHeader.DDSMagic) + { + throw new InvalidDataException($"{path}: Incorrect DDS signature, or file is not a DDS file"); + } - if (header.dwSize != DDSHeader.HeaderSize) - { - throw new InvalidDataException($"{path}: Incorrect DDS header size"); - } + if (header.dwSize != DDSHeader.HeaderSize) + { + throw new InvalidDataException($"{path}: Incorrect DDS header size"); + } - if ((header.dwFlags & 0xffff) != 0x1007) - { - throw new InvalidDataException($"{path}: Incorrect DDS texture flags"); - } + if ((header.dwFlags & 0xffff) != 0x1007) + { + throw new InvalidDataException($"{path}: Incorrect DDS texture flags"); + } - if (header.dwDepth != 0 && header.dwDepth != 1) - { - throw new InvalidDataException($"{path}: Only single-layer textures are supported"); - } + if (header.dwDepth != 0 && header.dwDepth != 1) + { + throw new InvalidDataException($"{path}: Only single-layer textures are supported"); + } - if ((header.dwPFFlags & 4) != 4) - { - throw new InvalidDataException($"{path}: DDS does not have a valid FourCC code"); - } + if ((header.dwPFFlags & 4) != 4) + { + throw new InvalidDataException($"{path}: DDS does not have a valid FourCC code"); + } - if (header.FourCCName != "DXT5") - { - throw new InvalidDataException($"{path}: Expected a DXT5 encoded texture, got: " + header.FourCCName); - } + if (header.FourCCName != "DXT5") + { + throw new InvalidDataException($"{path}: Expected a DXT5 encoded texture, got: " + header.FourCCName); + } - Int32 mips = 1; - if ((header.dwFlags & 0x20000) == 0x20000) - { - mips = (Int32)header.dwMipMapCount; - } + Int32 mips = 1; + if ((header.dwFlags & 0x20000) == 0x20000) + { + mips = (Int32)header.dwMipMapCount; + } - Mips = new List(mips); - for (var i = 0; i < mips; i++) - { - var width = Math.Max((int)header.dwWidth >> i, 1); - var height = Math.Max((int)header.dwHeight >> i, 1); - var bytes = Math.Max(width / 4, 1) * Math.Max(height / 4, 1) * 16; - var blob = reader.ReadBytes(bytes); - Mips.Add(new BC5Image(blob, width, height)); - } + Mips = new List(mips); + for (var i = 0; i < mips; i++) + { + var width = Math.Max((int)header.dwWidth >> i, 1); + var height = Math.Max((int)header.dwHeight >> i, 1); + var bytes = Math.Max(width / 4, 1) * Math.Max(height / 4, 1) * 16; + var blob = reader.ReadBytes(bytes); + Mips.Add(new BC5Image(blob, width, height)); } } } diff --git a/LSLib/VirtualTextures/Build.cs b/LSLib/VirtualTextures/Build.cs new file mode 100644 index 00000000..9585f054 --- /dev/null +++ b/LSLib/VirtualTextures/Build.cs @@ -0,0 +1,1132 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; +using System.Xml; + +namespace LSLib.VirtualTextures +{ + public class TextureDescriptor + { + public string Name; + public List Layers; + } + + public class TileSetDescriptor + { + public string Name; + public List Textures = []; + public TileSetConfiguration Config = new(); + public string RootPath; + public string SourceTexturePath; + public string VirtualTexturePath; + + public void Load(string path) + { + using var f = new FileStream(path, FileMode.Open, FileAccess.Read); + var doc = new XmlDocument(); + doc.Load(f); + Load(doc); + } + + public void Load(XmlDocument doc) + { + var version = doc.DocumentElement.GetAttribute("Version"); + if (version == null || !Int32.TryParse(version, out int versionNum) || versionNum != 2) + { + throw new InvalidDataException("Expected TileSet XML descriptor version 2"); + } + + Name = doc.DocumentElement.GetAttribute("Name"); + Config.GTSName = Name; + Config.Layers = []; + + var tileSetConfig = doc.DocumentElement.GetElementsByTagName("TileSetConfig"); + foreach (var node in (tileSetConfig[0] as XmlElement).ChildNodes) + { + if (node is XmlElement) + { + var key = (node as XmlElement).Name; + var value = (node as XmlElement).InnerText; + + switch (key) + { + case "TileWidth": Config.TileWidth = Int32.Parse(value); break; + case "TileHeight": Config.TileHeight = Int32.Parse(value); break; + case "TileBorder": Config.TileBorder = Int32.Parse(value); break; + case "Compression": Config.Compression = (TileCompressionPreference)Enum.Parse(typeof(TileCompressionPreference), value); break; + case "PageSize": Config.PageSize = Int32.Parse(value); break; + case "OneFilePerGTex": Config.OneFilePerGTex = Boolean.Parse(value); break; + case "BackfillPages": Config.BackfillPages = Boolean.Parse(value); break; + case "EmbedMips": Config.EmbedMips = Boolean.Parse(value); break; + case "EmbedTopLevelMips": Config.EmbedTopLevelMips = Boolean.Parse(value); break; + default: throw new InvalidDataException($"Unsupported configuration key: {key}"); + } + } + } + + var paths = doc.DocumentElement.GetElementsByTagName("Paths"); + foreach (var node in (paths[0] as XmlElement).ChildNodes) + { + if (node is XmlElement) + { + var key = (node as XmlElement).Name; + var value = (node as XmlElement).InnerText; + + switch (key) + { + case "SourceTextures": SourceTexturePath = Path.Combine(RootPath, value); break; + case "VirtualTextures": VirtualTexturePath = Path.Combine(RootPath, value); break; + default: throw new InvalidDataException($"Unsupported path type: {key}"); + } + } + } + + var layers = doc.DocumentElement.GetElementsByTagName("Layers"); + foreach (var node in (layers[0] as XmlElement).GetElementsByTagName("Layer")) + { + Config.Layers.Add(new BuildLayer + { + DataType = (GTSDataType)Enum.Parse(typeof(GTSDataType), (node as XmlElement).GetAttribute("Type")), + Name = (node as XmlElement).GetAttribute("Name") + }); + } + + if (Config.Layers.Count == 0) + { + throw new InvalidDataException("No tile set layers specified"); + } + + var textures = doc.DocumentElement.GetElementsByTagName("Texture"); + foreach (var texture in textures) + { + var tex = new TextureDescriptor() + { + Name = (texture as XmlElement).GetAttribute("Name"), + Layers = [] + }; + Textures.Add(tex); + + foreach (var layer in Config.Layers) + { + tex.Layers.Add(null); + } + + var texLayers = (texture as XmlElement).GetElementsByTagName("Layer"); + foreach (var layerNode in texLayers) + { + var name = (layerNode as XmlElement).GetAttribute("Name"); + var index = Config.Layers.FindIndex(ly => ly.Name == name); + if (index == -1) + { + throw new InvalidDataException($"Layer does not exist: '{name}'"); + } + + tex.Layers[index] = (layerNode as XmlElement).GetAttribute("Source"); + } + } + } + } + + public class BuildTile + { + public BC5Image Image; + public BC5Image EmbeddedMip; + public CompressedTile Compressed; + + // Set during initialization + public int Layer; + public GTSCodec Codec; + public GTSDataType DataType; + + // Set during layout + public int Level; + public int X; + public int Y; + + // Set during page file build + public bool AddedToPageFile = false; + public int PageFileIndex; + public int PageIndex; + public int ChunkIndex; + } + + public class BuildLayer + { + public GTSDataType DataType; + public string Name; + + public List Levels; + } + + public class TileSetConfiguration + { + public string GTSName; + public Int32 TileWidth = 0x80; + public Int32 TileHeight = 0x80; + public Int32 TileBorder = 8; + public List Layers; + public TileCompressionPreference Compression = TileCompressionPreference.Best; + public Int32 PageSize = 0x100000; + public bool OneFilePerGTex = true; + public bool BackfillPages = false; + public bool EmbedMips = true; + public bool EmbedTopLevelMips = false; + } + + public class BuildLayerTexture + { + public string Path; + public int FirstMip; + public BC5Mips Mips; + } + + public class BuildLevel + { + public int Level; // Level index (0..n) + public int Width; + public int Height; + public int TilesX; + public int TilesY; + public int PaddedTileWidth; + public int PaddedTileHeight; + public BuildTile[] Tiles; + + public BuildTile Get(int x, int y) + { + if (x >= TilesX || y >= TilesY) + { + throw new ArgumentException("Invalid tile index"); + } + + var off = x + TilesX * y; + return Tiles[off]; + } + + public BuildTile GetOrCreateTile(int x, int y, int layer, GTSCodec codec, GTSDataType dataType) + { + if (x >= TilesX || y >= TilesY) + { + throw new ArgumentException("Invalid tile index"); + } + + var off = x + TilesX * y; + if (Tiles[off] == null) + { + Tiles[off] = new BuildTile + { + Image = new BC5Image(PaddedTileWidth, PaddedTileHeight), + Layer = layer, + Codec = codec, + DataType = dataType + }; + } + + return Tiles[off]; + } + } + + public class BuildTexture + { + public string Name; + public int Width; + public int Height; + // Position at level 0 (including FirstMip) + public int X; + public int Y; + public List Layers; + } + + public class TileSetBuildData + { + public List Layers; + public string GTSName; + // Size of tile including borders + public int PaddedTileWidth; + public int PaddedTileHeight; + // Size of tile excluding borders from adjacent tiles + public int RawTileWidth; + public int RawTileHeight; + // Size of tile border + public int TileBorder; + // Total size of tileset in pixels + public int TotalWidth; + public int TotalHeight; + // Number of mip levels to save in page files + public int PageFileLevels; + // Number of mip levels to generate + public int BuildLevels; + // First mip level to save in a separate mip page file + public int MipFileStartLevel; + } + + public class ParameterBlock + { + public GTSCodec Codec; + public GTSDataType DataType; + public TileCompressionMethod Compression; + public UInt32 ParameterBlockID; + } + + public class ParameterBlockContainer + { + public List ParameterBlocks = []; + private UInt32 NextParameterBlockID = 1; + + public ParameterBlock GetOrAdd(GTSCodec codec, GTSDataType dataType, TileCompressionMethod compression) + { + foreach (var block in ParameterBlocks) + { + if (block.Codec == codec && block.DataType == dataType && block.Compression == compression) + { + return block; + } + } + + var newBlock = new ParameterBlock + { + Codec = codec, + DataType = dataType, + Compression = compression, + ParameterBlockID = NextParameterBlockID++ + }; + ParameterBlocks.Add(newBlock); + + return newBlock; + } + } + + public class TileSetBuilder + { + private readonly TileSetBuildData BuildData; + private readonly TileSetConfiguration Config; + private readonly TileCompressor Compressor; + private readonly ParameterBlockContainer ParameterBlocks; + + public VirtualTileSet TileSet; + public List Textures; + public List PageFiles; + + public delegate void BuildStepDelegate(string step); + public BuildStepDelegate OnStepStarted = delegate { }; + public delegate void BuildStepProgressDelegate(int numerator, int denumerator); + public BuildStepProgressDelegate OnStepProgress = delegate { }; + + private List PerLevelFlatTiles; + + public TileSetBuilder(TileSetConfiguration config) + { + BuildData = new TileSetBuildData + { + Layers = config.Layers, + GTSName = config.GTSName, + PaddedTileWidth = config.TileWidth + 2 * config.TileBorder, + PaddedTileHeight = config.TileHeight + 2 * config.TileBorder, + RawTileWidth = config.TileWidth, + RawTileHeight = config.TileHeight, + TileBorder = config.TileBorder + }; + Config = config; + + Compressor = new TileCompressor(); + ParameterBlocks = new ParameterBlockContainer(); + Compressor.Preference = Config.Compression; + Compressor.ParameterBlocks = ParameterBlocks; + + Textures = []; + } + + public void AddTexture(string name, List texturePaths) + { + var tex = new BuildTexture + { + Name = name, + Width = 0, + Height = 0, + X = 0, + Y = 0, + Layers = [] + }; + + foreach (var path in texturePaths) + { + if (path != null) + { + var mips = new BC5Mips(); + mips.LoadDDS(path); + if (mips.Mips.Count <= 1) + { + throw new InvalidDataException($"Texture must include mipmaps: {path}"); + } + + var mip = mips.Mips[0]; + if ((mip.Width % BuildData.RawTileWidth) != 0 + || (mip.Height % BuildData.RawTileHeight) != 0) + { + throw new InvalidDataException($"Texture {path} size ({mip.Width}x{mip.Height}) must be a multiple of the virtual tile size ({BuildData.RawTileWidth}x{BuildData.RawTileHeight})"); + } + + if ((mip.Width & (mip.Width - 1)) != 0 + || (mip.Height & (mip.Height - 1)) != 0) + { + throw new InvalidDataException($"Texture {path} size ({mip.Width}x{mip.Height}) must be a multiple of two"); + } + + tex.Layers.Add(new BuildLayerTexture + { + Path = path, + FirstMip = 0, + Mips = mips + }); + } + else + { + tex.Layers.Add(null); + } + } + + // Figure out top-level size for texture across all layers + foreach (var layer in tex.Layers) + { + if (layer == null) continue; + + tex.Width = Math.Max(tex.Width, layer.Mips.Mips[0].Width); + tex.Height = Math.Max(tex.Height, layer.Mips.Mips[0].Height); + } + + // Adjust first layer index for textures + foreach (var layer in tex.Layers) + { + if (layer == null) continue; + + var mip = layer.Mips.Mips[0]; + if (mip.Width > tex.Width || mip.Height > tex.Height) + { + throw new InvalidDataException($"Top-level texture size mismatch; texture {layer.Path} is {mip.Width}x{mip.Height}, size across all layers is {tex.Width}x{tex.Height}"); + } + + var mulW = tex.Width / mip.Width; + var mulH = tex.Height / mip.Height; + + if ((tex.Width % mip.Width) != 0 || (tex.Height % mip.Height) != 0 + || mulW != mulH + // Check if total layer size size is a power-of-two of the texture size + || (mulW & (mulW - 1)) != 0) + { + throw new InvalidDataException($"Texture sizes within all layers should be multiples of each other; texture {layer.Path} is {mip.Width}x{mip.Height}, size across all layers is {tex.Width}x{tex.Height}"); + } + + // Adjust first mip index based on texture size + while (mulW > 1) + { + mulW >>= 1; + layer.FirstMip++; + } + } + + Console.WriteLine($"Added GTex {tex.Name} ({tex.Width}x{tex.Height})"); + Textures.Add(tex); + } + + private void BuildParameterBlocks() + { + var blocks = ParameterBlocks.ParameterBlocks; + TileSet.ParameterBlockHeaders = new GTSParameterBlockHeader[blocks.Count]; + TileSet.ParameterBlocks = []; + + for (var i = 0; i < blocks.Count; i++) + { + var block = blocks[i]; + ref var header = ref TileSet.ParameterBlockHeaders[i]; + + header.ParameterBlockID = block.ParameterBlockID; + header.Codec = block.Codec; + + switch (block.Codec) + { + case GTSCodec.BC: + header.ParameterBlockSize = (uint)Marshal.SizeOf(typeof(GTSBCParameterBlock)); + + string compression1, compression2; + switch (block.Compression) + { + case TileCompressionMethod.Raw: + compression1 = "raw"; + compression2 = ""; + break; + + case TileCompressionMethod.LZ4: + compression1 = "lz4"; + compression2 = "lz40.1.0"; + break; + + case TileCompressionMethod.LZ77: + compression1 = "lz77"; + compression2 = "fastlz0.1.0"; + break; + + default: + throw new ArgumentException("Unsupported compression method"); + } + + TileSet.ParameterBlocks[block.ParameterBlockID] = new GTSBCParameterBlock + { + Version = 0x238e, + CompressionName1 = compression1, + CompressionName2 = compression2, + B = 0, + C1 = 0, + C2 = 0, + BCField3 = 0, + DataType = (Byte)block.DataType, + D = 0, + FourCC = 0x20334342, + E1 = 0, + SaveMip = 1, + E3 = 0, + E4 = 0, + F = 0 + }; + break; + + case GTSCodec.Uniform: + header.ParameterBlockSize = (uint)Marshal.SizeOf(typeof(GTSUniformParameterBlock)); + TileSet.ParameterBlocks[block.ParameterBlockID] = new GTSUniformParameterBlock + { + Version = 0x42, + A_Unused = 0, + Width = 4, + Height = 1, + DataType = block.DataType + }; + break; + + default: + throw new ArgumentException("Unsupported codec type"); + } + } + } + + private void BuildFourCC() + { + var fourCC = new TileSetFourCC(); + var meta = FourCCElement.Make("META"); + fourCC.Root = meta; + + var atlas = FourCCElement.Make("ATLS"); + meta.Children.Add(atlas); + + var textures = FourCCElement.Make("TXTS"); + atlas.Children.Add(textures); + + foreach (var texture in Textures) + { + var tex = FourCCElement.Make("TXTR"); + textures.Children.Add(tex); + tex.Children.Add(FourCCElement.Make("NAME", texture.Name)); + tex.Children.Add(FourCCElement.Make("WDTH", (uint)texture.Width)); + tex.Children.Add(FourCCElement.Make("HGHT", (uint)texture.Height)); + tex.Children.Add(FourCCElement.Make("XXXX", (uint)texture.X)); + tex.Children.Add(FourCCElement.Make("YYYY", (uint)texture.Y)); + tex.Children.Add(FourCCElement.Make("ADDR", "None")); + tex.Children.Add(FourCCElement.Make("SRGB", FourCCElementType.BinaryInt, [ + 0x01, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + ])); + tex.Children.Add(FourCCElement.Make("THMB", FourCCElementType.BinaryGuid, [ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ])); + } + + var project = FourCCElement.Make("PROJ", ""); + meta.Children.Add(project); + + var layers = FourCCElement.Make("LINF"); + meta.Children.Add(layers); + + for (var i = 0; i < BuildData.Layers.Count; i++) + { + var layerInfo = FourCCElement.Make("LAYR"); + layers.Children.Add(layerInfo); + layerInfo.Children.Add(FourCCElement.Make("INDX", (uint)i)); + layerInfo.Children.Add(FourCCElement.Make("TYPE", "BC3")); + layerInfo.Children.Add(FourCCElement.Make("NAME", BuildData.Layers[i].Name)); + } + + var info = FourCCElement.Make("INFO"); + meta.Children.Add(info); + + var compiler = FourCCElement.Make("COMP"); + info.Children.Add(compiler); + + var compVer = FourCCElement.Make("CMPW"); + compiler.Children.Add(compVer); + compVer.Children.Add(FourCCElement.Make("MAJR", 5)); + compVer.Children.Add(FourCCElement.Make("MINR", 0)); + + var buildVer = FourCCElement.Make("BLDV"); + compiler.Children.Add(buildVer); + buildVer.Children.Add(FourCCElement.Make("MAJR", 5)); + buildVer.Children.Add(FourCCElement.Make("MINR", 1)); + buildVer.Children.Add(FourCCElement.Make("BINF", "LSLib")); + + info.Children.Add(FourCCElement.Make("DATE", "02-08-2023 07:49:30.7662814 PM +02:00")); + info.Children.Add(FourCCElement.Make("BLKS", "4096")); + info.Children.Add(FourCCElement.Make("TILE", "Software")); + info.Children.Add(FourCCElement.Make("BDPR", "default")); + info.Children.Add(FourCCElement.Make("LTMP", 0)); + + TileSet.FourCCMetadata = fourCC; + } + + private void CalculateGeometry() + { + var geom = new TileSetGeometryCalculator + { + BuildData = BuildData, + Textures = Textures + }; + geom.Update(); + + Console.WriteLine($"Tile set geometry: {BuildData.TotalWidth}x{BuildData.TotalHeight} ({BuildData.TotalWidth/BuildData.RawTileWidth}x{BuildData.TotalHeight/BuildData.RawTileHeight} tiles), {BuildData.RawTileWidth}x{BuildData.RawTileHeight} tile size, {BuildData.PaddedTileWidth}x{BuildData.PaddedTileHeight} tile size with adjacency data"); + } + + private static int Clamp(int x, int min, int max) + { + return Math.Min(max, Math.Max(x, min)); + } + + private void StitchPartialTile(BuildTile tile, BC5Image source, int tileX, int tileY, int sourceX, int sourceY, int width, int height) + { + source.CopyTo( + tile.Image, + sourceX, sourceY, + tileX + BuildData.TileBorder, + tileY + BuildData.TileBorder, + width, height + ); + } + + private void StitchTiles(BuildLevel level, int layer, int x, int y, BC5Image mip) + { + var layerInfo = BuildData.Layers[layer]; + var firstTileX = x / BuildData.RawTileWidth; + var firstTileY = y / BuildData.RawTileHeight; + var lastTileX = (x + mip.Width - 1) / BuildData.RawTileWidth; + var lastTileY = (y + mip.Height - 1) / BuildData.RawTileHeight; + + int sourceY = 0; + for (var tileY = firstTileY; tileY <= lastTileY; tileY++) + { + int sourceX = 0; + for (var tileX = firstTileX; tileX <= lastTileX; tileX++) + { + var tileXPixelsMin = tileX * BuildData.RawTileWidth; + var tileYPixelsMin = tileY * BuildData.RawTileHeight; + var tileXPixelsMax = tileXPixelsMin + BuildData.RawTileWidth; + var tileYPixelsMax = tileYPixelsMin + BuildData.RawTileHeight; + + var stitchXMin = Clamp(x, tileXPixelsMin, tileXPixelsMax); + var stitchYMin = Clamp(y, tileYPixelsMin, tileYPixelsMax); + var stitchXMax = Clamp(x + mip.Width, tileXPixelsMin, tileXPixelsMax); + var stitchYMax = Clamp(y + mip.Height, tileYPixelsMin, tileYPixelsMax); + + var stitchW = stitchXMax - stitchXMin; + var stitchH = stitchYMax - stitchYMin; + + // GIGA JANK + if (stitchW >= 4 && stitchH >= 4) + { + var tile = level.GetOrCreateTile(tileX, tileY, layer, GTSCodec.BC, layerInfo.DataType); + StitchPartialTile(tile, mip, + stitchXMin - tileXPixelsMin, + stitchYMin - tileYPixelsMin, + sourceX, sourceY, + stitchXMax - stitchXMin, + stitchYMax - stitchYMin + ); + } + + sourceX += BuildData.RawTileWidth; + } + + sourceY += BuildData.RawTileHeight; + } + } + + private void BuildTextureTiles(BuildTexture texture, int level, int layerIndex, BuildLayer layer, BC5Image mip) + { + var x = texture.X >> level; + var y = texture.Y >> level; + StitchTiles(layer.Levels[level], layerIndex, x, y, mip); + } + + private void BuildTextureTiles(BuildTexture texture, int layerIndex, BuildLayerTexture texLayer, BuildLayer layer) + { + if (texLayer.FirstMip + texLayer.Mips.Mips.Count < BuildData.BuildLevels) + { + throw new InvalidDataException($"Insufficient mip layers in texture '{texture.Name}', layer '{layer.Name}'; got {texLayer.FirstMip}+{texLayer.Mips.Mips.Count}, virtual texture has {BuildData.BuildLevels}"); + } + + for (var i = texLayer.FirstMip; i < BuildData.BuildLevels; i++) + { + BuildTextureTiles(texture, i, layerIndex, layer, texLayer.Mips.Mips[i - texLayer.FirstMip]); + } + } + + private void BuildTiles() + { + foreach (var texture in Textures) + { + for (var layerIdx = 0; layerIdx < texture.Layers.Count; layerIdx++) + { + if (texture.Layers[layerIdx] != null) + { + BuildTextureTiles(texture, layerIdx, texture.Layers[layerIdx], BuildData.Layers[layerIdx]); + } + } + } + } + + private void BuildTileBorders(BuildLevel level) + { + for (var y = 0; y < level.TilesY; y++) + { + for (var x = 0; x < level.TilesX; x++) + { + var tile = level.Get(x, y); + if (tile == null) continue; + + // Left + if (x > 0) + { + level.Get(x - 1, y)?.Image.CopyTo(tile.Image, + BuildData.RawTileWidth, 0, + 0, 0, + BuildData.TileBorder, BuildData.PaddedTileHeight); + } + + // Right + if (x + 1 < level.TilesX) + { + level.Get(x + 1, y)?.Image.CopyTo(tile.Image, + BuildData.TileBorder, 0, + BuildData.RawTileWidth + BuildData.TileBorder, 0, + BuildData.TileBorder, BuildData.PaddedTileHeight); + } + + // Top + if (y > 0) + { + level.Get(x, y - 1)?.Image.CopyTo(tile.Image, + 0, BuildData.RawTileHeight, + 0, 0, + BuildData.PaddedTileWidth, BuildData.TileBorder); + } + + // Bottom + if (y + 1 < level.TilesY) + { + level.Get(x, y + 1)?.Image.CopyTo(tile.Image, + 0, BuildData.TileBorder, + 0, BuildData.RawTileHeight + BuildData.TileBorder, + BuildData.PaddedTileWidth, BuildData.TileBorder); + + // Bottom Left corner + if (x > 0) + { + level.Get(x - 1, y + 1)?.Image.CopyTo(tile.Image, + BuildData.RawTileWidth, BuildData.TileBorder, + 0, BuildData.RawTileHeight + BuildData.TileBorder, + BuildData.TileBorder, BuildData.TileBorder); + } + + // Bottom Right corner + if (x + 1 < level.TilesX) + { + level.Get(x + 1, y + 1)?.Image.CopyTo(tile.Image, + BuildData.TileBorder, BuildData.TileBorder, + BuildData.RawTileWidth + BuildData.TileBorder, BuildData.RawTileHeight + BuildData.TileBorder, + BuildData.TileBorder, BuildData.TileBorder); + } + } + } + } + } + + private void BuildTileBorders() + { + foreach (var layer in BuildData.Layers) + { + foreach (var level in layer.Levels) + { + BuildTileBorders(level); + } + } + } + + private void EmbedTileMips(BuildLayer layer, BuildLevel level) + { + for (var y = 0; y < level.TilesY; y++) + { + for (var x = 0; x < level.TilesX; x++) + { + var tile = level.Get(x, y); + if (tile != null) + { + if (level.Level + 1 < BuildData.BuildLevels) + { + var nextLevelTile = layer.Levels[level.Level + 1].Get(x / 2, y / 2); + if (nextLevelTile != null) + { + var nextMip = new BC5Image(BuildData.PaddedTileWidth / 2, BuildData.PaddedTileHeight / 2); + var mipX = (x & 1) * (BuildData.RawTileWidth / 2) + BuildData.TileBorder / 2; + var mipY = (y & 1) * (BuildData.RawTileHeight / 2) + BuildData.TileBorder / 2; + nextLevelTile.Image.CopyTo(nextMip, mipX, mipY, 0, 0, BuildData.PaddedTileWidth / 2, BuildData.PaddedTileHeight / 2); + tile.EmbeddedMip = nextMip; + } + } + } + } + } + } + + private void EmbedTileMips() + { + foreach (var layer in BuildData.Layers) + { + foreach (var level in layer.Levels) + { + if (level.Level > 0 || Config.EmbedTopLevelMips) + { + EmbedTileMips(layer, level); + } + } + } + } + + private void BuildGTSHeaders() + { + // Configuration-independent defaults + ref GTSHeader header = ref TileSet.Header; + header.Magic = GTSHeader.GRPGMagic; + header.Version = GTSHeader.CurrentVersion; + header.Unused = 0; + header.GUID = Guid.NewGuid(); + header.I6 = 0; + header.I7 = 0; + header.M = 0; + header.N = 0; + header.O = 0; + header.P = 0; + header.Q = 0; + header.R = 0; + header.S = 0; + header.PageSize = (UInt32)Config.PageSize; + header.XJJ = 0; + header.XKK = 0; + header.XLL = 0; + header.XMM = 0; + + header.TileWidth = BuildData.PaddedTileWidth; + header.TileHeight = BuildData.PaddedTileHeight; + header.TileBorder = BuildData.TileBorder; + } + + private void BuildPageFiles() + { + var builder = new PageFileSetBuilder(BuildData, Config); + if (Config.OneFilePerGTex) + { + PageFiles = builder.BuildFilePerGTex(Textures); + } + else + { + PageFiles = builder.BuildSingleFile(); + } + + TileSet.PageFileInfos = []; + uint firstPageIndex = 0; + foreach (var file in PageFiles) + { + var fileInfo = new PageFileInfo + { + Meta = new GTSPageFileInfo + { + FileName = file.FileName, + NumPages = (uint)file.Pages.Count, + Checksum = file.Checksum, + F = 2 + }, + FirstPageIndex = firstPageIndex, + FileName = file.FileName + }; + TileSet.PageFileInfos.Add(fileInfo); + firstPageIndex += (uint)file.Pages.Count; + } + } + + private void BuildGTS() + { + TileSet = new VirtualTileSet(); + BuildGTSHeaders(); + + TileSet.TileSetLayers = new GTSTileSetLayer[BuildData.Layers.Count]; + for (int i = 0; i < BuildData.Layers.Count; i++) + { + var layer = BuildData.Layers[i]; + ref var gtsLayer = ref TileSet.TileSetLayers[i]; + gtsLayer.DataType = layer.DataType; + gtsLayer.B = -1; + } + + var levels = BuildData.Layers[0].Levels; + + TileSet.TileSetLevels = new GTSTileSetLevel[BuildData.PageFileLevels]; + for (int i = 0; i < BuildData.PageFileLevels; i++) + { + var level = levels[i]; + ref var gtsLevel = ref TileSet.TileSetLevels[i]; + gtsLevel.Width = (uint)level.TilesX; + gtsLevel.Height = (uint)level.TilesY; + } + + OnStepStarted("Generating tile lists"); + BuildFlatTileList(); + OnStepStarted("Encoding tiles"); + CompressTiles(); + + OnStepStarted("Building page files"); + BuildPageFiles(); + + OnStepStarted("Building metadata"); + BuildTileInfos(); + BuildTileDownsampleInfos(); + + BuildParameterBlocks(); + BuildFourCC(); + } + + public void BuildFlatTileList() + { + PerLevelFlatTiles = new List(BuildData.PageFileLevels); + + for (var level = 0; level < BuildData.PageFileLevels; level++) + { + var levelInfo = BuildData.Layers[0].Levels[level]; + var flatTiles = new BuildTile[levelInfo.TilesX * levelInfo.TilesY * BuildData.Layers.Count]; + PerLevelFlatTiles.Add(flatTiles); + + var tileIdx = 0; + for (var y = 0; y < levelInfo.TilesY; y++) + { + for (var x = 0; x < levelInfo.TilesX; x++) + { + for (var layer = 0; layer < BuildData.Layers.Count; layer++) + { + var tile = BuildData.Layers[layer].Levels[level].Get(x, y); + if (tile != null) + { + tile.Layer = layer; + tile.Level = level; + tile.X = x; + tile.Y = y; + flatTiles[tileIdx] = tile; + } + else + { + flatTiles[tileIdx] = null; + } + + tileIdx++; + } + } + } + } + } + + public void CompressTiles() + { + var numTiles = PerLevelFlatTiles.Sum(tiles => tiles.Length); + var nextTile = 0; + + foreach (var level in PerLevelFlatTiles) + { + foreach (var tile in level) + { + OnStepProgress(nextTile++, numTiles); + if (tile != null) + { + Compressor.Compress(tile); + } + } + } + } + + public void BuildTileInfos() + { + TileSet.PerLevelFlatTileIndices = new List(BuildData.PageFileLevels); + PerLevelFlatTiles = new List(BuildData.PageFileLevels); + + var flatTileInfos = new List(); + var packedTileIds = new List(); + + for (var level = 0; level < BuildData.PageFileLevels; level++) + { + var levelInfo = BuildData.Layers[0].Levels[level]; + var flatTileIndices = new UInt32[levelInfo.TilesX * levelInfo.TilesY * BuildData.Layers.Count]; + TileSet.PerLevelFlatTileIndices.Add(flatTileIndices); + + var flatTiles = new BuildTile[levelInfo.TilesX * levelInfo.TilesY * BuildData.Layers.Count]; + PerLevelFlatTiles.Add(flatTiles); + + var tileIdx = 0; + for (var y = 0; y < levelInfo.TilesY; y++) + { + for (var x = 0; x < levelInfo.TilesX; x++) + { + for (var layer = 0; layer < BuildData.Layers.Count; layer++) + { + var tile = BuildData.Layers[layer].Levels[level].Get(x, y); + if (tile != null) + { + var flatTileIdx = (uint)flatTileInfos.Count; + var packedTileIdx = (uint)packedTileIds.Count; + + var packedTile = new GTSPackedTileID((uint)layer, (uint)level, (uint)x, (uint)y); + packedTileIds.Add(packedTile); + + var tileInfo = new GTSFlatTileInfo + { + PageFileIndex = (UInt16)tile.PageFileIndex, + PageIndex = (UInt16)tile.PageIndex, + ChunkIndex = (UInt16)tile.ChunkIndex, + D = 1, + PackedTileIndex = packedTileIdx + }; + flatTileInfos.Add(tileInfo); + + flatTileIndices[tileIdx] = flatTileIdx; + flatTiles[tileIdx] = tile; + } + else + { + flatTileIndices[tileIdx] = 0xFFFFFFFF; + flatTiles[tileIdx] = null; + } + + tileIdx++; + } + } + } + } + + TileSet.PackedTileIDs = packedTileIds.ToArray(); + TileSet.FlatTileInfos = flatTileInfos.ToArray(); + } + + public void BuildTileDownsampleInfos() + { + for (var level = 0; level < BuildData.PageFileLevels; level++) + { + var levelInfo = BuildData.Layers[0].Levels[level]; + var flatTileIndices = TileSet.PerLevelFlatTileIndices[level]; + + var tileIdx = 0; + for (var y = 0; y < levelInfo.TilesY; y++) + { + for (var x = 0; x < levelInfo.TilesX; x++) + { + for (var layer = 0; layer < BuildData.Layers.Count; layer++) + { + if (flatTileIndices[tileIdx] == 0xFFFFFFFF) + { + for (var downsampleLevel = level + 1; downsampleLevel < BuildData.PageFileLevels; downsampleLevel++) + { + var downsampleX = x >> (downsampleLevel - level); + var downsampleY = y >> (downsampleLevel - level); + + var dsIndices = TileSet.PerLevelFlatTileIndices[downsampleLevel]; + var dsIndex = dsIndices[layer + BuildData.Layers.Count * (downsampleX + downsampleY * BuildData.Layers[layer].Levels[downsampleLevel].TilesX)]; + if ((dsIndex & 0x80000000) == 0) + { + flatTileIndices[tileIdx] = dsIndex | 0x80000000; + break; + } + } + } + + tileIdx++; + } + } + } + } + } + + public void Build(string dir) + { + OnStepStarted("Calculating geometry"); + CalculateGeometry(); + OnStepStarted("Building tiles"); + BuildTiles(); + OnStepStarted("Building tile borders"); + BuildTileBorders(); + OnStepStarted("Embedding tile mipmaps"); + if (Config.EmbedMips) + { + EmbedTileMips(); + } + + BuildGTS(); + + long tileBytes = 0, embeddedMipBytes = 0, tileCompressedBytes = 0, pages = 0, chunks = 0, levelTiles = 0; + + foreach (var pageFile in PageFiles) + { + pages += pageFile.Pages.Count; + foreach (var page in pageFile.Pages) + { + chunks += page.Chunks.Count; + } + } + + foreach (var level in PerLevelFlatTiles) + { + levelTiles += level.Length; + foreach (var tile in level) + { + if (tile != null) + { + tileBytes += tile.Image.Data.Length; + if (tile.EmbeddedMip != null) + { + embeddedMipBytes += tile.EmbeddedMip.Data.Length; + } + + tileCompressedBytes += tile.Compressed.Data.Length; + } + } + } + + Console.WriteLine($"Flat tiles: {levelTiles} total, {TileSet.FlatTileInfos.Length} in use"); + Console.WriteLine($"Generated {PageFiles.Count} page files, {pages} pages, {chunks} chunks"); + Console.WriteLine($"Raw tile data: {tileBytes / 1024} KB tiles, {embeddedMipBytes / 1024} KB embedded mips, {tileCompressedBytes / 1024} KB transcoded, {pages*Config.PageSize/1024} KB pages total"); + + OnStepStarted("Saving tile set"); + TileSet.Save(dir + "\\" + BuildData.GTSName + ".gts"); + + foreach (var file in PageFiles) + { + OnStepStarted($"Saving page file: {file.FileName}"); + file.Save(dir + "\\" + file.FileName); + } + } + } +} diff --git a/LSLib/VirtualTextures/Compression.cs b/LSLib/VirtualTextures/Compression.cs new file mode 100644 index 00000000..8a59fad6 --- /dev/null +++ b/LSLib/VirtualTextures/Compression.cs @@ -0,0 +1,154 @@ +using System; +using System.IO; +using LZ4; + +namespace LSLib.VirtualTextures +{ + public enum TileCompressionMethod + { + Raw, + LZ4, + LZ77 + }; + + public enum TileCompressionPreference + { + Uncompressed, + Best, + LZ4, + LZ77 + }; + + public class CompressedTile + { + public TileCompressionMethod Method; + public UInt32 ParameterBlockID; + public byte[] Data; + } + + public class TileCompressor + { + public ParameterBlockContainer ParameterBlocks; + public TileCompressionPreference Preference = TileCompressionPreference.Best; + + private byte[] GetRawBytes(BuildTile tile) + { + if (tile.EmbeddedMip == null) + { + return tile.Image.Data; + } + else + { + var data = new byte[tile.Image.Data.Length + tile.EmbeddedMip.Data.Length]; + Array.Copy(tile.Image.Data, 0, data, 0, tile.Image.Data.Length); + Array.Copy(tile.EmbeddedMip.Data, 0, data, tile.Image.Data.Length, tile.EmbeddedMip.Data.Length); + return data; + } + } + + public static byte[] CompressLZ4(byte[] raw) + { + return LZ4Codec.EncodeHC(raw, 0, raw.Length); + } + + public static byte[] CompressLZ77(byte[] raw) + { + return Native.FastLZCompressor.Compress(raw, 2); + } + + public byte[] Compress(byte[] uncompressed, out TileCompressionMethod method) + { + switch (Preference) + { + case TileCompressionPreference.Uncompressed: + method = TileCompressionMethod.Raw; + return uncompressed; + + case TileCompressionPreference.Best: + var lz4 = CompressLZ4(uncompressed); + var lz77 = CompressLZ77(uncompressed); + if (lz4.Length <= lz77.Length) + { + method = TileCompressionMethod.LZ4; + return lz4; + } + else + { + method = TileCompressionMethod.LZ77; + return lz77; + } + + case TileCompressionPreference.LZ4: + method = TileCompressionMethod.LZ4; + return CompressLZ4(uncompressed); + + case TileCompressionPreference.LZ77: + method = TileCompressionMethod.LZ77; + return CompressLZ77(uncompressed); + + default: + throw new ArgumentException("Invalid compression preference"); + } + } + + public CompressedTile Compress(BuildTile tile) + { + if (tile.Compressed != null) + { + return tile.Compressed; + } + + var uncompressed = GetRawBytes(tile); + var compressed = new CompressedTile(); + compressed.Data = Compress(uncompressed, out compressed.Method); + + var paramBlock = ParameterBlocks.GetOrAdd(tile.Codec, tile.DataType, compressed.Method); + compressed.ParameterBlockID = paramBlock.ParameterBlockID; + + tile.Compressed = compressed; + return compressed; + } + + public TileCompressionMethod GetMethod(string method1, string method2) + { + if (method1 == "lz77" && method2 == "fastlz0.1.0") + { + return TileCompressionMethod.LZ77; + } + else if (method1 == "lz4" && method2 == "lz40.1.0") + { + return TileCompressionMethod.LZ4; + } + else if (method1 == "raw") + { + return TileCompressionMethod.Raw; + } + else + { + throw new InvalidDataException($"Unsupported compression format: '{method1}', '{method2}'"); + } + } + + public byte[] Decompress(byte[] compressed, int outputSize, string method1, string method2) + { + return Decompress(compressed, outputSize, GetMethod(method1, method2)); + } + + public byte[] Decompress(byte[] compressed, int outputSize, TileCompressionMethod method) + { + switch (method) + { + case TileCompressionMethod.Raw: + return compressed; + case TileCompressionMethod.LZ4: + var decompressed = new byte[outputSize]; + LZ4Codec.Decode(compressed, 0, compressed.Length, decompressed, 0, outputSize, true); + return decompressed; + case TileCompressionMethod.LZ77: + return Native.FastLZCompressor.Decompress(compressed, outputSize); + default: + throw new ArgumentException(); + } + } + } +} diff --git a/LSLib/VirtualTextures/Geometry.cs b/LSLib/VirtualTextures/Geometry.cs new file mode 100644 index 00000000..53fee2bc --- /dev/null +++ b/LSLib/VirtualTextures/Geometry.cs @@ -0,0 +1,183 @@ +using System; +using System.Collections.Generic; + +namespace LSLib.VirtualTextures +{ + public class TileSetGeometryCalculator + { + public List Textures; + public TileSetBuildData BuildData; + + private int PlacementTileWidth = 0x1000; + private int PlacementTileHeight = 0x1000; + private int PlacementGridWidth; + private int PlacementGridHeight; + private BuildTexture[] PlacementGrid; + + private void ResizePlacementGrid(int w, int h) + { + PlacementGridWidth = w; + PlacementGridHeight = h; + PlacementGrid = new BuildTexture[w * h]; + } + + private void GrowPlacementGrid() + { + if (PlacementGridWidth <= PlacementGridHeight) + { + ResizePlacementGrid(PlacementGridWidth * 2, PlacementGridHeight); + } + else + { + ResizePlacementGrid(PlacementGridWidth, PlacementGridHeight * 2); + } + } + + private bool TryToPlaceTexture(BuildTexture texture, int texX, int texY) + { + var width = texture.Width / BuildData.RawTileWidth / PlacementTileWidth; + var height = texture.Height / BuildData.RawTileHeight / PlacementTileHeight; + + for (var y = texY; y < texY + height; y++) + { + for (var x = texX; x < texX + width; x++) + { + if (PlacementGrid[x + y * PlacementGridWidth] != null) + { + return false; + } + } + } + + texture.X = texX * PlacementTileWidth * BuildData.RawTileWidth; + texture.Y = texY * PlacementTileHeight * BuildData.RawTileHeight; + + for (var y = texY; y < texY + height; y++) + { + for (var x = texX; x < texX + width; x++) + { + PlacementGrid[x + y * PlacementGridWidth] = texture; + } + } + + return true; + } + + private bool TryToPlaceTexture(BuildTexture texture) + { + var width = texture.Width / BuildData.RawTileWidth / PlacementTileWidth; + var height = texture.Height / BuildData.RawTileHeight / PlacementTileHeight; + + for (var y = 0; y < PlacementGridHeight - height + 1; y++) + { + for (var x = 0; x < PlacementGridWidth - width + 1; x++) + { + if (TryToPlaceTexture(texture, x, y)) + { + return true; + } + } + } + + return false; + } + + private bool PlaceAllTextures() + { + foreach (var tex in Textures) + { + if (!TryToPlaceTexture(tex)) + { + return false; + } + } + + return true; + } + + private void DoAutoPlacement() + { + var startingX = 0; + var startingY = 0; + + foreach (var tex in Textures) + { + PlacementTileWidth = Math.Min(PlacementTileWidth, tex.Width / BuildData.RawTileWidth); + PlacementTileHeight = Math.Min(PlacementTileHeight, tex.Height / BuildData.RawTileHeight); + startingX = Math.Max(startingX, tex.Width / BuildData.RawTileWidth); + startingY = Math.Max(startingY, tex.Height / BuildData.RawTileHeight); + } + + ResizePlacementGrid(startingX / PlacementTileWidth, startingY / PlacementTileHeight); + + while (!PlaceAllTextures()) + { + GrowPlacementGrid(); + } + + BuildData.TotalWidth = PlacementTileWidth * PlacementGridWidth * BuildData.RawTileWidth; + BuildData.TotalHeight = PlacementTileHeight * PlacementGridHeight * BuildData.RawTileWidth; + } + + private void UpdateGeometry() + { + var minTexSize = 0x10000; + foreach (var tex in Textures) + { + minTexSize = Math.Min(minTexSize, Math.Min(tex.Height, tex.Width)); + } + + BuildData.MipFileStartLevel = 0; + while (minTexSize >= BuildData.RawTileHeight) + { + BuildData.MipFileStartLevel++; + minTexSize >>= 1; + } + + // Max W/H of all textures + var maxSize = Math.Max(BuildData.TotalWidth, BuildData.TotalHeight); + BuildData.PageFileLevels = 0; + while (maxSize >= BuildData.RawTileHeight) + { + BuildData.PageFileLevels++; + maxSize >>= 1; + } + + BuildData.BuildLevels = BuildData.PageFileLevels + 1; + + foreach (var layer in BuildData.Layers) + { + var levelWidth = BuildData.TotalWidth; + var levelHeight = BuildData.TotalHeight; + + layer.Levels = new List(BuildData.BuildLevels); + for (var i = 0; i < BuildData.BuildLevels; i++) + { + var tilesX = levelWidth / BuildData.RawTileWidth + (((levelWidth % BuildData.RawTileWidth) > 0) ? 1 : 0); + var tilesY = levelHeight / BuildData.RawTileHeight + (((levelHeight % BuildData.RawTileHeight) > 0) ? 1 : 0); + var level = new BuildLevel + { + Level = i, + Width = tilesX * BuildData.RawTileWidth, + Height = tilesY * BuildData.RawTileHeight, + TilesX = tilesX, + TilesY = tilesY, + PaddedTileWidth = BuildData.PaddedTileWidth, + PaddedTileHeight = BuildData.PaddedTileHeight, + Tiles = new BuildTile[tilesX * tilesY] + }; + layer.Levels.Add(level); + + levelWidth = Math.Max(1, levelWidth >> 1); + levelHeight = Math.Max(1, levelHeight >> 1); + } + } + } + + public void Update() + { + DoAutoPlacement(); + UpdateGeometry(); + } + } +} diff --git a/LSLib/VirtualTextures/PageFile.cs b/LSLib/VirtualTextures/PageFile.cs index bc00b98f..68f8f434 100644 --- a/LSLib/VirtualTextures/PageFile.cs +++ b/LSLib/VirtualTextures/PageFile.cs @@ -2,19 +2,16 @@ using System; using System.Collections.Generic; using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace LSLib.VirtualTextures { public class PageFile : IDisposable { - private VirtualTileSet TileSet; - private FileStream Stream; - private BinaryReader Reader; + private readonly VirtualTileSet TileSet; + private readonly FileStream Stream; + private readonly BinaryReader Reader; public GTPHeader Header; - private List ChunkOffsets; + private readonly List ChunkOffsets; public PageFile(VirtualTileSet tileset, string path) { @@ -25,7 +22,7 @@ public PageFile(VirtualTileSet tileset, string path) Header = BinUtils.ReadStruct(Reader); var numPages = Stream.Length / tileset.Header.PageSize; - ChunkOffsets = new List(); + ChunkOffsets = []; for (var page = 0; page < numPages; page++) { @@ -44,22 +41,11 @@ public void Dispose() Stream.Dispose(); } - private byte[] DoUnpackTileBC(GTPChunkHeader header, int outputSize) + private byte[] DoUnpackTileBC(GTPChunkHeader header, int outputSize, TileCompressor compressor) { var parameterBlock = (GTSBCParameterBlock)TileSet.ParameterBlocks[header.ParameterBlockID]; - if (parameterBlock.CompressionName1 == "lz77" && parameterBlock.CompressionName2 == "fastlz0.1.0") - { - var buf = Reader.ReadBytes((int)header.Size); - return Native.FastLZCompressor.Decompress(buf, outputSize); - } - else if (parameterBlock.CompressionName1 == "raw") - { - return Reader.ReadBytes((int)header.Size); - } - else - { - throw new InvalidDataException($"Unsupported BC compression format: '{parameterBlock.CompressionName1}', '{parameterBlock.CompressionName2}'"); - } + var compressed = Reader.ReadBytes((int)header.Size); + return compressor.Decompress(compressed, outputSize, parameterBlock.CompressionName1, parameterBlock.CompressionName2); } private byte[] DoUnpackTileUniform(GTPChunkHeader header) @@ -71,23 +57,23 @@ private byte[] DoUnpackTileUniform(GTPChunkHeader header) return img; } - public byte[] UnpackTile(int pageIndex, int chunkIndex, int outputSize) + public byte[] UnpackTile(int pageIndex, int chunkIndex, int outputSize, TileCompressor compressor) { Stream.Position = ChunkOffsets[pageIndex][chunkIndex] + (pageIndex * TileSet.Header.PageSize); var chunkHeader = BinUtils.ReadStruct(Reader); - switch (chunkHeader.Codec) + return chunkHeader.Codec switch { - case GTSCodec.Uniform: return DoUnpackTileUniform(chunkHeader); - case GTSCodec.BC: return DoUnpackTileBC(chunkHeader, outputSize); - default: throw new InvalidDataException($"Unsupported codec: {chunkHeader.Codec}"); - } + GTSCodec.Uniform => DoUnpackTileUniform(chunkHeader), + GTSCodec.BC => DoUnpackTileBC(chunkHeader, outputSize, compressor), + _ => throw new InvalidDataException($"Unsupported codec: {chunkHeader.Codec}"), + }; } - public BC5Image UnpackTileBC5(int pageIndex, int chunkIndex) + public BC5Image UnpackTileBC5(int pageIndex, int chunkIndex, TileCompressor compressor) { var compressedSize = 16 * ((TileSet.Header.TileWidth + 3) / 4) * ((TileSet.Header.TileHeight + 3) / 4) + 16 * ((TileSet.Header.TileWidth/2 + 3) / 4) * ((TileSet.Header.TileHeight/2 + 3) / 4); - var chunk = UnpackTile(pageIndex, chunkIndex, compressedSize); + var chunk = UnpackTile(pageIndex, chunkIndex, compressedSize, compressor); return new BC5Image(chunk, TileSet.Header.TileWidth, TileSet.Header.TileHeight); } } diff --git a/LSLib/VirtualTextures/PageFileBuild.cs b/LSLib/VirtualTextures/PageFileBuild.cs new file mode 100644 index 00000000..d6a7a50b --- /dev/null +++ b/LSLib/VirtualTextures/PageFileBuild.cs @@ -0,0 +1,289 @@ +using LSLib.LS; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Runtime.InteropServices; + +namespace LSLib.VirtualTextures +{ + + public class BuiltChunk + { + public GTSCodec Codec; + public UInt32 ParameterBlockID; + public byte[] EncodedBlob; + public int ChunkIndex; + public UInt32 OffsetInPage; + } + + public class PageBuilder + { + public PageFileBuilder PageFile; + public List Chunks; + public int PageFileIndex; + public int PageIndex; + public int Budget = 0; + + public PageBuilder() + { + Chunks = []; + } + + public bool TryAdd(BuildTile tile) + { + if (tile.AddedToPageFile) + { + throw new InvalidOperationException("Tried to add tile to page file multiple times"); + } + + var chunkSize = 4 + Marshal.SizeOf(typeof(GTPChunkHeader)) + tile.Compressed.Data.Length; + if (Budget + chunkSize > PageFile.Config.PageSize) + { + return false; + } + + var chunk = new BuiltChunk + { + Codec = GTSCodec.BC, + ParameterBlockID = tile.Compressed.ParameterBlockID, + EncodedBlob = tile.Compressed.Data, + ChunkIndex = Chunks.Count + }; + + tile.AddedToPageFile = true; + tile.PageFileIndex = PageFileIndex; + tile.PageIndex = PageIndex; + tile.ChunkIndex = chunk.ChunkIndex; + Chunks.Add(chunk); + Budget += chunkSize; + return true; + } + } + + public class PageFileBuilder(TileSetConfiguration config) + { + public readonly TileSetConfiguration Config = config; + public List Pages = []; + public string Name; + public string FileName; + public Guid Checksum; + public int PageFileIndex; + + public void AddTile(BuildTile tile) + { + if (Config.BackfillPages) + { + foreach (var page in Pages) + { + if (page.TryAdd(tile)) + { + return; + } + } + } + + if (Pages.Count == 0 || !Pages.Last().TryAdd(tile)) + { + var newPage = new PageBuilder + { + PageFile = this, + PageFileIndex = PageFileIndex, + PageIndex = Pages.Count + }; + + if (newPage.PageIndex == 0) + { + newPage.Budget += Marshal.SizeOf(typeof(GTPHeader)); + } + + Pages.Add(newPage); + newPage.TryAdd(tile); + } + } + + public void Save(string path) + { + using var stream = new FileStream(path, FileMode.Create, FileAccess.ReadWrite); + using var writer = new BinaryWriter(stream); + Save(stream, writer); + } + + public void SaveChunk(BinaryWriter writer, BuiltChunk chunk) + { + var header = new GTPChunkHeader + { + Codec = chunk.Codec, + ParameterBlockID = chunk.ParameterBlockID, + Size = (UInt32)chunk.EncodedBlob.Length + }; + BinUtils.WriteStruct(writer, ref header); + writer.Write(chunk.EncodedBlob); + } + + public void Save(Stream s, BinaryWriter writer) + { + var header = new GTPHeader + { + Magic = GTPHeader.HeaderMagic, + Version = GTPHeader.DefaultVersion, + GUID = Checksum + }; + BinUtils.WriteStruct(writer, ref header); + + for (var i = 0; i < Pages.Count; i++) + { + var page = Pages[i]; + + writer.Write((UInt32)page.Chunks.Count); + foreach (var chunk in page.Chunks) + { + writer.Write(chunk.OffsetInPage); + } + + foreach (var chunk in page.Chunks) + { + chunk.OffsetInPage = (uint)(s.Position % Config.PageSize); + SaveChunk(writer, chunk); + } + + var padSize = (Config.PageSize - (s.Position % Config.PageSize) % Config.PageSize); + if (padSize > 0) + { + var pad = new byte[padSize]; + Array.Clear(pad, 0, (int)padSize); + writer.Write(pad); + } + } + + for (var i = 0; i < Pages.Count; i++) + { + var page = Pages[i]; + s.Position = (i * Config.PageSize); + if (i == 0) + { + s.Position += Marshal.SizeOf(typeof(GTPHeader)); + } + + writer.Write((UInt32)page.Chunks.Count); + foreach (var chunk in page.Chunks) + { + writer.Write(chunk.OffsetInPage); + } + } + } + } + + public class PageFileSetBuilder(TileSetBuildData buildData, TileSetConfiguration config) + { + private readonly TileSetBuildData BuildData = buildData; + private readonly TileSetConfiguration Config = config; + + private void BuildPageFile(PageFileBuilder file, int level, int minTileX, int minTileY, int maxTileX, int maxTileY) + { + for (var y = minTileY; y <= maxTileY; y++) + { + for (var x = minTileX; x <= maxTileX; x++) + { + for (var layer = 0; layer < BuildData.Layers.Count; layer++) + { + var tile = BuildData.Layers[layer].Levels[level].Get(x, y); + if (tile != null) + { + file.AddTile(tile); + } + } + } + } + } + + private void BuildPageFile(PageFileBuilder file, BuildTexture texture) + { + for (var level = 0; level < BuildData.MipFileStartLevel; level++) + { + var x = texture.X >> level; + var y = texture.Y >> level; + var width = texture.Width >> level; + var height = texture.Height >> level; + + var minTileX = x / BuildData.RawTileWidth; + var minTileY = y / BuildData.RawTileHeight; + var maxTileX = (x + width - 1) / BuildData.RawTileWidth; + var maxTileY = (y + height - 1) / BuildData.RawTileHeight; + + BuildPageFile(file, level, minTileX, minTileY, maxTileX, maxTileY); + } + } + + private void BuildMipPageFile(PageFileBuilder file) + { + for (var level = BuildData.MipFileStartLevel; level < BuildData.PageFileLevels; level++) + { + var lvl = BuildData.Layers[0].Levels[level]; + BuildPageFile(file, level, 0, 0, lvl.TilesX - 1, lvl.TilesY - 1); + } + } + + private void BuildFullPageFile(PageFileBuilder file) + { + for (var level = 0; level < BuildData.PageFileLevels; level++) + { + var lvl = BuildData.Layers[0].Levels[level]; + BuildPageFile(file, level, 0, 0, lvl.TilesX - 1, lvl.TilesY - 1); + } + } + + public List BuildFilePerGTex(List textures) + { + var pageFiles = new List(); + + uint firstPageIndex = 0; + foreach (var texture in textures) + { + var file = new PageFileBuilder(Config) + { + Name = texture.Name, + FileName = BuildData.GTSName + "_" + texture.Name + ".gtp", + Checksum = Guid.NewGuid(), + PageFileIndex = pageFiles.Count + }; + pageFiles.Add(file); + BuildPageFile(file, texture); + + firstPageIndex += (uint)file.Pages.Count; + } + + if (BuildData.MipFileStartLevel < BuildData.PageFileLevels) + { + var file = new PageFileBuilder(Config) + { + Name = "Mips", + FileName = BuildData.GTSName + "_Mips.gtp", + Checksum = Guid.NewGuid(), + PageFileIndex = pageFiles.Count + }; + pageFiles.Add(file); + BuildMipPageFile(file); + } + + return pageFiles; + } + + public List BuildSingleFile() + { + var pageFiles = new List(); + + var file = new PageFileBuilder(Config) + { + Name = "Global", + FileName = BuildData.GTSName + ".gtp", + Checksum = Guid.NewGuid(), + PageFileIndex = pageFiles.Count + }; + pageFiles.Add(file); + BuildFullPageFile(file); + + return pageFiles; + } + } +} diff --git a/LSLib/VirtualTextures/VirtualTexture.cs b/LSLib/VirtualTextures/VirtualTexture.cs index 4021b420..99b2faf6 100644 --- a/LSLib/VirtualTextures/VirtualTexture.cs +++ b/LSLib/VirtualTextures/VirtualTexture.cs @@ -3,9 +3,7 @@ using System.Collections.Generic; using System.Diagnostics; using System.IO; -using System.Linq; using System.Text; -using System.Threading.Tasks; namespace LSLib.VirtualTextures { @@ -40,7 +38,7 @@ public static FourCCElement Make(string fourCC) { Type = FourCCElementType.Node, FourCC = fourCC, - Children = new List() + Children = [] }; } @@ -73,6 +71,28 @@ public static FourCCElement Make(string fourCC, FourCCElementType type, byte[] v Blob = value }; } + + public FourCCElement GetChild(string fourCC) + { + foreach (var child in Children) + { + if (child.FourCC == fourCC) + { + return child; + } + } + + return null; + } + } + + public class FourCCTextureMeta + { + public string Name; + public int X; + public int Y; + public int Width; + public int Height; } public class TileSetFourCC @@ -98,7 +118,7 @@ public void Read(Stream fs, BinaryReader reader, long length, List(); + cc.Children = []; Read(fs, reader, valueSize, cc.Children); break; } @@ -159,6 +179,27 @@ public void Read(Stream fs, BinaryReader reader, long length, List ExtractTextureMetadata() + { + var metaList = new List(); + var textures = Root.GetChild("ATLS").GetChild("TXTS").Children; + foreach (var tex in textures) + { + var meta = new FourCCTextureMeta + { + Name = tex.GetChild("NAME").Str, + Width = (int)tex.GetChild("WDTH").UInt, + Height = (int)tex.GetChild("HGHT").UInt, + X = (int)tex.GetChild("XXXX").UInt, + Y = (int)tex.GetChild("YYYY").UInt + }; + metaList.Add(meta); + } + + return metaList; + } + public void Write(Stream fs, BinaryWriter writer) { Write(fs, writer, Root); @@ -166,58 +207,29 @@ public void Write(Stream fs, BinaryWriter writer) public void Write(Stream fs, BinaryWriter writer, FourCCElement element) { - var header = new GTSFourCCMetadata(); - header.FourCCName = element.FourCC; - - UInt32 length; - switch (element.Type) + var header = new GTSFourCCMetadata { - case FourCCElementType.Node: - length = 0x10000000; - break; - - case FourCCElementType.Int: - length = 4; - break; - - case FourCCElementType.String: - length = (UInt32)Encoding.Unicode.GetBytes(element.Str).Length + 2; - break; - - case FourCCElementType.BinaryInt: - case FourCCElementType.BinaryGuid: - length = (UInt32)element.Blob.Length; - break; - - default: - throw new InvalidDataException($"Unsupported FourCC value type: {element.Type}"); - } + FourCCName = element.FourCC + }; - switch (element.Type) + var length = element.Type switch { - case FourCCElementType.Node: - header.Format = 1; - break; - - case FourCCElementType.Int: - header.Format = 3; - break; - - case FourCCElementType.String: - header.Format = 2; - break; - - case FourCCElementType.BinaryInt: - header.Format = 8; - break; - - case FourCCElementType.BinaryGuid: - header.Format = 0xD; - break; + FourCCElementType.Node => (uint)0x10000000, + FourCCElementType.Int => (uint)4, + FourCCElementType.String => (UInt32)Encoding.Unicode.GetBytes(element.Str).Length + 2, + FourCCElementType.BinaryInt or FourCCElementType.BinaryGuid => (UInt32)element.Blob.Length, + _ => throw new InvalidDataException($"Unsupported FourCC value type: {element.Type}"), + }; - default: - throw new InvalidDataException($"Unsupported FourCC value type: {element.Type}"); - } + header.Format = element.Type switch + { + FourCCElementType.Node => 1, + FourCCElementType.Int => 3, + FourCCElementType.String => 2, + FourCCElementType.BinaryInt => 8, + FourCCElementType.BinaryGuid => 0xD, + _ => throw new InvalidDataException($"Unsupported FourCC value type: {element.Type}"), + }; header.Length = (UInt16)(length & 0xffff); if (length > 0xffff) @@ -294,17 +306,17 @@ public class VirtualTileSet : IDisposable public GTSPackedTileID[] PackedTileIDs; public GTSFlatTileInfo[] FlatTileInfos; - private Dictionary PageFiles = new Dictionary(); + private readonly Dictionary PageFiles = []; + private readonly TileCompressor Compressor; public VirtualTileSet(string path, string pagePath) { PagePath = pagePath; + Compressor = new TileCompressor(); - using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read)) - using (var reader = new BinaryReader(fs)) - { - LoadFromStream(fs, reader, false); - } + using var fs = new FileStream(path, FileMode.Open, FileAccess.Read); + using var reader = new BinaryReader(fs); + LoadFromStream(fs, reader, false); } public VirtualTileSet(string path) : this(path, Path.GetDirectoryName(path)) @@ -317,11 +329,9 @@ public VirtualTileSet() public void Save(string path) { - using (var fs = new FileStream(path, FileMode.Create, FileAccess.Write)) - using (var writer = new BinaryWriter(fs)) - { - SaveToStream(fs, writer); - } + using var fs = new FileStream(path, FileMode.Create, FileAccess.Write); + using var writer = new BinaryWriter(fs); + SaveToStream(fs, writer); } public void Dispose() @@ -383,7 +393,7 @@ public void LoadFromStream(Stream fs, BinaryReader reader, bool loadThumbnails) TileSetLevels = new GTSTileSetLevel[Header.NumLevels]; BinUtils.ReadStructs(reader, TileSetLevels); - PerLevelFlatTileIndices = new List(); + PerLevelFlatTileIndices = []; foreach (var level in TileSetLevels) { fs.Position = (uint)level.FlatTileIndicesOffset; @@ -396,7 +406,7 @@ public void LoadFromStream(Stream fs, BinaryReader reader, bool loadThumbnails) ParameterBlockHeaders = new GTSParameterBlockHeader[Header.ParameterBlockHeadersCount]; BinUtils.ReadStructs(reader, ParameterBlockHeaders); - ParameterBlocks = new Dictionary(); + ParameterBlocks = []; foreach (var hdr in ParameterBlockHeaders) { fs.Position = (uint)hdr.FileInfoOffset; @@ -409,15 +419,15 @@ public void LoadFromStream(Stream fs, BinaryReader reader, bool loadThumbnails) Debug.Assert(bc.B == 0); Debug.Assert(bc.C1 == 0); Debug.Assert(bc.C2 == 0); - Debug.Assert(bc.DataType == (Byte)GTSDataType.R8G8B8A8_SRGB || bc.DataType == (Byte)GTSDataType.X8Y8Z8W8); Debug.Assert(bc.BCField3 == 0); + Debug.Assert(bc.DataType == (Byte)GTSDataType.R8G8B8A8_SRGB || bc.DataType == (Byte)GTSDataType.X8Y8Z8W8); + Debug.Assert(bc.D == 0); + Debug.Assert(bc.FourCC == 0x20334342); Debug.Assert(bc.E1 == 0); - Debug.Assert(bc.E3 == 0); Debug.Assert(bc.SaveMip == 1); + Debug.Assert(bc.E3 == 0); Debug.Assert(bc.E4 == 0); - Debug.Assert(bc.D == 0); Debug.Assert(bc.F == 0); - Debug.Assert(bc.FourCC == 0x20334342); } else { @@ -438,7 +448,7 @@ public void LoadFromStream(Stream fs, BinaryReader reader, bool loadThumbnails) var pageFileInfos = new GTSPageFileInfo[Header.NumPageFiles]; BinUtils.ReadStructs(reader, pageFileInfos); - PageFileInfos = new List(); + PageFileInfos = []; uint nextPageIndex = 0; foreach (var info in pageFileInfos) { @@ -504,15 +514,6 @@ public void SaveToStream(Stream fs, BinaryWriter writer) if (hdr.Codec == GTSCodec.BC) { var block = (GTSBCParameterBlock)ParameterBlocks[hdr.ParameterBlockID]; - hdr.ParameterBlockSize = 0x38; - block.Version = 0x238e; - var comp1 = Encoding.UTF8.GetBytes("lz77"); - Array.Copy(comp1, block.Compression1, comp1.Length); - var comp2 = Encoding.UTF8.GetBytes("fastlz0.1.0"); - Array.Copy(comp2, block.Compression2, comp2.Length); - block.DataType = (Byte)GTSDataType.R8G8B8A8_SRGB; // X8Y8Z8W8 for normal/phys - block.SaveMip = 1; - block.FourCC = 0x20334342; BinUtils.WriteStruct(writer, ref block); } else @@ -521,11 +522,6 @@ public void SaveToStream(Stream fs, BinaryWriter writer) hdr.ParameterBlockSize = 0x10; var block = (GTSUniformParameterBlock)ParameterBlocks[hdr.ParameterBlockID]; - block.Version = 0x42; - block.A_Unused = 0; - block.Width = 4; - block.Height = 1; - block.DataType = GTSDataType.R8G8B8A8_SRGB; // X8Y8Z8W8 for normal/phys BinUtils.WriteStruct(writer, ref block); } } @@ -544,8 +540,10 @@ public void SaveToStream(Stream fs, BinaryWriter writer) Header.FourCCListSize = (uint)((ulong)fs.Position - Header.FourCCListOffset); Header.ThumbnailsOffset = (ulong)fs.Position; - var thumbHdr = new GTSThumbnailInfoHeader(); - thumbHdr.NumThumbnails = 0; + var thumbHdr = new GTSThumbnailInfoHeader + { + NumThumbnails = 0 + }; BinUtils.WriteStruct(writer, ref thumbHdr); Header.PackedTileIDsOffset = (ulong)fs.Position; @@ -581,8 +579,7 @@ public bool GetTileInfo(int level, int layer, int x, int y, ref GTSFlatTileInfo public PageFile GetOrLoadPageFile(int pageFileIdx) { - PageFile file; - if (!PageFiles.TryGetValue(pageFileIdx, out file)) + if (!PageFiles.TryGetValue(pageFileIdx, out PageFile file)) { var meta = PageFileInfos[pageFileIdx]; file = new PageFile(this, PagePath + Path.DirectorySeparatorChar + meta.FileName); @@ -596,7 +593,7 @@ public void StitchTexture(int level, int layer, int minX, int minY, int maxX, in { var tileWidth = Header.TileWidth - Header.TileBorder * 2; var tileHeight = Header.TileHeight - Header.TileBorder * 2; - GTSFlatTileInfo tileInfo = new GTSFlatTileInfo(); + GTSFlatTileInfo tileInfo = new(); for (var y = minY; y <= maxY; y++) { for (var x = minX; x <= maxX; x++) @@ -604,7 +601,7 @@ public void StitchTexture(int level, int layer, int minX, int minY, int maxX, in if (GetTileInfo(level, layer, x, y, ref tileInfo)) { var pageFile = GetOrLoadPageFile(tileInfo.PageFileIndex); - var tile = pageFile.UnpackTileBC5(tileInfo.PageIndex, tileInfo.ChunkIndex); + var tile = pageFile.UnpackTileBC5(tileInfo.PageIndex, tileInfo.ChunkIndex, Compressor); tile.CopyTo(output, 8, 8, (x - minX) * tileWidth, (y - minY) * tileHeight, tileWidth, tileHeight); } } @@ -638,50 +635,39 @@ public void ReleasePageFiles() this.PageFiles.Clear(); } - public BC5Image ExtractPageFileTexture(int pageFileIndex, int levelIndex, int layer) + public BC5Image ExtractTexture(int level, int layer, FourCCTextureMeta tex) { - int minX = 0, maxX = 0, minY = 0, maxY = 0; - bool foundPages = false; + var tlW = Header.TileWidth - Header.TileBorder * 2; + var tlH = Header.TileHeight - Header.TileBorder * 2; + var tX = tex.X / tlW; + var tY = tex.Y / tlH; + var tW = tex.Width / tlW; + var tH = tex.Height / tlH; + var lv = (1 << level); + + var minX = (tX / lv) + ((tX % lv) > 0 ? 1 : 0); + var minY = (tY / lv) + ((tY % lv) > 0 ? 1 : 0); + var maxX = ((tX+tW) / lv) + (((tX + tW) % lv) > 0 ? 1 : 0) - 1; + var maxY = ((tY+tH) / lv) + (((tY + tH) % lv) > 0 ? 1 : 0) - 1; + + return ExtractTextureIfExists(level, layer, minX, minY, maxX, maxY); + } - GTSFlatTileInfo tile = new GTSFlatTileInfo(); - var level = TileSetLevels[levelIndex]; - for (var x = 0; x < level.Width; x++) + public BC5Image ExtractTextureIfExists(int levelIndex, int layer, int minX, int minY, int maxX, int maxY) + { + GTSFlatTileInfo tile = new(); + for (var x = minX; x <= maxX; x++) { - for (var y = 0; y < level.Height; y++) + for (var y = minY; y <= maxY; y++) { - if (GetTileInfo(levelIndex, layer, x, y, ref tile)) + if (!GetTileInfo(levelIndex, layer, x, y, ref tile)) { - if (tile.PageFileIndex == pageFileIndex) - { - if (!foundPages) - { - minX = x; - maxX = x; - minY = y; - maxY = y; - foundPages = true; - } - else - { - minX = Math.Min(minX, x); - maxX = Math.Max(maxX, x); - minY = Math.Min(minY, y); - maxY = Math.Max(maxY, y); - } - } + return null; } } } - // Temporary workaround for page files that contain split textures - if (!foundPages || (maxX - minX) > 16 || (maxY - minY) > 16) - { - return null; - } - else - { - return ExtractTexture(levelIndex, layer, minX, minY, maxX, maxY); - } + return ExtractTexture(levelIndex, layer, minX, minY, maxX, maxY); } } } diff --git a/LSLib/VirtualTextures/VirtualTextureFormats.cs b/LSLib/VirtualTextures/VirtualTextureFormats.cs index f93a51a9..0a7f6a4d 100644 --- a/LSLib/VirtualTextures/VirtualTextureFormats.cs +++ b/LSLib/VirtualTextures/VirtualTextureFormats.cs @@ -1,4 +1,5 @@ -using System; +using LSLib.Granny; +using System; using System.Runtime.InteropServices; using System.Text; @@ -7,9 +8,9 @@ namespace LSLib.VirtualTextures [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct DDSHeader { - public static UInt32 DDSMagic = 0x20534444; - public static UInt32 HeaderSize = 0x7c; - public static UInt32 FourCC_DXT5 = 0x35545844; + public const UInt32 DDSMagic = 0x20534444; + public const UInt32 HeaderSize = 0x7c; + public const UInt32 FourCC_DXT5 = 0x35545844; public UInt32 dwMagic; public UInt32 dwSize; @@ -107,6 +108,9 @@ public enum GTSCodec : UInt32 [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct GTSHeader { + public const UInt32 GRPGMagic = 0x47505247; // 'GRPG' + public const UInt32 CurrentVersion = 5; + public UInt32 Magic; public UInt32 Version; public UInt32 Unused; @@ -194,6 +198,13 @@ public string CompressionName1 for (len = 0; len < Compression1.Length && Compression1[len] != 0; len ++) {} return Encoding.UTF8.GetString(Compression1, 0, len); } + set + { + Compression1 = new byte[0x10]; + Array.Clear(Compression1, 0, 0x10); + byte[] encoded = Encoding.UTF8.GetBytes(value); + Array.Copy(encoded, Compression1, encoded.Length); + } } public string CompressionName2 @@ -204,6 +215,13 @@ public string CompressionName2 for (len = 0; len < Compression2.Length && Compression2[len] != 0; len ++) {} return Encoding.UTF8.GetString(Compression2, 0, len); } + set + { + Compression2 = new byte[0x10]; + Array.Clear(Compression2, 0, 0x10); + byte[] encoded = Encoding.UTF8.GetBytes(value); + Array.Copy(encoded, Compression2, encoded.Length); + } } public UInt32 B; @@ -250,6 +268,13 @@ public string FileName } return Encoding.Unicode.GetString(FileNameBuf, 0, nameLen); } + set + { + FileNameBuf = new byte[512]; + Array.Clear(FileNameBuf, 0, 512); + byte[] encoded = Encoding.Unicode.GetBytes(value); + Array.Copy(encoded, FileNameBuf, encoded.Length); + } } } @@ -301,9 +326,12 @@ public struct GTSThumbnailInfo } [StructLayout(LayoutKind.Sequential, Pack = 1)] - public struct GTSPackedTileID + public struct GTSPackedTileID(UInt32 layer, UInt32 level, UInt32 x, UInt32 y) { - public UInt32 Val; + public UInt32 Val = (layer & 0xF) + | ((level & 0xF) << 4) + | ((y & 0xFFF) << 8) + | ((x & 0xFFF) << 20); public UInt32 Layer { @@ -352,6 +380,9 @@ public struct GTSFlatTileInfo [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct GTPHeader { + public const UInt32 HeaderMagic = 0x50415247; + public const UInt32 DefaultVersion = 4; + public UInt32 Magic; public UInt32 Version; public Guid GUID; diff --git a/LSLib/packages.config b/LSLib/packages.config deleted file mode 100644 index 1ccf9bc1..00000000 --- a/LSLib/packages.config +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - \ No newline at end of file diff --git a/LSTools.sln b/LSTools.sln index 40a847bd..ab953a61 100644 --- a/LSTools.sln +++ b/LSTools.sln @@ -1,37 +1,35 @@ - Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30330.147 +# Visual Studio Version 17 +VisualStudioVersion = 17.8.34309.116 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LSLib", "LSLib\LSLib.csproj", "{46372C50-4288-4B8E-AF21-C934560600E0}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "LSLib", "LSLib\LSLib.csproj", "{46372C50-4288-4B8E-AF21-C934560600E0}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "LSLibNative", "LSLibNative\LSLibNative.vcxproj", "{D8B26B12-E45C-47EA-88F7-56628EB2CCD1}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenTK", "OpenTK\OpenTK.csproj", "{ABB9DB44-14F2-46E0-A4B8-B46C300CA982}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ConverterApp", "ConverterApp\ConverterApp.csproj", "{FAD67294-6223-47E0-8838-E4E7FBC53ED2}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ConverterApp", "ConverterApp\ConverterApp.csproj", "{FAD67294-6223-47E0-8838-E4E7FBC53ED2}" ProjectSection(ProjectDependencies) = postProject {D8B26B12-E45C-47EA-88F7-56628EB2CCD1} = {D8B26B12-E45C-47EA-88F7-56628EB2CCD1} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Divine", "Divine\Divine.csproj", "{CBFEE38F-5F12-4D6F-B4FB-267FB68A6BEA}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Divine", "Divine\Divine.csproj", "{CBFEE38F-5F12-4D6F-B4FB-267FB68A6BEA}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RconClient", "RconClient\RconClient.csproj", "{EF82C289-53D6-41C8-B5C3-72B37655C7F3}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RconClient", "RconClient\RconClient.csproj", "{EF82C289-53D6-41C8-B5C3-72B37655C7F3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StoryCompiler", "StoryCompiler\StoryCompiler.csproj", "{32F08B9A-F50B-4C2E-AB56-533FED066DDE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StoryCompiler", "StoryCompiler\StoryCompiler.csproj", "{32F08B9A-F50B-4C2E-AB56-533FED066DDE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DebuggerFrontend", "DebuggerFrontend\DebuggerFrontend.csproj", "{31E71543-CBCF-43BB-AF77-D210D548118E}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "DebuggerFrontend", "DebuggerFrontend\DebuggerFrontend.csproj", "{31E71543-CBCF-43BB-AF77-D210D548118E}" ProjectSection(ProjectDependencies) = postProject {46372C50-4288-4B8E-AF21-C934560600E0} = {46372C50-4288-4B8E-AF21-C934560600E0} EndProjectSection EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StoryDecompiler", "StoryDecompiler\StoryDecompiler.csproj", "{E4B4F95E-F027-44D7-AB93-B96EF2E661B6}" -EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StatParser", "StatParser\StatParser.csproj", "{94D900D1-EC77-4170-8942-56E3736E44DE}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StoryDecompiler", "StoryDecompiler\StoryDecompiler.csproj", "{E4B4F95E-F027-44D7-AB93-B96EF2E661B6}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "UnpackGrid", "UnpackGrid\UnpackGrid.csproj", "{1948A6AF-41EE-4711-B617-B5CBA8434013}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "StatParser", "StatParser\StatParser.csproj", "{94D900D1-EC77-4170-8942-56E3736E44DE}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TerrainFixup", "TerrainFixup\TerrainFixup.csproj", "{C3B44D0D-D7D8-4080-859B-90B391F8D5B1}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VTexTool", "VTexTool\VTexTool.csproj", "{67E646C2-3C3C-4327-A0B4-40C1DB32579F}" + ProjectSection(ProjectDependencies) = postProject + {D8B26B12-E45C-47EA-88F7-56628EB2CCD1} = {D8B26B12-E45C-47EA-88F7-56628EB2CCD1} + EndProjectSection EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -64,18 +62,6 @@ Global {D8B26B12-E45C-47EA-88F7-56628EB2CCD1}.RelWithDebInfo|Any CPU.ActiveCfg = Release|x64 {D8B26B12-E45C-47EA-88F7-56628EB2CCD1}.RelWithDebInfo|Any CPU.Build.0 = Release|x64 {D8B26B12-E45C-47EA-88F7-56628EB2CCD1}.RelWithDebInfo|x64.ActiveCfg = Release|x64 - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.Debug|Any CPU.Build.0 = Debug|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.Debug|x64.ActiveCfg = Debug|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.Debug|x64.Build.0 = Debug|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.Release|Any CPU.ActiveCfg = Release|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.Release|Any CPU.Build.0 = Release|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.Release|x64.ActiveCfg = Release|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.Release|x64.Build.0 = Release|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982}.RelWithDebInfo|x64.Build.0 = Release|Any CPU {FAD67294-6223-47E0-8838-E4E7FBC53ED2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FAD67294-6223-47E0-8838-E4E7FBC53ED2}.Debug|Any CPU.Build.0 = Debug|Any CPU {FAD67294-6223-47E0-8838-E4E7FBC53ED2}.Debug|x64.ActiveCfg = Debug|Any CPU @@ -160,30 +146,18 @@ Global {94D900D1-EC77-4170-8942-56E3736E44DE}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU {94D900D1-EC77-4170-8942-56E3736E44DE}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU {94D900D1-EC77-4170-8942-56E3736E44DE}.RelWithDebInfo|x64.Build.0 = Release|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.Debug|Any CPU.Build.0 = Debug|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.Debug|x64.ActiveCfg = Debug|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.Debug|x64.Build.0 = Debug|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.Release|Any CPU.ActiveCfg = Release|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.Release|Any CPU.Build.0 = Release|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.Release|x64.ActiveCfg = Release|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.Release|x64.Build.0 = Release|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU - {1948A6AF-41EE-4711-B617-B5CBA8434013}.RelWithDebInfo|x64.Build.0 = Release|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.Debug|x64.ActiveCfg = Debug|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.Debug|x64.Build.0 = Debug|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.Release|Any CPU.Build.0 = Release|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.Release|x64.ActiveCfg = Release|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.Release|x64.Build.0 = Release|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU - {C3B44D0D-D7D8-4080-859B-90B391F8D5B1}.RelWithDebInfo|x64.Build.0 = Release|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.Debug|x64.ActiveCfg = Debug|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.Debug|x64.Build.0 = Debug|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.Release|Any CPU.Build.0 = Release|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.Release|x64.ActiveCfg = Release|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.Release|x64.Build.0 = Release|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.RelWithDebInfo|Any CPU.ActiveCfg = Release|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.RelWithDebInfo|Any CPU.Build.0 = Release|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.RelWithDebInfo|x64.ActiveCfg = Release|Any CPU + {67E646C2-3C3C-4327-A0B4-40C1DB32579F}.RelWithDebInfo|x64.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE diff --git a/OpenTK/Math/BezierCurve.cs b/OpenTK/Math/BezierCurve.cs deleted file mode 100644 index 4e3035bd..00000000 --- a/OpenTK/Math/BezierCurve.cs +++ /dev/null @@ -1,261 +0,0 @@ -#region --- License --- -/* Licensed under the MIT/X11 license. - * Copyright (c) 2006-2008 the OpenTK Team. - * This notice may not be removed from any source distribution. - * See license.txt for licensing detailed licensing details. - * - * Contributions by Georg W�chter. - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenTK -{ - /// - /// Represents a bezier curve with as many points as you want. - /// - [Serializable] - public struct BezierCurve - { - #region Fields - - private List points; - - /// - /// The parallel value. - /// - /// This value defines whether the curve should be calculated as a - /// parallel curve to the original bezier curve. A value of 0.0f represents - /// the original curve, 5.0f i.e. stands for a curve that has always a distance - /// of 5.0f to the orignal curve at any point. - public float Parallel; - - #endregion - - #region Properties - - /// - /// Gets the points of this curve. - /// - /// The first point and the last points represent the anchor points. - public IList Points - { - get - { - return points; - } - } - - #endregion - - #region Constructors - - /// - /// Constructs a new . - /// - /// The points. - public BezierCurve(IEnumerable points) - { - if (points == null) - throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures."); - - this.points = new List(points); - this.Parallel = 0.0f; - } - - /// - /// Constructs a new . - /// - /// The points. - public BezierCurve(params Vector2[] points) - { - if (points == null) - throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures."); - - this.points = new List(points); - this.Parallel = 0.0f; - } - - /// - /// Constructs a new . - /// - /// The parallel value. - /// The points. - public BezierCurve(float parallel, params Vector2[] points) - { - if (points == null) - throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures."); - - this.Parallel = parallel; - this.points = new List(points); - } - - /// - /// Constructs a new . - /// - /// The parallel value. - /// The points. - public BezierCurve(float parallel, IEnumerable points) - { - if (points == null) - throw new ArgumentNullException("points", "Must point to a valid list of Vector2 structures."); - - this.Parallel = parallel; - this.points = new List(points); - } - - #endregion - - #region Functions - - - /// - /// Calculates the point with the specified t. - /// - /// The t value, between 0.0f and 1.0f. - /// Resulting point. - public Vector2 CalculatePoint(float t) - { - return BezierCurve.CalculatePoint(points, t, Parallel); - } - - /// - /// Calculates the length of this bezier curve. - /// - /// The precision. - /// Length of curve. - /// The precision gets better as the - /// value gets smaller. - public float CalculateLength(float precision) - { - return BezierCurve.CalculateLength(points, precision, Parallel); - } - - #region Static methods - - /// - /// Calculates the length of the specified bezier curve. - /// - /// The points. - /// The precision value. - /// The precision gets better as the - /// value gets smaller. - public static float CalculateLength(IList points, float precision) - { - return BezierCurve.CalculateLength(points, precision, 0.0f); - } - - /// - /// Calculates the length of the specified bezier curve. - /// - /// The points. - /// The precision value. - /// The parallel value. - /// Length of curve. - /// The precision gets better as the - /// value gets smaller. - /// The parameter defines whether the curve should be calculated as a - /// parallel curve to the original bezier curve. A value of 0.0f represents - /// the original curve, 5.0f represents a curve that has always a distance - /// of 5.0f to the orignal curve. - public static float CalculateLength(IList points, float precision, float parallel) - { - float length = 0.0f; - Vector2 old = BezierCurve.CalculatePoint(points, 0.0f, parallel); - - for (float i = precision; i < (1.0f + precision); i += precision) - { - Vector2 n = CalculatePoint(points, i, parallel); - length += (n - old).Length; - old = n; - } - - return length; - } - - /// - /// Calculates the point on the given bezier curve with the specified t parameter. - /// - /// The points. - /// The t parameter, a value between 0.0f and 1.0f. - /// Resulting point. - public static Vector2 CalculatePoint(IList points, float t) - { - return BezierCurve.CalculatePoint(points, t, 0.0f); - } - - /// - /// Calculates the point on the given bezier curve with the specified t parameter. - /// - /// The points. - /// The t parameter, a value between 0.0f and 1.0f. - /// The parallel value. - /// Resulting point. - /// The parameter defines whether the curve should be calculated as a - /// parallel curve to the original bezier curve. A value of 0.0f represents - /// the original curve, 5.0f represents a curve that has always a distance - /// of 5.0f to the orignal curve. - public static Vector2 CalculatePoint(IList points, float t, float parallel) - { - Vector2 r = new Vector2(); - double c = 1.0d - (double)t; - float temp; - int i = 0; - - foreach (Vector2 pt in points) - { - temp = (float)MathHelper.BinomialCoefficient(points.Count - 1, i) * (float)(System.Math.Pow(t, i) * - System.Math.Pow(c, (points.Count - 1) - i)); - - r.X += temp * pt.X; - r.Y += temp * pt.Y; - i++; - } - - if (parallel == 0.0f) - return r; - - Vector2 perpendicular = new Vector2(); - - if (t != 0.0f) - perpendicular = r - BezierCurve.CalculatePointOfDerivative(points, t); - else - perpendicular = points[1] - points[0]; - - return r + Vector2.Normalize(perpendicular).PerpendicularRight * parallel; - } - - /// - /// Calculates the point with the specified t of the derivative of the given bezier function. - /// - /// The points. - /// The t parameter, value between 0.0f and 1.0f. - /// Resulting point. - private static Vector2 CalculatePointOfDerivative(IList points, float t) - { - Vector2 r = new Vector2(); - double c = 1.0d - (double)t; - float temp; - int i = 0; - - foreach (Vector2 pt in points) - { - temp = (float)MathHelper.BinomialCoefficient(points.Count - 2, i) * (float)(System.Math.Pow(t, i) * - System.Math.Pow(c, (points.Count - 2) - i)); - - r.X += temp * pt.X; - r.Y += temp * pt.Y; - i++; - } - - return r; - } - - #endregion - - #endregion - } -} diff --git a/OpenTK/Math/BezierCurveCubic.cs b/OpenTK/Math/BezierCurveCubic.cs deleted file mode 100644 index 149bbf7a..00000000 --- a/OpenTK/Math/BezierCurveCubic.cs +++ /dev/null @@ -1,163 +0,0 @@ -#region --- License --- -/* Licensed under the MIT/X11 license. - * Copyright (c) 2006-2008 the OpenTK Team. - * This notice may not be removed from any source distribution. - * See license.txt for licensing detailed licensing details. - * - * Contributions by Georg W�chter. - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenTK -{ - /// - /// Represents a cubic bezier curve with two anchor and two control points. - /// - [Serializable] - public struct BezierCurveCubic - { - #region Fields - - /// - /// Start anchor point. - /// - public Vector2 StartAnchor; - - /// - /// End anchor point. - /// - public Vector2 EndAnchor; - - /// - /// First control point, controls the direction of the curve start. - /// - public Vector2 FirstControlPoint; - - /// - /// Second control point, controls the direction of the curve end. - /// - public Vector2 SecondControlPoint; - - /// - /// Gets or sets the parallel value. - /// - /// This value defines whether the curve should be calculated as a - /// parallel curve to the original bezier curve. A value of 0.0f represents - /// the original curve, 5.0f i.e. stands for a curve that has always a distance - /// of 5.f to the orignal curve at any point. - public float Parallel; - - #endregion - - #region Constructors - - /// - /// Constructs a new . - /// - /// The start anchor point. - /// The end anchor point. - /// The first control point. - /// The second control point. - public BezierCurveCubic(Vector2 startAnchor, Vector2 endAnchor, Vector2 firstControlPoint, Vector2 secondControlPoint) - { - this.StartAnchor = startAnchor; - this.EndAnchor = endAnchor; - this.FirstControlPoint = firstControlPoint; - this.SecondControlPoint = secondControlPoint; - this.Parallel = 0.0f; - } - - /// - /// Constructs a new . - /// - /// The parallel value. - /// The start anchor point. - /// The end anchor point. - /// The first control point. - /// The second control point. - public BezierCurveCubic(float parallel, Vector2 startAnchor, Vector2 endAnchor, Vector2 firstControlPoint, Vector2 secondControlPoint) - { - this.Parallel = parallel; - this.StartAnchor = startAnchor; - this.EndAnchor = endAnchor; - this.FirstControlPoint = firstControlPoint; - this.SecondControlPoint = secondControlPoint; - } - - #endregion - - #region Functions - - /// - /// Calculates the point with the specified t. - /// - /// The t value, between 0.0f and 1.0f. - /// Resulting point. - public Vector2 CalculatePoint(float t) - { - Vector2 r = new Vector2(); - float c = 1.0f - t; - - r.X = (StartAnchor.X * c * c * c) + (FirstControlPoint.X * 3 * t * c * c) + (SecondControlPoint.X * 3 * t * t * c) - + EndAnchor.X * t * t * t; - r.Y = (StartAnchor.Y * c * c * c) + (FirstControlPoint.Y * 3 * t * c * c) + (SecondControlPoint.Y * 3 * t * t * c) - + EndAnchor.Y * t * t * t; - - if (Parallel == 0.0f) - return r; - - Vector2 perpendicular = new Vector2(); - - if (t == 0.0f) - perpendicular = FirstControlPoint - StartAnchor; - else - perpendicular = r - CalculatePointOfDerivative(t); - - return r + Vector2.Normalize(perpendicular).PerpendicularRight * Parallel; - } - - /// - /// Calculates the point with the specified t of the derivative of this function. - /// - /// The t, value between 0.0f and 1.0f. - /// Resulting point. - private Vector2 CalculatePointOfDerivative(float t) - { - Vector2 r = new Vector2(); - float c = 1.0f - t; - - r.X = (c * c * StartAnchor.X) + (2 * t * c * FirstControlPoint.X) + (t * t * SecondControlPoint.X); - r.Y = (c * c * StartAnchor.Y) + (2 * t * c * FirstControlPoint.Y) + (t * t * SecondControlPoint.Y); - - return r; - } - - /// - /// Calculates the length of this bezier curve. - /// - /// The precision. - /// Length of the curve. - /// The precision gets better when the - /// value gets smaller. - public float CalculateLength(float precision) - { - float length = 0.0f; - Vector2 old = CalculatePoint(0.0f); - - for (float i = precision; i < (1.0f + precision); i += precision) - { - Vector2 n = CalculatePoint(i); - length += (n - old).Length; - old = n; - } - - return length; - } - - #endregion - } -} diff --git a/OpenTK/Math/BezierCurveQuadric.cs b/OpenTK/Math/BezierCurveQuadric.cs deleted file mode 100644 index 500b7fff..00000000 --- a/OpenTK/Math/BezierCurveQuadric.cs +++ /dev/null @@ -1,151 +0,0 @@ -#region --- License --- -/* Licensed under the MIT/X11 license. - * Copyright (c) 2006-2008 the OpenTK Team. - * This notice may not be removed from any source distribution. - * See license.txt for licensing detailed licensing details. - * - * Contributions by Georg W�chter. - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenTK -{ - /// - /// Represents a quadric bezier curve with two anchor and one control point. - /// - [Serializable] - public struct BezierCurveQuadric - { - #region Fields - - /// - /// Start anchor point. - /// - public Vector2 StartAnchor; - - /// - /// End anchor point. - /// - public Vector2 EndAnchor; - - /// - /// Control point, controls the direction of both endings of the curve. - /// - public Vector2 ControlPoint; - - /// - /// The parallel value. - /// - /// This value defines whether the curve should be calculated as a - /// parallel curve to the original bezier curve. A value of 0.0f represents - /// the original curve, 5.0f i.e. stands for a curve that has always a distance - /// of 5.f to the orignal curve at any point. - public float Parallel; - - #endregion - - #region Constructors - - /// - /// Constructs a new . - /// - /// The start anchor. - /// The end anchor. - /// The control point. - public BezierCurveQuadric(Vector2 startAnchor, Vector2 endAnchor, Vector2 controlPoint) - { - this.StartAnchor = startAnchor; - this.EndAnchor = endAnchor; - this.ControlPoint = controlPoint; - this.Parallel = 0.0f; - } - - /// - /// Constructs a new . - /// - /// The parallel value. - /// The start anchor. - /// The end anchor. - /// The control point. - public BezierCurveQuadric(float parallel, Vector2 startAnchor, Vector2 endAnchor, Vector2 controlPoint) - { - this.Parallel = parallel; - this.StartAnchor = startAnchor; - this.EndAnchor = endAnchor; - this.ControlPoint = controlPoint; - } - - #endregion - - #region Functions - - /// - /// Calculates the point with the specified t. - /// - /// The t value, between 0.0f and 1.0f. - /// Resulting point. - public Vector2 CalculatePoint(float t) - { - Vector2 r = new Vector2(); - float c = 1.0f - t; - - r.X = (c * c * StartAnchor.X) + (2 * t * c * ControlPoint.X) + (t * t * EndAnchor.X); - r.Y = (c * c * StartAnchor.Y) + (2 * t * c * ControlPoint.Y) + (t * t * EndAnchor.Y); - - if (Parallel == 0.0f) - return r; - - Vector2 perpendicular = new Vector2(); - - if (t == 0.0f) - perpendicular = ControlPoint - StartAnchor; - else - perpendicular = r - CalculatePointOfDerivative(t); - - return r + Vector2.Normalize(perpendicular).PerpendicularRight * Parallel; - } - - /// - /// Calculates the point with the specified t of the derivative of this function. - /// - /// The t, value between 0.0f and 1.0f. - /// Resulting point. - private Vector2 CalculatePointOfDerivative(float t) - { - Vector2 r = new Vector2(); - - r.X = (1.0f - t) * StartAnchor.X + t * ControlPoint.X; - r.Y = (1.0f - t) * StartAnchor.Y + t * ControlPoint.Y; - - return r; - } - - /// - /// Calculates the length of this bezier curve. - /// - /// The precision. - /// Length of curve. - /// The precision gets better when the - /// value gets smaller. - public float CalculateLength(float precision) - { - float length = 0.0f; - Vector2 old = CalculatePoint(0.0f); - - for (float i = precision; i < (1.0f + precision); i += precision) - { - Vector2 n = CalculatePoint(i); - length += (n - old).Length; - old = n; - } - - return length; - } - - #endregion - } -} diff --git a/OpenTK/Math/Box2.cs b/OpenTK/Math/Box2.cs deleted file mode 100644 index 4c54b622..00000000 --- a/OpenTK/Math/Box2.cs +++ /dev/null @@ -1,99 +0,0 @@ -#region --- License --- -/* Copyright (c) 2006, 2007 Stefanos Apostolopoulos - * See license.txt for license info - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; -using System.Runtime.InteropServices; -namespace OpenTK -{ - /// - /// Defines a 2d box (rectangle). - /// - [StructLayout(LayoutKind.Sequential)] - public struct Box2 - { - /// - /// The left boundary of the structure. - /// - public float Left; - - /// - /// The right boundary of the structure. - /// - public float Right; - - /// - /// The top boundary of the structure. - /// - public float Top; - - /// - /// The bottom boundary of the structure. - /// - public float Bottom; - - /// - /// Constructs a new Box2 with the specified dimensions. - /// - /// AnOpenTK.Vector2 describing the top-left corner of the Box2. - /// An OpenTK.Vector2 describing the bottom-right corner of the Box2. - public Box2(Vector2 topLeft, Vector2 bottomRight) - { - Left = topLeft.X; - Top = topLeft.Y; - Right = bottomRight.X; - Bottom = bottomRight.Y; - } - - /// - /// Constructs a new Box2 with the specified dimensions. - /// - /// The position of the left boundary. - /// The position of the top boundary. - /// The position of the right boundary. - /// The position of the bottom boundary. - public Box2(float left, float top, float right, float bottom) - { - Left = left; - Top = top; - Right = right; - Bottom = bottom; - } - - /// - /// Creates a new Box2 with the specified dimensions. - /// - /// The position of the top boundary. - /// The position of the left boundary. - /// The position of the right boundary. - /// The position of the bottom boundary. - /// A new OpenTK.Box2 with the specfied dimensions. - public static Box2 FromTLRB(float top, float left, float right, float bottom) - { - return new Box2(left, top, right, bottom); - } - - /// - /// Gets a float describing the width of the Box2 structure. - /// - public float Width { get { return (float)System.Math.Abs(Right - Left); } } - - /// - /// Gets a float describing the height of the Box2 structure. - /// - public float Height { get { return (float)System.Math.Abs(Bottom - Top); } } - - /// - /// Returns a describing the current instance. - /// - /// - public override string ToString() - { - return String.Format("({0},{1})-({2},{3})", Left, Top, Right, Bottom); - } - } -} diff --git a/OpenTK/Math/Functions.cs b/OpenTK/Math/Functions.cs deleted file mode 100644 index 15fd0f60..00000000 --- a/OpenTK/Math/Functions.cs +++ /dev/null @@ -1,371 +0,0 @@ -#region --- License --- -/* Licensed under the MIT/X11 license. - * Copyright (c) 2006-2008 the OpenTK Team. - * This notice may not be removed from any source distribution. - * See license.txt for licensing detailed licensing details. - * - * Contributions by Andy Gill, James Talton and Georg Wächter. - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenTK -{ - /// - /// Contains mathematical functions for the OpenTK.Math toolkit. - /// - [Obsolete("Use OpenTK.MathHelper instead.")] - public static class Functions - { - #region NextPowerOfTwo - - /// - /// Returns the next power of two that is larger than the specified number. - /// - /// The specified number. - /// The next power of two. - public static long NextPowerOfTwo(long n) - { - if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); - return (long)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); - } - - /// - /// Returns the next power of two that is larger than the specified number. - /// - /// The specified number. - /// The next power of two. - public static int NextPowerOfTwo(int n) - { - if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); - return (int)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); - } - - /// - /// Returns the next power of two that is larger than the specified number. - /// - /// The specified number. - /// The next power of two. - public static float NextPowerOfTwo(float n) - { - if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); - return (float)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); - } - - /// - /// Returns the next power of two that is larger than the specified number. - /// - /// The specified number. - /// The next power of two. - public static double NextPowerOfTwo(double n) - { - if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); - return System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); - } - - #endregion - - #region Factorial - - /// Calculates the factorial of a given natural number. - /// - /// The number. - /// n! - public static long Factorial(int n) - { - long result = 1; - - for (; n > 1; n--) - result *= n; - - return result; - } - - #endregion - - #region BinomialCoefficient - - /// - /// Calculates the binomial coefficient above . - /// - /// The n. - /// The k. - /// n! / (k! * (n - k)!) - public static long BinomialCoefficient(int n, int k) - { - return Factorial(n) / (Factorial(k) * Factorial(n - k)); - } - - #endregion - - #region InverseSqrtFast - - /// - /// Returns an approximation of the inverse square root of left number. - /// - /// A number. - /// An approximation of the inverse square root of the specified number, with an upper error bound of 0.001 - /// - /// This is an improved implementation of the the method known as Carmack's inverse square root - /// which is found in the Quake III source code. This implementation comes from - /// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see - /// http://www.beyond3d.com/content/articles/8/ - /// - public static float InverseSqrtFast(float x) - { - unsafe - { - float xhalf = 0.5f * x; - int i = *(int*)&x; // Read bits as integer. - i = 0x5f375a86 - (i >> 1); // Make an initial guess for Newton-Raphson approximation - x = *(float*)&i; // Convert bits back to float - x = x * (1.5f - xhalf * x * x); // Perform left single Newton-Raphson step. - return x; - } - } - - /// - /// Returns an approximation of the inverse square root of left number. - /// - /// A number. - /// An approximation of the inverse square root of the specified number, with an upper error bound of 0.001 - /// - /// This is an improved implementation of the the method known as Carmack's inverse square root - /// which is found in the Quake III source code. This implementation comes from - /// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see - /// http://www.beyond3d.com/content/articles/8/ - /// - public static double InverseSqrtFast(double x) - { - return InverseSqrtFast((float)x); - // TODO: The following code is wrong. Fix it, to improve precision. -#if false - unsafe - { - double xhalf = 0.5f * x; - int i = *(int*)&x; // Read bits as integer. - i = 0x5f375a86 - (i >> 1); // Make an initial guess for Newton-Raphson approximation - x = *(float*)&i; // Convert bits back to float - x = x * (1.5f - xhalf * x * x); // Perform left single Newton-Raphson step. - return x; - } -#endif - } - - #endregion - - #region DegreesToRadians - - /// - /// Convert degrees to radians - /// - /// An angle in degrees - /// The angle expressed in radians - public static float DegreesToRadians(float degrees) - { - const float degToRad = (float)System.Math.PI / 180.0f; - return degrees * degToRad; - } - - /// - /// Convert radians to degrees - /// - /// An angle in radians - /// The angle expressed in degrees - public static float RadiansToDegrees(float radians) - { - const float radToDeg = 180.0f / (float)System.Math.PI; - return radians * radToDeg; - } - - #endregion - - #region Mathematical constants - - /// - /// Obsolete. Do not use. - /// - public static readonly float PIF = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930382f; - - /// - /// Obsolete. Do not use. - /// - public static readonly float RTODF = 180.0f / PIF; - - /// - /// Obsolete. Do not use. - /// - public static readonly float DTORF = PIF / 180.0f; - - /// - /// Obsolete. Do not use. - /// - public static readonly double PI = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930382d; - - /// - /// Obsolete. Do not use. - /// - public static readonly double RTOD = 180.0d / PIF; - - /// - /// Obsolete. Do not use. - /// - public static readonly double DTOR = PIF / 180.0d; - - #endregion - - #region Swap - - /// - /// Swaps two float values. - /// - /// The first value. - /// The second value. - public static void Swap(ref double a, ref double b) - { - double temp = a; - a = b; - b = temp; - } - - /// - /// Swaps two float values. - /// - /// The first value. - /// The second value. - public static void Swap(ref float a, ref float b) - { - float temp = a; - a = b; - b = temp; - } - - #endregion - } - -#if false - public static partial class Math - { - #region --- Vectors --- - - #region --- Addition --- - - /// - /// Adds the given Vector2 to the current Vector3. - /// - /// The right operand of the addition. - /// A new Vector3 containing the result of the addition. - public static Vector2 Add(Vector2 left, Vector2 right) - { - return new Vector2(left).Add(right); - } - - /// - /// Adds the given Vector3 to the current Vector3. - /// - /// The right operand of the addition. - /// A new Vector3 containing the result of the addition. - public static Vector3 Add(Vector2 left, Vector3 right) - { - return new Vector3(left).Add(right); - } - - /// - /// Adds the given Vector4 to the current Vector3. W-coordinate remains unaffected. - /// - /// The right operand of the addition. - /// A new Vector4 containing the result of the addition. - public static Vector4 Add(Vector2 left, Vector4 right) - { - return new Vector4(left).Add(right); - } - - /// - /// Adds the given Vector2 to the current Vector3. - /// - /// The right operand of the addition. - /// A new Vector3 containing the result of the addition. - public static Vector3 Add(Vector3 left, Vector2 right) - { - return new Vector3(left).Add(right); - } - - /// - /// Adds the given Vector3 to the current Vector3. - /// - /// The right operand of the addition. - /// A new Vector3 containing the result of the addition. - public static Vector3 Add(Vector3 left, Vector3 right) - { - return new Vector3(left).Add(right); - } - - /// - /// Adds the given Vector4 to the current Vector3. W-coordinate remains unaffected. - /// - /// The right operand of the addition. - /// A new Vector4 containing the result of the addition. - public static Vector4 Add(Vector3 left, Vector4 right) - { - return new Vector4(left).Add(right); - } - - /// - /// Adds the given Vector2 to the current Vector3. - /// - /// The right operand of the addition. - /// A new Vector3 containing the result of the addition. - public static Vector4 Add(Vector4 left, Vector2 right) - { - return new Vector4(left).Add(right); - } - - /// - /// Adds the given Vector3 to the current Vector3. - /// - /// The right operand of the addition. - /// A new Vector3 containing the result of the addition. - public static Vector4 Add(Vector4 left, Vector3 right) - { - return new Vector4(left).Add(right); - } - - /// - /// Adds the given Vector4 to the current Vector3. W-coordinate remains unaffected. - /// - /// The right operand of the addition. - /// A new Vector4 containing the result of the addition. - public static Vector4 Add(Vector4 left, Vector4 right) - { - return new Vector4(left).Add(right); - } - - #endregion - - #region --- Subtraction --- - - - - #endregion - - #region --- Cross --- - - /// - /// Computes the cross product between the current and the given Vector3. The current Vector3 is set to the result of the computation. - /// - /// The right operand of the cross product - /// The current - public static Vector3 Cross(Vector3 left, Vector3 right) - { - return new Vector3(left).Cross(right); - } - - #endregion - - #endregion - } -#endif -} diff --git a/OpenTK/Math/Half.cs b/OpenTK/Math/Half.cs deleted file mode 100644 index 06ff241c..00000000 --- a/OpenTK/Math/Half.cs +++ /dev/null @@ -1,588 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -/* -The conversion functions are derived from OpenEXR's implementation and are -governed by the following license: - -Copyright (c) 2002, Industrial Light & Magic, a division of Lucas -Digital Ltd. LLC - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are -met: -* Redistributions of source code must retain the above copyright -notice, this list of conditions and the following disclaimer. -* Redistributions in binary form must reproduce the above -copyright notice, this list of conditions and the following disclaimer -in the documentation and/or other materials provided with the -distribution. -* Neither the name of Industrial Light & Magic nor the names of -its contributors may be used to endorse or promote products derived -from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -#endregion --- License --- - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; - -namespace OpenTK -{ - - /// - /// The name Half is derived from half-precision floating-point number. - /// It occupies only 16 bits, which are split into 1 Sign bit, 5 Exponent bits and 10 Mantissa bits. - /// - /// - /// Quote from ARB_half_float_pixel specification: - /// Any representable 16-bit floating-point value is legal as input to a GL command that accepts 16-bit floating-point data. The - /// result of providing a value that is not a floating-point number (such as infinity or NaN) to such a command is unspecified, - /// but must not lead to GL interruption or termination. Providing a denormalized number or negative zero to GL must yield - /// predictable results. - /// - [Serializable, StructLayout(LayoutKind.Sequential)] - public struct Half : ISerializable, IComparable, IFormattable, IEquatable - { - #region Internal Field - - UInt16 bits; - - #endregion Internal Field - - #region Properties - - /// Returns true if the Half is zero. - public bool IsZero { get { return (bits == 0) || (bits == 0x8000); } } - - /// Returns true if the Half represents Not A Number (NaN) - public bool IsNaN { get { return (((bits & 0x7C00) == 0x7C00) && (bits & 0x03FF) != 0x0000); } } - - /// Returns true if the Half represents positive infinity. - public bool IsPositiveInfinity { get { return (bits == 31744); } } - - /// Returns true if the Half represents negative infinity. - public bool IsNegativeInfinity { get { return (bits == 64512); } } - - #endregion Properties - - #region Constructors - - /// - /// The new Half instance will convert the parameter into 16-bit half-precision floating-point. - /// - /// 32-bit single-precision floating-point number. - public Half(Single f) - : this() - { - unsafe - { - bits = SingleToHalf(*(int*)&f); - } - } - - /// - /// The new Half instance will convert the parameter into 16-bit half-precision floating-point. - /// - /// 32-bit single-precision floating-point number. - /// Enable checks that will throw if the conversion result is not meaningful. - public Half(Single f, bool throwOnError) - : this(f) - { - if (throwOnError) - { - // handle cases that cause overflow rather than silently ignoring it - if (f > Half.MaxValue) throw new ArithmeticException("Half: Positive maximum value exceeded."); - if (f < -Half.MaxValue) throw new ArithmeticException("Half: Negative minimum value exceeded."); - - // handle cases that make no sense - if (Single.IsNaN(f)) throw new ArithmeticException("Half: Input is not a number (NaN)."); - if (Single.IsPositiveInfinity(f)) throw new ArithmeticException("Half: Input is positive infinity."); - if (Single.IsNegativeInfinity(f)) throw new ArithmeticException("Half: Input is negative infinity."); - } - } - - /// - /// The new Half instance will convert the parameter into 16-bit half-precision floating-point. - /// - /// 64-bit double-precision floating-point number. - public Half(Double d) : this((Single)d) { } - - /// - /// The new Half instance will convert the parameter into 16-bit half-precision floating-point. - /// - /// 64-bit double-precision floating-point number. - /// Enable checks that will throw if the conversion result is not meaningful. - public Half(Double d, bool throwOnError) : this((Single)d, throwOnError) { } - - #endregion Constructors - - #region Single -> Half - - /// Ported from OpenEXR's IlmBase 1.0.1 - private UInt16 SingleToHalf(Int32 si32) - { - // Our floating point number, F, is represented by the bit pattern in integer i. - // Disassemble that bit pattern into the sign, S, the exponent, E, and the significand, M. - // Shift S into the position where it will go in in the resulting half number. - // Adjust E, accounting for the different exponent bias of float and half (127 versus 15). - - Int32 sign = (si32 >> 16) & 0x00008000; - Int32 exponent = ((si32 >> 23) & 0x000000ff) - (127 - 15); - Int32 mantissa = si32 & 0x007fffff; - - // Now reassemble S, E and M into a half: - - if (exponent <= 0) - { - if (exponent < -10) - { - // E is less than -10. The absolute value of F is less than Half.MinValue - // (F may be a small normalized float, a denormalized float or a zero). - // - // We convert F to a half zero with the same sign as F. - - return (UInt16)sign; - } - - // E is between -10 and 0. F is a normalized float whose magnitude is less than Half.MinNormalizedValue. - // - // We convert F to a denormalized half. - - // Add an explicit leading 1 to the significand. - - mantissa = mantissa | 0x00800000; - - // Round to M to the nearest (10+E)-bit value (with E between -10 and 0); in case of a tie, round to the nearest even value. - // - // Rounding may cause the significand to overflow and make our number normalized. Because of the way a half's bits - // are laid out, we don't have to treat this case separately; the code below will handle it correctly. - - Int32 t = 14 - exponent; - Int32 a = (1 << (t - 1)) - 1; - Int32 b = (mantissa >> t) & 1; - - mantissa = (mantissa + a + b) >> t; - - // Assemble the half from S, E (==zero) and M. - - return (UInt16)(sign | mantissa); - } - else if (exponent == 0xff - (127 - 15)) - { - if (mantissa == 0) - { - // F is an infinity; convert F to a half infinity with the same sign as F. - - return (UInt16)(sign | 0x7c00); - } - else - { - // F is a NAN; we produce a half NAN that preserves the sign bit and the 10 leftmost bits of the - // significand of F, with one exception: If the 10 leftmost bits are all zero, the NAN would turn - // into an infinity, so we have to set at least one bit in the significand. - - mantissa >>= 13; - return (UInt16)(sign | 0x7c00 | mantissa | ((mantissa == 0) ? 1 : 0)); - } - } - else - { - // E is greater than zero. F is a normalized float. We try to convert F to a normalized half. - - // Round to M to the nearest 10-bit value. In case of a tie, round to the nearest even value. - - mantissa = mantissa + 0x00000fff + ((mantissa >> 13) & 1); - - if ((mantissa & 0x00800000) != 0) - { - mantissa = 0; // overflow in significand, - exponent += 1; // adjust exponent - } - - // exponent overflow - if (exponent > 30) throw new ArithmeticException("Half: Hardware floating-point overflow."); - - // Assemble the half from S, E and M. - - return (UInt16)(sign | (exponent << 10) | (mantissa >> 13)); - } - } - - #endregion Single -> Half - - #region Half -> Single - - /// Converts the 16-bit half to 32-bit floating-point. - /// A single-precision floating-point number. - public Single ToSingle() - { - int i = HalfToFloat(bits); - - unsafe - { - return *(float*)&i; - } - } - - /// Ported from OpenEXR's IlmBase 1.0.1 - private Int32 HalfToFloat(UInt16 ui16) - { - - Int32 sign = (ui16 >> 15) & 0x00000001; - Int32 exponent = (ui16 >> 10) & 0x0000001f; - Int32 mantissa = ui16 & 0x000003ff; - - if (exponent == 0) - { - if (mantissa == 0) - { - // Plus or minus zero - - return sign << 31; - } - else - { - // Denormalized number -- renormalize it - - while ((mantissa & 0x00000400) == 0) - { - mantissa <<= 1; - exponent -= 1; - } - - exponent += 1; - mantissa &= ~0x00000400; - } - } - else if (exponent == 31) - { - if (mantissa == 0) - { - // Positive or negative infinity - - return (sign << 31) | 0x7f800000; - } - else - { - // Nan -- preserve sign and significand bits - - return (sign << 31) | 0x7f800000 | (mantissa << 13); - } - } - - // Normalized number - - exponent = exponent + (127 - 15); - mantissa = mantissa << 13; - - // Assemble S, E and M. - - return (sign << 31) | (exponent << 23) | mantissa; - } - - #endregion Half -> Single - - #region Conversions - - /// - /// Converts a System.Single to a OpenTK.Half. - /// - /// The value to convert. - /// A - /// - /// The result of the conversion. - /// A - /// - public static explicit operator Half(float f) - { - return new Half(f); - } - - /// - /// Converts a System.Double to a OpenTK.Half. - /// - /// The value to convert. - /// A - /// - /// The result of the conversion. - /// A - /// - public static explicit operator Half(double d) - { - return new Half(d); - } - - /// - /// Converts a OpenTK.Half to a System.Single. - /// - /// The value to convert. - /// A - /// - /// The result of the conversion. - /// A - /// - public static implicit operator float(Half h) - { - return h.ToSingle(); - } - - /// - /// Converts a OpenTK.Half to a System.Double. - /// - /// The value to convert. - /// A - /// - /// The result of the conversion. - /// A - /// - public static implicit operator double(Half h) - { - return (double)h.ToSingle(); - } - - #endregion Conversions - - #region Constants - - /// The size in bytes for an instance of the Half struct. - public static readonly Int32 SizeInBytes = 2; - - /// Smallest positive half - public static readonly Single MinValue = 5.96046448e-08f; - - /// Smallest positive normalized half - public static readonly Single MinNormalizedValue = 6.10351562e-05f; - - /// Largest positive half - public static readonly Single MaxValue = 65504.0f; - - /// Smallest positive e for which half (1.0 + e) != half (1.0) - public static readonly Single Epsilon = 0.00097656f; - - #endregion Constants - - #region ISerializable - - /// Constructor used by ISerializable to deserialize the object. - /// - /// - public Half(SerializationInfo info, StreamingContext context) - { - this.bits = (ushort)info.GetValue("bits", typeof(ushort)); - } - - /// Used by ISerialize to serialize the object. - /// - /// - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("bits", this.bits); - } - - #endregion ISerializable - - #region Binary dump - - /// Updates the Half by reading from a Stream. - /// A BinaryReader instance associated with an open Stream. - public void FromBinaryStream(BinaryReader bin) - { - this.bits = bin.ReadUInt16(); - - } - - /// Writes the Half into a Stream. - /// A BinaryWriter instance associated with an open Stream. - public void ToBinaryStream(BinaryWriter bin) - { - bin.Write(this.bits); - } - - #endregion Binary dump - - #region IEquatable Members - - const int maxUlps = 1; - - /// - /// Returns a value indicating whether this instance is equal to a specified OpenTK.Half value. - /// - /// OpenTK.Half object to compare to this instance.. - /// True, if other is equal to this instance; false otherwise. - public bool Equals(Half other) - { - short aInt, bInt; - unchecked { aInt = (short)other.bits; } - unchecked { bInt = (short)this.bits; } - - // Make aInt lexicographically ordered as a twos-complement int - if (aInt < 0) - aInt = (short)(0x8000 - aInt); - - // Make bInt lexicographically ordered as a twos-complement int - if (bInt < 0) - bInt = (short)(0x8000 - bInt); - - short intDiff = System.Math.Abs((short)(aInt - bInt)); - - if (intDiff <= maxUlps) - return true; - - return false; - } - - #endregion - - #region IComparable Members - - /// - /// Compares this instance to a specified half-precision floating-point number - /// and returns an integer that indicates whether the value of this instance - /// is less than, equal to, or greater than the value of the specified half-precision - /// floating-point number. - /// - /// A half-precision floating-point number to compare. - /// - /// A signed number indicating the relative values of this instance and value. If the number is: - /// Less than zero, then this instance is less than other, or this instance is not a number - /// (OpenTK.Half.NaN) and other is a number. - /// Zero: this instance is equal to value, or both this instance and other - /// are not a number (OpenTK.Half.NaN), OpenTK.Half.PositiveInfinity, or - /// OpenTK.Half.NegativeInfinity. - /// Greater than zero: this instance is greater than othrs, or this instance is a number - /// and other is not a number (OpenTK.Half.NaN). - /// - public int CompareTo(Half other) - { - return ((float)this).CompareTo((float)other); - } - - #endregion IComparable Members - - #region IFormattable Members - - /// Converts this Half into a human-legible string representation. - /// The string representation of this instance. - public override string ToString() - { - return this.ToSingle().ToString(); - } - - /// Converts this Half into a human-legible string representation. - /// Formatting for the output string. - /// Culture-specific formatting information. - /// The string representation of this instance. - public string ToString(string format, IFormatProvider formatProvider) - { - return this.ToSingle().ToString(format, formatProvider); - } - - #endregion IFormattable Members - - #region String -> Half - - /// Converts the string representation of a number to a half-precision floating-point equivalent. - /// String representation of the number to convert. - /// A new Half instance. - public static Half Parse(string s) - { - return (Half)Single.Parse(s); - } - - /// Converts the string representation of a number to a half-precision floating-point equivalent. - /// String representation of the number to convert. - /// Specifies the format of s. - /// Culture-specific formatting information. - /// A new Half instance. - public static Half Parse(string s, System.Globalization.NumberStyles style, IFormatProvider provider) - { - return (Half)Single.Parse(s, style, provider); - } - - /// Converts the string representation of a number to a half-precision floating-point equivalent. Returns success. - /// String representation of the number to convert. - /// The Half instance to write to. - /// Success. - public static bool TryParse(string s, out Half result) - { - float f; - bool b = Single.TryParse(s, out f); - result = (Half)f; - return b; - } - - /// Converts the string representation of a number to a half-precision floating-point equivalent. Returns success. - /// String representation of the number to convert. - /// Specifies the format of s. - /// Culture-specific formatting information. - /// The Half instance to write to. - /// Success. - public static bool TryParse(string s, System.Globalization.NumberStyles style, IFormatProvider provider, out Half result) - { - float f; - bool b = Single.TryParse(s, style, provider, out f); - result = (Half)f; - return b; - } - - #endregion String -> Half - - #region BitConverter - - /// Returns the Half as an array of bytes. - /// The Half to convert. - /// The input as byte array. - public static byte[] GetBytes(Half h) - { - return BitConverter.GetBytes(h.bits); - } - - /// Converts an array of bytes into Half. - /// A Half in it's byte[] representation. - /// The starting position within value. - /// A new Half instance. - public static Half FromBytes(byte[] value, int startIndex) - { - Half h; - h.bits = BitConverter.ToUInt16(value, startIndex); - return h; - } - - #endregion BitConverter - } -} \ No newline at end of file diff --git a/OpenTK/Math/MathHelper.cs b/OpenTK/Math/MathHelper.cs deleted file mode 100644 index 87fad768..00000000 --- a/OpenTK/Math/MathHelper.cs +++ /dev/null @@ -1,333 +0,0 @@ -#region --- License --- -/* Licensed under the MIT/X11 license. - * Copyright (c) 2006-2008 the OpenTK Team. - * This notice may not be removed from any source distribution. - * See license.txt for licensing detailed licensing details. - * - * Contributions by Andy Gill, James Talton and Georg Wächter. - */ -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenTK -{ - /// - /// Contains common mathematical functions and constants. - /// - public static class MathHelper - { - #region Fields - - /// - /// Defines the value of Pi as a . - /// - public const float Pi = 3.141592653589793238462643383279502884197169399375105820974944592307816406286208998628034825342117067982148086513282306647093844609550582231725359408128481117450284102701938521105559644622948954930382f; - - /// - /// Defines the value of Pi divided by two as a . - /// - public const float PiOver2 = Pi / 2; - - /// - /// Defines the value of Pi divided by three as a . - /// - public const float PiOver3 = Pi / 3; - - /// - /// Definesthe value of Pi divided by four as a . - /// - public const float PiOver4 = Pi / 4; - - /// - /// Defines the value of Pi divided by six as a . - /// - public const float PiOver6 = Pi / 6; - - /// - /// Defines the value of Pi multiplied by two as a . - /// - public const float TwoPi = 2 * Pi; - - /// - /// Defines the value of Pi multiplied by 3 and divided by two as a . - /// - public const float ThreePiOver2 = 3 * Pi / 2; - - /// - /// Defines the value of E as a . - /// - public const float E = 2.71828182845904523536f; - - /// - /// Defines the base-10 logarithm of E. - /// - public const float Log10E = 0.434294482f; - - /// - /// Defines the base-2 logarithm of E. - /// - public const float Log2E = 1.442695041f; - - #endregion - - #region Public Members - - #region NextPowerOfTwo - - /// - /// Returns the next power of two that is larger than the specified number. - /// - /// The specified number. - /// The next power of two. - public static long NextPowerOfTwo(long n) - { - if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); - return (long)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); - } - - /// - /// Returns the next power of two that is larger than the specified number. - /// - /// The specified number. - /// The next power of two. - public static int NextPowerOfTwo(int n) - { - if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); - return (int)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); - } - - /// - /// Returns the next power of two that is larger than the specified number. - /// - /// The specified number. - /// The next power of two. - public static float NextPowerOfTwo(float n) - { - if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); - return (float)System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); - } - - /// - /// Returns the next power of two that is larger than the specified number. - /// - /// The specified number. - /// The next power of two. - public static double NextPowerOfTwo(double n) - { - if (n < 0) throw new ArgumentOutOfRangeException("n", "Must be positive."); - return System.Math.Pow(2, System.Math.Ceiling(System.Math.Log((double)n, 2))); - } - - #endregion - - #region Factorial - - /// Calculates the factorial of a given natural number. - /// - /// The number. - /// n! - public static long Factorial(int n) - { - long result = 1; - - for (; n > 1; n--) - result *= n; - - return result; - } - - #endregion - - #region BinomialCoefficient - - /// - /// Calculates the binomial coefficient above . - /// - /// The n. - /// The k. - /// n! / (k! * (n - k)!) - public static long BinomialCoefficient(int n, int k) - { - return Factorial(n) / (Factorial(k) * Factorial(n - k)); - } - - #endregion - - #region InverseSqrtFast - - /// - /// Returns an approximation of the inverse square root of left number. - /// - /// A number. - /// An approximation of the inverse square root of the specified number, with an upper error bound of 0.001 - /// - /// This is an improved implementation of the the method known as Carmack's inverse square root - /// which is found in the Quake III source code. This implementation comes from - /// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see - /// http://www.beyond3d.com/content/articles/8/ - /// - public static float InverseSqrtFast(float x) - { - unsafe - { - float xhalf = 0.5f * x; - int i = *(int*)&x; // Read bits as integer. - i = 0x5f375a86 - (i >> 1); // Make an initial guess for Newton-Raphson approximation - x = *(float*)&i; // Convert bits back to float - x = x * (1.5f - xhalf * x * x); // Perform left single Newton-Raphson step. - return x; - } - } - - /// - /// Returns an approximation of the inverse square root of left number. - /// - /// A number. - /// An approximation of the inverse square root of the specified number, with an upper error bound of 0.001 - /// - /// This is an improved implementation of the the method known as Carmack's inverse square root - /// which is found in the Quake III source code. This implementation comes from - /// http://www.codemaestro.com/reviews/review00000105.html. For the history of this method, see - /// http://www.beyond3d.com/content/articles/8/ - /// - public static double InverseSqrtFast(double x) - { - return InverseSqrtFast((float)x); - // TODO: The following code is wrong. Fix it, to improve precision. -#if false - unsafe - { - double xhalf = 0.5f * x; - int i = *(int*)&x; // Read bits as integer. - i = 0x5f375a86 - (i >> 1); // Make an initial guess for Newton-Raphson approximation - x = *(float*)&i; // Convert bits back to float - x = x * (1.5f - xhalf * x * x); // Perform left single Newton-Raphson step. - return x; - } -#endif - } - - #endregion - - #region DegreesToRadians - - /// - /// Convert degrees to radians - /// - /// An angle in degrees - /// The angle expressed in radians - public static float DegreesToRadians(float degrees) - { - const float degToRad = (float)System.Math.PI / 180.0f; - return degrees * degToRad; - } - - /// - /// Convert radians to degrees - /// - /// An angle in radians - /// The angle expressed in degrees - public static float RadiansToDegrees(float radians) - { - const float radToDeg = 180.0f / (float)System.Math.PI; - return radians * radToDeg; - } - - /// - /// Convert degrees to radians - /// - /// An angle in degrees - /// The angle expressed in radians - public static double DegreesToRadians(double degrees) - { - const double degToRad = System.Math.PI / 180.0; - return degrees * degToRad; - } - - /// - /// Convert radians to degrees - /// - /// An angle in radians - /// The angle expressed in degrees - public static double RadiansToDegrees(double radians) - { - const double radToDeg = 180.0 / System.Math.PI; - return radians * radToDeg; - } - - #endregion - - #region Swap - - /// - /// Swaps two double values. - /// - /// The first value. - /// The second value. - public static void Swap(ref double a, ref double b) - { - double temp = a; - a = b; - b = temp; - } - - /// - /// Swaps two float values. - /// - /// The first value. - /// The second value. - public static void Swap(ref float a, ref float b) - { - float temp = a; - a = b; - b = temp; - } - - #endregion - - #region Clamp - - /// - /// Clamps a number between a minimum and a maximum. - /// - /// The number to clamp. - /// The minimum allowed value. - /// The maximum allowed value. - /// min, if n is lower than min; max, if n is higher than max; n otherwise. - public static int Clamp(int n, int min, int max) - { - return Math.Max(Math.Min(n, max), min); - } - - /// - /// Clamps a number between a minimum and a maximum. - /// - /// The number to clamp. - /// The minimum allowed value. - /// The maximum allowed value. - /// min, if n is lower than min; max, if n is higher than max; n otherwise. - public static float Clamp(float n, float min, float max) - { - return Math.Max(Math.Min(n, max), min); - } - - /// - /// Clamps a number between a minimum and a maximum. - /// - /// The number to clamp. - /// The minimum allowed value. - /// The maximum allowed value. - /// min, if n is lower than min; max, if n is higher than max; n otherwise. - public static double Clamp(double n, double min, double max) - { - return Math.Max(Math.Min(n, max), min); - } - - #endregion - - #endregion - } -} diff --git a/OpenTK/Math/Matrix2.cs b/OpenTK/Math/Matrix2.cs deleted file mode 100644 index 0a0cb382..00000000 --- a/OpenTK/Math/Matrix2.cs +++ /dev/null @@ -1,764 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 2x2 matrix - /// - public struct Matrix2 : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector2 Row0; - - /// - /// Bottom row of the matrix. - /// - public Vector2 Row1; - - /// - /// The identity matrix. - /// - public static readonly Matrix2 Identity = new Matrix2(Vector2.UnitX, Vector2.UnitY); - - /// - /// The zero matrix. - /// - public static readonly Matrix2 Zero = new Matrix2(Vector2.Zero, Vector2.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Bottom row of the matrix. - public Matrix2(Vector2 row0, Vector2 row1) - { - Row0 = row0; - Row1 = row1; - } - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - public Matrix2( - float m00, float m01, - float m10, float m11) - { - Row0 = new Vector2(m00, m01); - Row1 = new Vector2(m10, m11); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets the determinant of this matrix. - /// - public float Determinant - { - get - { - float m11 = Row0.X, m12 = Row0.Y, - m21 = Row1.X, m22 = Row1.Y; - - return m11 * m22 - m12 * m21; - } - } - - /// - /// Gets or sets the first column of this matrix. - /// - public Vector2 Column0 - { - get { return new Vector2(Row0.X, Row1.X); } - set { Row0.X = value.X; Row1.X = value.Y; } - } - - /// - /// Gets or sets the second column of this matrix. - /// - public Vector2 Column1 - { - get { return new Vector2(Row0.Y, Row1.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2 Diagonal - { - get - { - return new Vector2(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public float Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public float this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Transpose() - - /// - /// Converts this instance to it's transpose. - /// - public void Transpose() - { - this = Matrix2.Transpose(this); - } - - #endregion - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - /// - public void Invert() - { - this = Matrix2.Invert(this); - } - - #endregion - - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2 instance. - public static void CreateRotation(float angle, out Matrix2 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row1.X = -sin; - result.Row1.Y = cos; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2 instance. - public static Matrix2 CreateRotation(float angle) - { - Matrix2 result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(float scale, out Matrix2 result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix2 CreateScale(float scale) - { - Matrix2 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2 scale, out Matrix2 result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix2 CreateScale(Vector2 scale) - { - Matrix2 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(float x, float y, out Matrix2 result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = y; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix2 CreateScale(float x, float y) - { - Matrix2 result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2 left, float right, out Matrix2 result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2 Mult(Matrix2 left, float right) - { - Matrix2 result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2 left, ref Matrix2 right, out Matrix2 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2 Mult(Matrix2 left, Matrix2 right) - { - Matrix2 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2 left, ref Matrix2x3 right, out Matrix2x3 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x3 Mult(Matrix2 left, Matrix2x3 right) - { - Matrix2x3 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2 left, ref Matrix2x4 right, out Matrix2x4 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x4 Mult(Matrix2 left, Matrix2x4 right) - { - Matrix2x4 result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix2 left, ref Matrix2 right, out Matrix2 result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix2 Add(Matrix2 left, Matrix2 right) - { - Matrix2 result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix2 left, ref Matrix2 right, out Matrix2 result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix2 Subtract(Matrix2 left, Matrix2 right) - { - Matrix2 result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix2 is singular. - public static void Invert(ref Matrix2 mat, out Matrix2 result) - { - float det = mat.Determinant; - - if (det == 0) - throw new InvalidOperationException("Matrix is singular and cannot be inverted."); - - float invDet = 1f / det; - - result.Row0.X = mat.Row1.Y * invDet; - result.Row0.Y = -mat.Row0.Y * invDet; - result.Row1.X = -mat.Row1.X * invDet; - result.Row1.Y = mat.Row0.X * invDet; - } - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix2 is singular. - public static Matrix2 Invert(Matrix2 mat) - { - Matrix2 result; - Invert(ref mat, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix2 mat, out Matrix2 result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix2 Transpose(Matrix2 mat) - { - Matrix2 result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2 which holds the result of the multiplication - public static Matrix2 operator *(float left, Matrix2 right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2 which holds the result of the multiplication - public static Matrix2 operator *(Matrix2 left, float right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2 which holds the result of the multiplication - public static Matrix2 operator *(Matrix2 left, Matrix2 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3 which holds the result of the multiplication - public static Matrix2x3 operator *(Matrix2 left, Matrix2x3 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4 which holds the result of the multiplication - public static Matrix2x4 operator *(Matrix2 left, Matrix2x4 right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2 which holds the result of the addition - public static Matrix2 operator +(Matrix2 left, Matrix2 right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2 which holds the result of the subtraction - public static Matrix2 operator -(Matrix2 left, Matrix2 right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix2 left, Matrix2 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix2 left, Matrix2 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix4. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}", Row0, Row1); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix2)) - return false; - - return this.Equals((Matrix2)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current matrix is equal to another matrix. - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix2 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix2d.cs b/OpenTK/Math/Matrix2d.cs deleted file mode 100644 index 999f105e..00000000 --- a/OpenTK/Math/Matrix2d.cs +++ /dev/null @@ -1,764 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 2x2 matrix - /// - public struct Matrix2d : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector2d Row0; - - /// - /// Bottom row of the matrix. - /// - public Vector2d Row1; - - /// - /// The identity matrix. - /// - public static readonly Matrix2d Identity = new Matrix2d(Vector2d.UnitX, Vector2d.UnitY); - - /// - /// The zero matrix. - /// - public static readonly Matrix2d Zero = new Matrix2d(Vector2d.Zero, Vector2d.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Bottom row of the matrix. - public Matrix2d(Vector2d row0, Vector2d row1) - { - Row0 = row0; - Row1 = row1; - } - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - public Matrix2d( - double m00, double m01, - double m10, double m11) - { - Row0 = new Vector2d(m00, m01); - Row1 = new Vector2d(m10, m11); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets the determinant of this matrix. - /// - public double Determinant - { - get - { - double m11 = Row0.X, m12 = Row0.Y, - m21 = Row1.X, m22 = Row1.Y; - - return m11 * m22 - m12 * m21; - } - } - - /// - /// Gets or sets the first column of this matrix. - /// - public Vector2d Column0 - { - get { return new Vector2d(Row0.X, Row1.X); } - set { Row0.X = value.X; Row1.X = value.Y; } - } - - /// - /// Gets or sets the second column of this matrix. - /// - public Vector2d Column1 - { - get { return new Vector2d(Row0.Y, Row1.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public double M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public double M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2d Diagonal - { - get - { - return new Vector2d(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public double Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public double this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Transpose() - - /// - /// Converts this instance to it's transpose. - /// - public void Transpose() - { - this = Matrix2d.Transpose(this); - } - - #endregion - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - /// - public void Invert() - { - this = Matrix2d.Invert(this); - } - - #endregion - - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2d instance. - public static void CreateRotation(double angle, out Matrix2d result) - { - double cos = (double)System.Math.Cos(angle); - double sin = (double)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row1.X = -sin; - result.Row1.Y = cos; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2d instance. - public static Matrix2d CreateRotation(double angle) - { - Matrix2d result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(double scale, out Matrix2d result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix2d CreateScale(double scale) - { - Matrix2d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2d scale, out Matrix2d result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix2d CreateScale(Vector2d scale) - { - Matrix2d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(double x, double y, out Matrix2d result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = y; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix2d CreateScale(double x, double y) - { - Matrix2d result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2d left, double right, out Matrix2d result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2d Mult(Matrix2d left, double right) - { - Matrix2d result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2d left, ref Matrix2d right, out Matrix2d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2d Mult(Matrix2d left, Matrix2d right) - { - Matrix2d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2d left, ref Matrix2x3d right, out Matrix2x3d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x3d Mult(Matrix2d left, Matrix2x3d right) - { - Matrix2x3d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2d left, ref Matrix2x4d right, out Matrix2x4d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x4d Mult(Matrix2d left, Matrix2x4d right) - { - Matrix2x4d result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix2d left, ref Matrix2d right, out Matrix2d result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix2d Add(Matrix2d left, Matrix2d right) - { - Matrix2d result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix2d left, ref Matrix2d right, out Matrix2d result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix2d Subtract(Matrix2d left, Matrix2d right) - { - Matrix2d result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix2d is singular. - public static void Invert(ref Matrix2d mat, out Matrix2d result) - { - double det = mat.Determinant; - - if (det == 0) - throw new InvalidOperationException("Matrix is singular and cannot be inverted."); - - double invDet = 1f / det; - - result.Row0.X = mat.Row1.Y * invDet; - result.Row0.Y = -mat.Row0.Y * invDet; - result.Row1.X = -mat.Row1.X * invDet; - result.Row1.Y = mat.Row0.X * invDet; - } - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix2d is singular. - public static Matrix2d Invert(Matrix2d mat) - { - Matrix2d result; - Invert(ref mat, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix2d mat, out Matrix2d result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix2d Transpose(Matrix2d mat) - { - Matrix2d result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2d which holds the result of the multiplication - public static Matrix2d operator *(double left, Matrix2d right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2d which holds the result of the multiplication - public static Matrix2d operator *(Matrix2d left, double right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2d which holds the result of the multiplication - public static Matrix2d operator *(Matrix2d left, Matrix2d right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3d which holds the result of the multiplication - public static Matrix2x3d operator *(Matrix2d left, Matrix2x3d right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4d which holds the result of the multiplication - public static Matrix2x4d operator *(Matrix2d left, Matrix2x4d right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2d which holds the result of the addition - public static Matrix2d operator +(Matrix2d left, Matrix2d right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2d which holds the result of the subtraction - public static Matrix2d operator -(Matrix2d left, Matrix2d right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix2d left, Matrix2d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix2d left, Matrix2d right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix4. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}", Row0, Row1); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix2d)) - return false; - - return this.Equals((Matrix2d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current matrix is equal to another matrix. - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix2d other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix2x3.cs b/OpenTK/Math/Matrix2x3.cs deleted file mode 100644 index bd2236ca..00000000 --- a/OpenTK/Math/Matrix2x3.cs +++ /dev/null @@ -1,724 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Collections.Generic; - -namespace OpenTK -{ - /// - /// Represents a 2x3 matrix. - /// - public struct Matrix2x3 : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector3 Row0; - - /// - /// Bottom row of the matrix. - /// - public Vector3 Row1; - - /// - /// The zero matrix. - /// - public static readonly Matrix2x3 Zero = new Matrix2x3(Vector3.Zero, Vector3.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Bottom row of the matrix. - public Matrix2x3(Vector3 row0, Vector3 row1) - { - Row0 = row0; - Row1 = row1; - } - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - public Matrix2x3( - float m00, float m01, float m02, - float m10, float m11, float m12) - { - Row0 = new Vector3(m00, m01, m02); - Row1 = new Vector3(m10, m11, m12); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets or sets the first column of this matrix. - /// - public Vector2 Column0 - { - get { return new Vector2(Row0.X, Row1.X); } - set { Row0.X = value.X; Row1.X = value.Y; } - } - - /// - /// Gets or sets the second column of this matrix. - /// - public Vector2 Column1 - { - get { return new Vector2(Row0.Y, Row1.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; } - } - - /// - /// Gets or sets the third column of this matrix. - /// - public Vector2 Column2 - { - get { return new Vector2(Row0.Z, Row1.Z); } - set { Row0.Z = value.X; Row1.Z = value.Y; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public float M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public float M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2 Diagonal - { - get - { - return new Vector2(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public float Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public float this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2x3 instance. - public static void CreateRotation(float angle, out Matrix2x3 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row0.Z = 0; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row1.Z = 0; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2x3 instance. - public static Matrix2x3 CreateRotation(float angle) - { - Matrix2x3 result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(float scale, out Matrix2x3 result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - result.Row1.Z = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix2x3 CreateScale(float scale) - { - Matrix2x3 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2 scale, out Matrix2x3 result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - result.Row1.Z = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix2x3 CreateScale(Vector2 scale) - { - Matrix2x3 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(float x, float y, out Matrix2x3 result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row1.Z = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix2x3 CreateScale(float x, float y) - { - Matrix2x3 result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x3 left, float right, out Matrix2x3 result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row0.Z = left.Row0.Z * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - result.Row1.Z = left.Row1.Z * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x3 Mult(Matrix2x3 left, float right) - { - Matrix2x3 result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x3 left, ref Matrix3x2 right, out Matrix2 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y, - rM31 = right.Row2.X, rM32 = right.Row2.Y; - - result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); - result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32); - result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); - result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2 Mult(Matrix2x3 left, Matrix3x2 right) - { - Matrix2 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x3 left, ref Matrix3 right, out Matrix2x3 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rm32 = right.Row2.Y, rM33 = right.Row2.Z; - - result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); - result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rm32); - result.Row0.Z = ((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33); - result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); - result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rm32); - result.Row1.Z = ((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x3 Mult(Matrix2x3 left, Matrix3 right) - { - Matrix2x3 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x3 left, ref Matrix3x4 right, out Matrix2x4 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rm32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W; - - result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); - result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rm32); - result.Row0.Z = ((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33); - result.Row0.W = ((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34); - result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); - result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rm32); - result.Row1.Z = ((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33); - result.Row1.W = ((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x4 Mult(Matrix2x3 left, Matrix3x4 right) - { - Matrix2x4 result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix2x3 left, ref Matrix2x3 right, out Matrix2x3 result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row0.Z = left.Row0.Z + right.Row0.Z; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - result.Row1.Z = left.Row1.Z + right.Row1.Z; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix2x3 Add(Matrix2x3 left, Matrix2x3 right) - { - Matrix2x3 result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix2x3 left, ref Matrix2x3 right, out Matrix2x3 result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row0.Z = left.Row0.Z - right.Row0.Z; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - result.Row1.Z = left.Row1.Z - right.Row1.Z; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix2x3 Subtract(Matrix2x3 left, Matrix2x3 right) - { - Matrix2x3 result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix2x3 mat, out Matrix3x2 result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - result.Row2.X = mat.Row0.Z; - result.Row2.Y = mat.Row1.Z; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix3x2 Transpose(Matrix2x3 mat) - { - Matrix3x2 result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3 which holds the result of the multiplication - public static Matrix2x3 operator *(float left, Matrix2x3 right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3 which holds the result of the multiplication - public static Matrix2x3 operator *(Matrix2x3 left, float right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2 which holds the result of the multiplication - public static Matrix2 operator *(Matrix2x3 left, Matrix3x2 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3 which holds the result of the multiplication - public static Matrix2x3 operator *(Matrix2x3 left, Matrix3 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4 which holds the result of the multiplication - public static Matrix2x4 operator *(Matrix2x3 left, Matrix3x4 right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3 which holds the result of the addition - public static Matrix2x3 operator +(Matrix2x3 left, Matrix2x3 right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3 which holds the result of the subtraction - public static Matrix2x3 operator -(Matrix2x3 left, Matrix2x3 right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix2x3 left, Matrix2x3 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix2x3 left, Matrix2x3 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix2x3. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}", Row0, Row1); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare tresult. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix2x3)) - return false; - - return this.Equals((Matrix2x3)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix2x3 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix2x3d.cs b/OpenTK/Math/Matrix2x3d.cs deleted file mode 100644 index 30a59eb5..00000000 --- a/OpenTK/Math/Matrix2x3d.cs +++ /dev/null @@ -1,724 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Collections.Generic; - -namespace OpenTK -{ - /// - /// Represents a 2x3 matrix. - /// - public struct Matrix2x3d : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector3d Row0; - - /// - /// Bottom row of the matrix. - /// - public Vector3d Row1; - - /// - /// The zero matrix. - /// - public static readonly Matrix2x3d Zero = new Matrix2x3d(Vector3d.Zero, Vector3d.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Bottom row of the matrix. - public Matrix2x3d(Vector3d row0, Vector3d row1) - { - Row0 = row0; - Row1 = row1; - } - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - public Matrix2x3d( - double m00, double m01, double m02, - double m10, double m11, double m12) - { - Row0 = new Vector3d(m00, m01, m02); - Row1 = new Vector3d(m10, m11, m12); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets or sets the first column of this matrix. - /// - public Vector2d Column0 - { - get { return new Vector2d(Row0.X, Row1.X); } - set { Row0.X = value.X; Row1.X = value.Y; } - } - - /// - /// Gets or sets the second column of this matrix. - /// - public Vector2d Column1 - { - get { return new Vector2d(Row0.Y, Row1.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; } - } - - /// - /// Gets or sets the third column of this matrix. - /// - public Vector2d Column2 - { - get { return new Vector2d(Row0.Z, Row1.Z); } - set { Row0.Z = value.X; Row1.Z = value.Y; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public double M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public double M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public double M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public double M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2d Diagonal - { - get - { - return new Vector2d(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public double Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public double this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2x3d instance. - public static void CreateRotation(double angle, out Matrix2x3d result) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row0.Z = 0; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row1.Z = 0; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2x3d instance. - public static Matrix2x3d CreateRotation(double angle) - { - Matrix2x3d result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(double scale, out Matrix2x3d result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - result.Row1.Z = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix2x3d CreateScale(double scale) - { - Matrix2x3d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2d scale, out Matrix2x3d result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - result.Row1.Z = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix2x3d CreateScale(Vector2d scale) - { - Matrix2x3d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(double x, double y, out Matrix2x3d result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row1.Z = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix2x3d CreateScale(double x, double y) - { - Matrix2x3d result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x3d left, double right, out Matrix2x3d result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row0.Z = left.Row0.Z * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - result.Row1.Z = left.Row1.Z * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x3d Mult(Matrix2x3d left, double right) - { - Matrix2x3d result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x3d left, ref Matrix3x2 right, out Matrix2d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y, - rM31 = right.Row2.X, rM32 = right.Row2.Y; - - result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); - result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32); - result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); - result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2d Mult(Matrix2x3d left, Matrix3x2 right) - { - Matrix2d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x3d left, ref Matrix3 right, out Matrix2x3d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rm32 = right.Row2.Y, rM33 = right.Row2.Z; - - result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); - result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rm32); - result.Row0.Z = ((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33); - result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); - result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rm32); - result.Row1.Z = ((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x3d Mult(Matrix2x3d left, Matrix3 right) - { - Matrix2x3d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x3d left, ref Matrix3x4 right, out Matrix2x4d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rm32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W; - - result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); - result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rm32); - result.Row0.Z = ((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33); - result.Row0.W = ((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34); - result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); - result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rm32); - result.Row1.Z = ((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33); - result.Row1.W = ((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x4d Mult(Matrix2x3d left, Matrix3x4 right) - { - Matrix2x4d result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix2x3d left, ref Matrix2x3d right, out Matrix2x3d result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row0.Z = left.Row0.Z + right.Row0.Z; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - result.Row1.Z = left.Row1.Z + right.Row1.Z; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix2x3d Add(Matrix2x3d left, Matrix2x3d right) - { - Matrix2x3d result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix2x3d left, ref Matrix2x3d right, out Matrix2x3d result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row0.Z = left.Row0.Z - right.Row0.Z; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - result.Row1.Z = left.Row1.Z - right.Row1.Z; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix2x3d Subtract(Matrix2x3d left, Matrix2x3d right) - { - Matrix2x3d result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix2x3d mat, out Matrix3x2d result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - result.Row2.X = mat.Row0.Z; - result.Row2.Y = mat.Row1.Z; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix3x2d Transpose(Matrix2x3d mat) - { - Matrix3x2d result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3d which holds the result of the multiplication - public static Matrix2x3d operator *(double left, Matrix2x3d right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3d which holds the result of the multiplication - public static Matrix2x3d operator *(Matrix2x3d left, double right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2d which holds the result of the multiplication - public static Matrix2d operator *(Matrix2x3d left, Matrix3x2 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3d which holds the result of the multiplication - public static Matrix2x3d operator *(Matrix2x3d left, Matrix3 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4d which holds the result of the multiplication - public static Matrix2x4d operator *(Matrix2x3d left, Matrix3x4 right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3d which holds the result of the addition - public static Matrix2x3d operator +(Matrix2x3d left, Matrix2x3d right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3d which holds the result of the subtraction - public static Matrix2x3d operator -(Matrix2x3d left, Matrix2x3d right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix2x3d left, Matrix2x3d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix2x3d left, Matrix2x3d right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix2x3d. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}", Row0, Row1); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare tresult. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix2x3d)) - return false; - - return this.Equals((Matrix2x3d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix2x3d other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix2x4.cs b/OpenTK/Math/Matrix2x4.cs deleted file mode 100644 index c3afecdb..00000000 --- a/OpenTK/Math/Matrix2x4.cs +++ /dev/null @@ -1,761 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 2x4 matrix. - /// - public struct Matrix2x4 : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector4 Row0; - - /// - /// Bottom row of the matrix. - /// - public Vector4 Row1; - - /// - /// The zero matrix. - /// - public static readonly Matrix2x4 Zero = new Matrix2x4(Vector4.Zero, Vector4.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Bottom row of the matrix. - public Matrix2x4(Vector4 row0, Vector4 row1) - { - Row0 = row0; - Row1 = row1; - } - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// Fourth item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// Fourth item of the second row of the matrix. - public Matrix2x4( - float m00, float m01, float m02, float m03, - float m10, float m11, float m12, float m13) - { - Row0 = new Vector4(m00, m01, m02, m03); - Row1 = new Vector4(m10, m11, m12, m13); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets or sets the first column of the matrix. - /// - public Vector2 Column0 - { - get { return new Vector2(Row0.X, Row1.X); } - set { Row0.X = value.X; Row1.X = value.Y; } - } - - /// - /// Gets or sets the second column of the matrix. - /// - public Vector2 Column1 - { - get { return new Vector2(Row0.Y, Row1.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; } - } - - /// - /// Gets or sets the third column of the matrix. - /// - public Vector2 Column2 - { - get { return new Vector2(Row0.Z, Row1.Z); } - set { Row0.Z = value.X; Row1.Z = value.Y; } - } - - /// - /// Gets or sets the fourth column of the matrix. - /// - public Vector2 Column3 - { - get { return new Vector2(Row0.W, Row1.W); } - set { Row0.W = value.X; Row1.W = value.Y; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public float M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 1, column 4 of this instance. - /// - public float M14 { get { return Row0.W; } set { Row0.W = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public float M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 4 of this instance. - /// - public float M24 { get { return Row1.W; } set { Row1.W = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2 Diagonal - { - get - { - return new Vector2(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public float Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public float this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2x4 instance. - public static void CreateRotation(float angle, out Matrix2x4 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row1.Z = 0; - result.Row1.W = 0; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2x3 instance. - public static Matrix2x4 CreateRotation(float angle) - { - Matrix2x4 result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(float scale, out Matrix2x4 result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - result.Row1.Z = 0; - result.Row1.W = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix2x4 CreateScale(float scale) - { - Matrix2x4 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2 scale, out Matrix2x4 result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - result.Row1.Z = 0; - result.Row1.W = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix2x4 CreateScale(Vector2 scale) - { - Matrix2x4 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(float x, float y, out Matrix2x4 result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row1.Z = 0; - result.Row1.W = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix2x4 CreateScale(float x, float y) - { - Matrix2x4 result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x4 left, float right, out Matrix2x4 result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row0.Z = left.Row0.Z * right; - result.Row0.W = left.Row0.W * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - result.Row1.Z = left.Row1.Z * right; - result.Row1.W = left.Row1.W * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x4 Mult(Matrix2x4 left, float right) - { - Matrix2x4 result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x4 left, ref Matrix4x2 right, out Matrix2 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y, - rM31 = right.Row2.X, rM32 = right.Row2.Y, - rM41 = right.Row3.X, rM42 = right.Row3.Y; - - result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41); - result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42); - result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41); - result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2 Mult(Matrix2x4 left, Matrix4x2 right) - { - Matrix2 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x4 left, ref Matrix4x3 right, out Matrix2x3 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z; - - result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41); - result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42); - result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43); - result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41); - result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42); - result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x3 Mult(Matrix2x4 left, Matrix4x3 right) - { - Matrix2x3 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x4 left, ref Matrix4 right, out Matrix2x4 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z, rM44 = right.Row3.W; - - result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41); - result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42); - result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43); - result.Row0.W = (((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34)) + (lM14 * rM44); - result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41); - result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42); - result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43); - result.Row1.W = (((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34)) + (lM24 * rM44); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x4 Mult(Matrix2x4 left, Matrix4 right) - { - Matrix2x4 result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix2x4 left, ref Matrix2x4 right, out Matrix2x4 result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row0.Z = left.Row0.Z + right.Row0.Z; - result.Row0.W = left.Row0.W + right.Row0.W; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - result.Row1.Z = left.Row1.Z + right.Row1.Z; - result.Row1.W = left.Row1.W + right.Row1.W; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix2x4 Add(Matrix2x4 left, Matrix2x4 right) - { - Matrix2x4 result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix2x4 left, ref Matrix2x4 right, out Matrix2x4 result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row0.Z = left.Row0.Z - right.Row0.Z; - result.Row0.W = left.Row0.W - right.Row0.W; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - result.Row1.Z = left.Row1.Z - right.Row1.Z; - result.Row1.W = left.Row1.W - right.Row1.W; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix2x4 Subtract(Matrix2x4 left, Matrix2x4 right) - { - Matrix2x4 result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix2x4 mat, out Matrix4x2 result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - result.Row2.X = mat.Row0.Z; - result.Row2.Y = mat.Row1.Z; - result.Row3.X = mat.Row0.W; - result.Row3.Y = mat.Row1.W; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix4x2 Transpose(Matrix2x4 mat) - { - Matrix4x2 result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4 which holds the result of the multiplication - public static Matrix2x4 operator *(float left, Matrix2x4 right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4 which holds the result of the multiplication - public static Matrix2x4 operator *(Matrix2x4 left, float right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2 which holds the result of the multiplication - public static Matrix2 operator *(Matrix2x4 left, Matrix4x2 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3 which holds the result of the multiplication - public static Matrix2x3 operator *(Matrix2x4 left, Matrix4x3 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4 which holds the result of the multiplication - public static Matrix2x4 operator *(Matrix2x4 left, Matrix4 right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2 which holds the result of the addition - public static Matrix2x4 operator +(Matrix2x4 left, Matrix2x4 right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4 which holds the result of the subtraction - public static Matrix2x4 operator -(Matrix2x4 left, Matrix2x4 right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix2x4 left, Matrix2x4 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix2x4 left, Matrix2x4 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix4. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}", Row0, Row1); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix2x4)) - return false; - - return this.Equals((Matrix2x4)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix2x4 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix2x4d.cs b/OpenTK/Math/Matrix2x4d.cs deleted file mode 100644 index deb2b1cb..00000000 --- a/OpenTK/Math/Matrix2x4d.cs +++ /dev/null @@ -1,761 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 2x4 matrix. - /// - public struct Matrix2x4d : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector4d Row0; - - /// - /// Bottom row of the matrix. - /// - public Vector4d Row1; - - /// - /// The zero matrix. - /// - public static readonly Matrix2x4d Zero = new Matrix2x4d(Vector4d.Zero, Vector4d.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Bottom row of the matrix. - public Matrix2x4d(Vector4d row0, Vector4d row1) - { - Row0 = row0; - Row1 = row1; - } - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// Fourth item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// Fourth item of the second row of the matrix. - public Matrix2x4d( - double m00, double m01, double m02, double m03, - double m10, double m11, double m12, double m13) - { - Row0 = new Vector4d(m00, m01, m02, m03); - Row1 = new Vector4d(m10, m11, m12, m13); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets or sets the first column of the matrix. - /// - public Vector2d Column0 - { - get { return new Vector2d(Row0.X, Row1.X); } - set { Row0.X = value.X; Row1.X = value.Y; } - } - - /// - /// Gets or sets the second column of the matrix. - /// - public Vector2d Column1 - { - get { return new Vector2d(Row0.Y, Row1.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; } - } - - /// - /// Gets or sets the third column of the matrix. - /// - public Vector2d Column2 - { - get { return new Vector2d(Row0.Z, Row1.Z); } - set { Row0.Z = value.X; Row1.Z = value.Y; } - } - - /// - /// Gets or sets the fourth column of the matrix. - /// - public Vector2d Column3 - { - get { return new Vector2d(Row0.W, Row1.W); } - set { Row0.W = value.X; Row1.W = value.Y; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public double M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public double M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 1, column 4 of this instance. - /// - public double M14 { get { return Row0.W; } set { Row0.W = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public double M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public double M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 4 of this instance. - /// - public double M24 { get { return Row1.W; } set { Row1.W = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2d Diagonal - { - get - { - return new Vector2d(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public double Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public double this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2x4d instance. - public static void CreateRotation(double angle, out Matrix2x4d result) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row1.Z = 0; - result.Row1.W = 0; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix2x3d instance. - public static Matrix2x4d CreateRotation(double angle) - { - Matrix2x4d result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(double scale, out Matrix2x4d result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - result.Row1.Z = 0; - result.Row1.W = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix2x4d CreateScale(double scale) - { - Matrix2x4d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2d scale, out Matrix2x4d result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - result.Row1.Z = 0; - result.Row1.W = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix2x4d CreateScale(Vector2d scale) - { - Matrix2x4d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(double x, double y, out Matrix2x4d result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row1.Z = 0; - result.Row1.W = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix2x4d CreateScale(double x, double y) - { - Matrix2x4d result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x4d left, double right, out Matrix2x4d result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row0.Z = left.Row0.Z * right; - result.Row0.W = left.Row0.W * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - result.Row1.Z = left.Row1.Z * right; - result.Row1.W = left.Row1.W * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x4d Mult(Matrix2x4d left, double right) - { - Matrix2x4d result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x4d left, ref Matrix4x2 right, out Matrix2d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y, - rM31 = right.Row2.X, rM32 = right.Row2.Y, - rM41 = right.Row3.X, rM42 = right.Row3.Y; - - result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41); - result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42); - result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41); - result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2d Mult(Matrix2x4d left, Matrix4x2 right) - { - Matrix2d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x4d left, ref Matrix4x3 right, out Matrix2x3d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z; - - result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41); - result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42); - result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43); - result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41); - result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42); - result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x3d Mult(Matrix2x4d left, Matrix4x3 right) - { - Matrix2x3d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix2x4d left, ref Matrix4 right, out Matrix2x4d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z, rM44 = right.Row3.W; - - result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41); - result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42); - result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43); - result.Row0.W = (((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34)) + (lM14 * rM44); - result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41); - result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42); - result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43); - result.Row1.W = (((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34)) + (lM24 * rM44); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix2x4d Mult(Matrix2x4d left, Matrix4 right) - { - Matrix2x4d result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix2x4d left, ref Matrix2x4d right, out Matrix2x4d result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row0.Z = left.Row0.Z + right.Row0.Z; - result.Row0.W = left.Row0.W + right.Row0.W; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - result.Row1.Z = left.Row1.Z + right.Row1.Z; - result.Row1.W = left.Row1.W + right.Row1.W; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix2x4d Add(Matrix2x4d left, Matrix2x4d right) - { - Matrix2x4d result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix2x4d left, ref Matrix2x4d right, out Matrix2x4d result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row0.Z = left.Row0.Z - right.Row0.Z; - result.Row0.W = left.Row0.W - right.Row0.W; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - result.Row1.Z = left.Row1.Z - right.Row1.Z; - result.Row1.W = left.Row1.W - right.Row1.W; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix2x4d Subtract(Matrix2x4d left, Matrix2x4d right) - { - Matrix2x4d result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix2x4d mat, out Matrix4x2d result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - result.Row2.X = mat.Row0.Z; - result.Row2.Y = mat.Row1.Z; - result.Row3.X = mat.Row0.W; - result.Row3.Y = mat.Row1.W; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix4x2d Transpose(Matrix2x4d mat) - { - Matrix4x2d result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4d which holds the result of the multiplication - public static Matrix2x4d operator *(double left, Matrix2x4d right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4d which holds the result of the multiplication - public static Matrix2x4d operator *(Matrix2x4d left, double right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2d which holds the result of the multiplication - public static Matrix2d operator *(Matrix2x4d left, Matrix4x2 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x3d which holds the result of the multiplication - public static Matrix2x3d operator *(Matrix2x4d left, Matrix4x3 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4d which holds the result of the multiplication - public static Matrix2x4d operator *(Matrix2x4d left, Matrix4 right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2d which holds the result of the addition - public static Matrix2x4d operator +(Matrix2x4d left, Matrix2x4d right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2x4d which holds the result of the subtraction - public static Matrix2x4d operator -(Matrix2x4d left, Matrix2x4d right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix2x4d left, Matrix2x4d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix2x4d left, Matrix2x4d right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix4. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}", Row0, Row1); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix2x4d)) - return false; - - return this.Equals((Matrix2x4d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix2x4d other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix3.cs b/OpenTK/Math/Matrix3.cs deleted file mode 100644 index cd2f3bc7..00000000 --- a/OpenTK/Math/Matrix3.cs +++ /dev/null @@ -1,974 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 3x3 matrix containing 3D rotation and scale. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Matrix3 : IEquatable - { - #region Fields - - /// - /// First row of the matrix. - /// - public Vector3 Row0; - - /// - /// Second row of the matrix. - /// - public Vector3 Row1; - - /// - /// Third row of the matrix. - /// - public Vector3 Row2; - - /// - /// The identity matrix. - /// - public static readonly Matrix3 Identity = new Matrix3(Vector3.UnitX, Vector3.UnitY, Vector3.UnitZ); - - /// - /// The zero matrix. - /// - public static readonly Matrix3 Zero = new Matrix3(Vector3.Zero, Vector3.Zero, Vector3.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix - /// Second row of the matrix - /// Bottom row of the matrix - public Matrix3(Vector3 row0, Vector3 row1, Vector3 row2) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - } - - /// - /// Constructs a new instance. - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// Third item of the third row of the matrix. - public Matrix3( - float m00, float m01, float m02, - float m10, float m11, float m12, - float m20, float m21, float m22) - { - Row0 = new Vector3(m00, m01, m02); - Row1 = new Vector3(m10, m11, m12); - Row2 = new Vector3(m20, m21, m22); - } - - /// - /// Constructs a new instance. - /// - /// A Matrix4 to take the upper-left 3x3 from. - public Matrix3(Matrix4 matrix) - { - Row0 = matrix.Row0.Xyz; - Row1 = matrix.Row1.Xyz; - Row2 = matrix.Row2.Xyz; - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets the determinant of this matrix. - /// - public float Determinant - { - get - { - float m11 = Row0.X, m12 = Row0.Y, m13 = Row0.Z, - m21 = Row1.X, m22 = Row1.Y, m23 = Row1.Z, - m31 = Row2.X, m32 = Row2.Y, m33 = Row2.Z; - - return m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32 - - m13 * m22 * m31 - m11 * m23 * m32 - m12 * m21 * m33; - } - } - - /// - /// Gets the first column of this matrix. - /// - public Vector3 Column0 - { - get { return new Vector3(Row0.X, Row1.X, Row2.X); } - } - - /// - /// Gets the second column of this matrix. - /// - public Vector3 Column1 - { - get { return new Vector3(Row0.Y, Row1.Y, Row2.Y); } - } - - /// - /// Gets the third column of this matrix. - /// - public Vector3 Column2 - { - get { return new Vector3(Row0.Z, Row1.Z, Row2.Z); } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public float M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public float M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public float M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public float M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 3 of this instance. - /// - public float M33 { get { return Row2.Z; } set { Row2.Z = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector3 Diagonal - { - get - { - return new Vector3(Row0.X, Row1.Y, Row2.Z); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - Row2.Z = value.Z; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public float Trace { get { return Row0.X + Row1.Y + Row2.Z; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public float this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - /// - public void Invert() - { - this = Matrix3.Invert(this); - } - - #endregion - - #region public void Transpose() - - /// - /// Converts this instance into its transpose. - /// - public void Transpose() - { - this = Matrix3.Transpose(this); - } - - #endregion - - /// - /// Returns a normalised copy of this instance. - /// - public Matrix3 Normalized() - { - Matrix3 m = this; - m.Normalize(); - return m; - } - - /// - /// Divides each element in the Matrix by the . - /// - public void Normalize() - { - var determinant = this.Determinant; - Row0 /= determinant; - Row1 /= determinant; - Row2 /= determinant; - } - - /// - /// Returns an inverted copy of this instance. - /// - public Matrix3 Inverted() - { - Matrix3 m = this; - if (m.Determinant != 0) - m.Invert(); - return m; - } - - /// - /// Returns a copy of this Matrix3 without scale. - /// - public Matrix3 ClearScale() - { - Matrix3 m = this; - m.Row0 = m.Row0.Normalized(); - m.Row1 = m.Row1.Normalized(); - m.Row2 = m.Row2.Normalized(); - return m; - } - /// - /// Returns a copy of this Matrix3 without rotation. - /// - public Matrix3 ClearRotation() - { - Matrix3 m = this; - m.Row0 = new Vector3(m.Row0.Length, 0, 0); - m.Row1 = new Vector3(0, m.Row1.Length, 0); - m.Row2 = new Vector3(0, 0, m.Row2.Length); - return m; - } - - /// - /// Returns the scale component of this instance. - /// - public Vector3 ExtractScale() { return new Vector3(Row0.Length, Row1.Length, Row2.Length); } - - /// - /// Returns the rotation component of this instance. Quite slow. - /// - /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised. - public Quaternion ExtractRotation(bool row_normalise = true) - { - var row0 = Row0; - var row1 = Row1; - var row2 = Row2; - - if (row_normalise) - { - row0 = row0.Normalized(); - row1 = row1.Normalized(); - row2 = row2.Normalized(); - } - - // code below adapted from Blender - - Quaternion q = new Quaternion(); - double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0); - - if (trace > 0) - { - double sq = Math.Sqrt(trace); - - q.W = (float)sq; - sq = 1.0 / (4.0 * sq); - q.X = (float)((row1[2] - row2[1]) * sq); - q.Y = (float)((row2[0] - row0[2]) * sq); - q.Z = (float)((row0[1] - row1[0]) * sq); - } - else if (row0[0] > row1[1] && row0[0] > row2[2]) - { - double sq = 2.0 * Math.Sqrt(1.0 + row0[0] - row1[1] - row2[2]); - - q.X = (float)(0.25 * sq); - sq = 1.0 / sq; - q.W = (float)((row2[1] - row1[2]) * sq); - q.Y = (float)((row1[0] + row0[1]) * sq); - q.Z = (float)((row2[0] + row0[2]) * sq); - } - else if (row1[1] > row2[2]) - { - double sq = 2.0 * Math.Sqrt(1.0 + row1[1] - row0[0] - row2[2]); - - q.Y = (float)(0.25 * sq); - sq = 1.0 / sq; - q.W = (float)((row2[0] - row0[2]) * sq); - q.X = (float)((row1[0] + row0[1]) * sq); - q.Z = (float)((row2[1] + row1[2]) * sq); - } - else - { - double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]); - - q.Z = (float)(0.25 * sq); - sq = 1.0 / sq; - q.W = (float)((row1[0] - row0[1]) * sq); - q.X = (float)((row2[0] + row0[2]) * sq); - q.Y = (float)((row2[1] + row1[2]) * sq); - } - - q.Normalize(); - return q; - } - - #endregion - - #region Static - - #region CreateFromAxisAngle - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix3 result) - { - //normalize and create a local copy of the vector. - axis.Normalize(); - float axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; - - //calculate angles - float cos = (float)System.Math.Cos(-angle); - float sin = (float)System.Math.Sin(-angle); - float t = 1.0f - cos; - - //do the conversion math once - float tXX = t * axisX * axisX, - tXY = t * axisX * axisY, - tXZ = t * axisX * axisZ, - tYY = t * axisY * axisY, - tYZ = t * axisY * axisZ, - tZZ = t * axisZ * axisZ; - - float sinX = sin * axisX, - sinY = sin * axisY, - sinZ = sin * axisZ; - - result.Row0.X = tXX + cos; - result.Row0.Y = tXY - sinZ; - result.Row0.Z = tXZ + sinY; - result.Row1.X = tXY + sinZ; - result.Row1.Y = tYY + cos; - result.Row1.Z = tYZ - sinX; - result.Row2.X = tXZ - sinY; - result.Row2.Y = tYZ + sinX; - result.Row2.Z = tZZ + cos; - } - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static Matrix3 CreateFromAxisAngle(Vector3 axis, float angle) - { - Matrix3 result; - CreateFromAxisAngle(axis, angle, out result); - return result; - } - - #endregion - - #region CreateFromQuaternion - - /// - /// Build a rotation matrix from the specified quaternion. - /// - /// Quaternion to translate. - /// Matrix result. - public static void CreateFromQuaternion(ref Quaternion q, out Matrix3 result) - { - Vector3 axis; - float angle; - q.ToAxisAngle(out axis, out angle); - CreateFromAxisAngle(axis, angle, out result); - } - - /// - /// Build a rotation matrix from the specified quaternion. - /// - /// Quaternion to translate. - /// A matrix instance. - public static Matrix3 CreateFromQuaternion(Quaternion q) - { - Matrix3 result; - CreateFromQuaternion(ref q, out result); - return result; - } - - #endregion - - #region CreateRotation[XYZ] - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3 instance. - public static void CreateRotationX(float angle, out Matrix3 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result = Identity; - result.Row1.Y = cos; - result.Row1.Z = sin; - result.Row2.Y = -sin; - result.Row2.Z = cos; - } - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3 instance. - public static Matrix3 CreateRotationX(float angle) - { - Matrix3 result; - CreateRotationX(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3 instance. - public static void CreateRotationY(float angle, out Matrix3 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result = Identity; - result.Row0.X = cos; - result.Row0.Z = -sin; - result.Row2.X = sin; - result.Row2.Z = cos; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3 instance. - public static Matrix3 CreateRotationY(float angle) - { - Matrix3 result; - CreateRotationY(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3 instance. - public static void CreateRotationZ(float angle, out Matrix3 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result = Identity; - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row1.X = -sin; - result.Row1.Y = cos; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3 instance. - public static Matrix3 CreateRotationZ(float angle) - { - Matrix3 result; - CreateRotationZ(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static Matrix3 CreateScale(float scale) - { - Matrix3 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x, y, and z axes. - /// A scale matrix. - public static Matrix3 CreateScale(Vector3 scale) - { - Matrix3 result; - CreateScale(ref scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// Scale factor for the z axis. - /// A scale matrix. - public static Matrix3 CreateScale(float x, float y, float z) - { - Matrix3 result; - CreateScale(x, y, z, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(float scale, out Matrix3 result) - { - result = Identity; - result.Row0.X = scale; - result.Row1.Y = scale; - result.Row2.Z = scale; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(ref Vector3 scale, out Matrix3 result) - { - result = Identity; - result.Row0.X = scale.X; - result.Row1.Y = scale.Y; - result.Row2.Z = scale.Z; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// Scale factor for the z axis. - /// A scale matrix. - public static void CreateScale(float x, float y, float z, out Matrix3 result) - { - result = Identity; - result.Row0.X = x; - result.Row1.Y = y; - result.Row2.Z = z; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix3 Mult(Matrix3 left, Matrix3 right) - { - Matrix3 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix3 left, ref Matrix3 right, out Matrix3 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z; - - result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); - result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32); - result.Row0.Z = ((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33); - result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); - result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32); - result.Row1.Z = ((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33); - result.Row2.X = ((lM31 * rM11) + (lM32 * rM21)) + (lM33 * rM31); - result.Row2.Y = ((lM31 * rM12) + (lM32 * rM22)) + (lM33 * rM32); - result.Row2.Z = ((lM31 * rM13) + (lM32 * rM23)) + (lM33 * rM33); - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix3 is singular. - public static void Invert(ref Matrix3 mat, out Matrix3 result) - { - int[] colIdx = { 0, 0, 0 }; - int[] rowIdx = { 0, 0, 0 }; - int[] pivotIdx = { -1, -1, -1 }; - - float[,] inverse = {{mat.Row0.X, mat.Row0.Y, mat.Row0.Z}, - {mat.Row1.X, mat.Row1.Y, mat.Row1.Z}, - {mat.Row2.X, mat.Row2.Y, mat.Row2.Z}}; - - int icol = 0; - int irow = 0; - for (int i = 0; i < 3; i++) - { - float maxPivot = 0.0f; - for (int j = 0; j < 3; j++) - { - if (pivotIdx[j] != 0) - { - for (int k = 0; k < 3; ++k) - { - if (pivotIdx[k] == -1) - { - float absVal = System.Math.Abs(inverse[j, k]); - if (absVal > maxPivot) - { - maxPivot = absVal; - irow = j; - icol = k; - } - } - else if (pivotIdx[k] > 0) - { - result = mat; - return; - } - } - } - } - - ++(pivotIdx[icol]); - - if (irow != icol) - { - for (int k = 0; k < 3; ++k) - { - float f = inverse[irow, k]; - inverse[irow, k] = inverse[icol, k]; - inverse[icol, k] = f; - } - } - - rowIdx[i] = irow; - colIdx[i] = icol; - - float pivot = inverse[icol, icol]; - - if (pivot == 0.0f) - { - throw new InvalidOperationException("Matrix is singular and cannot be inverted."); - } - - float oneOverPivot = 1.0f / pivot; - inverse[icol, icol] = 1.0f; - for (int k = 0; k < 3; ++k) - inverse[icol, k] *= oneOverPivot; - - for (int j = 0; j < 3; ++j) - { - if (icol != j) - { - float f = inverse[j, icol]; - inverse[j, icol] = 0.0f; - for (int k = 0; k < 3; ++k) - inverse[j, k] -= inverse[icol, k] * f; - } - } - } - - for (int j = 2; j >= 0; --j) - { - int ir = rowIdx[j]; - int ic = colIdx[j]; - for (int k = 0; k < 3; ++k) - { - float f = inverse[k, ir]; - inverse[k, ir] = inverse[k, ic]; - inverse[k, ic] = f; - } - } - - result.Row0.X = inverse[0, 0]; - result.Row0.Y = inverse[0, 1]; - result.Row0.Z = inverse[0, 2]; - result.Row1.X = inverse[1, 0]; - result.Row1.Y = inverse[1, 1]; - result.Row1.Z = inverse[1, 2]; - result.Row2.X = inverse[2, 0]; - result.Row2.Y = inverse[2, 1]; - result.Row2.Z = inverse[2, 2]; - } - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static Matrix3 Invert(Matrix3 mat) - { - Matrix3 result; - Invert(ref mat, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The transpose of the given matrix - public static Matrix3 Transpose(Matrix3 mat) - { - return new Matrix3(mat.Column0, mat.Column1, mat.Column2); - } - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The result of the calculation - public static void Transpose(ref Matrix3 mat, out Matrix3 result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row0.Z = mat.Row2.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - result.Row1.Z = mat.Row2.Y; - result.Row2.X = mat.Row0.Z; - result.Row2.Y = mat.Row1.Z; - result.Row2.Z = mat.Row2.Z; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3d which holds the result of the multiplication - public static Matrix3 operator *(Matrix3 left, Matrix3 right) - { - return Matrix3.Mult(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix3 left, Matrix3 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix3 left, Matrix3 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix3d. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix3)) - return false; - - return this.Equals((Matrix3)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current matrix is equal to another matrix. - /// A matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix3 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2; - } - - #endregion - } -} \ No newline at end of file diff --git a/OpenTK/Math/Matrix3d.cs b/OpenTK/Math/Matrix3d.cs deleted file mode 100644 index 757c36ca..00000000 --- a/OpenTK/Math/Matrix3d.cs +++ /dev/null @@ -1,965 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 3x3 matrix containing 3D rotation and scale with double-precision components. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Matrix3d : IEquatable - { - #region Fields - - /// - /// First row of the matrix. - /// - public Vector3d Row0; - - /// - /// Second row of the matrix. - /// - public Vector3d Row1; - - /// - /// Third row of the matrix. - /// - public Vector3d Row2; - - /// - /// The identity matrix. - /// - public static Matrix3d Identity = new Matrix3d(Vector3d.UnitX, Vector3d.UnitY, Vector3d.UnitZ); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix - /// Second row of the matrix - /// Bottom row of the matrix - public Matrix3d(Vector3d row0, Vector3d row1, Vector3d row2) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - } - - /// - /// Constructs a new instance. - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// Third item of the third row of the matrix. - public Matrix3d( - double m00, double m01, double m02, - double m10, double m11, double m12, - double m20, double m21, double m22) - { - Row0 = new Vector3d(m00, m01, m02); - Row1 = new Vector3d(m10, m11, m12); - Row2 = new Vector3d(m20, m21, m22); - } - - /// - /// Constructs a new instance. - /// - /// A Matrix4d to take the upper-left 3x3 from. - public Matrix3d(Matrix4d matrix) - { - Row0 = matrix.Row0.Xyz; - Row1 = matrix.Row1.Xyz; - Row2 = matrix.Row2.Xyz; - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets the determinant of this matrix. - /// - public double Determinant - { - get - { - double m11 = Row0.X, m12 = Row0.Y, m13 = Row0.Z, - m21 = Row1.X, m22 = Row1.Y, m23 = Row1.Z, - m31 = Row2.X, m32 = Row2.Y, m33 = Row2.Z; - - return - m11 * m22 * m33 + m12 * m23 * m31 + m13 * m21 * m32 - - m13 * m22 * m31 - m11 * m23 * m32 - m12 * m21 * m33; - } - } - - /// - /// Gets the first column of this matrix. - /// - public Vector3d Column0 - { - get { return new Vector3d(Row0.X, Row1.X, Row2.X); } - } - - /// - /// Gets the second column of this matrix. - /// - public Vector3d Column1 - { - get { return new Vector3d(Row0.Y, Row1.Y, Row2.Y); } - } - - /// - /// Gets the third column of this matrix. - /// - public Vector3d Column2 - { - get { return new Vector3d(Row0.Z, Row1.Z, Row2.Z); } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public double M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public double M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public double M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public double M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public double M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public double M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 3 of this instance. - /// - public double M33 { get { return Row2.Z; } set { Row2.Z = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector3d Diagonal - { - get - { - return new Vector3d(Row0.X, Row1.Y, Row2.Z); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - Row2.Z = value.Z; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public double Trace { get { return Row0.X + Row1.Y + Row2.Z; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public double this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - /// - public void Invert() - { - this = Matrix3d.Invert(this); - } - - #endregion - - #region public void Transpose() - - /// - /// Converts this instance into its transpose. - /// - public void Transpose() - { - this = Matrix3d.Transpose(this); - } - - #endregion - - /// - /// Returns a normalised copy of this instance. - /// - public Matrix3d Normalized() - { - Matrix3d m = this; - m.Normalize(); - return m; - } - - /// - /// Divides each element in the Matrix by the . - /// - public void Normalize() - { - var determinant = this.Determinant; - Row0 /= determinant; - Row1 /= determinant; - Row2 /= determinant; - } - - /// - /// Returns an inverted copy of this instance. - /// - public Matrix3d Inverted() - { - Matrix3d m = this; - if (m.Determinant != 0) - m.Invert(); - return m; - } - - - /// - /// Returns a copy of this Matrix3 without scale. - /// - public Matrix3d ClearScale() - { - Matrix3d m = this; - m.Row0 = m.Row0.Normalized(); - m.Row1 = m.Row1.Normalized(); - m.Row2 = m.Row2.Normalized(); - return m; - } - /// - /// Returns a copy of this Matrix3 without rotation. - /// - public Matrix3d ClearRotation() - { - Matrix3d m = this; - m.Row0 = new Vector3d(m.Row0.Length, 0, 0); - m.Row1 = new Vector3d(0, m.Row1.Length, 0); - m.Row2 = new Vector3d(0, 0, m.Row2.Length); - return m; - } - - /// - /// Returns the scale component of this instance. - /// - public Vector3d ExtractScale() { return new Vector3d(Row0.Length, Row1.Length, Row2.Length); } - - /// - /// Returns the rotation component of this instance. Quite slow. - /// - /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised. - public Quaterniond ExtractRotation(bool row_normalise = true) - { - var row0 = Row0; - var row1 = Row1; - var row2 = Row2; - - if (row_normalise) - { - row0 = row0.Normalized(); - row1 = row1.Normalized(); - row2 = row2.Normalized(); - } - - // code below adapted from Blender - - Quaterniond q = new Quaterniond(); - double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0); - - if (trace > 0) - { - double sq = Math.Sqrt(trace); - - q.W = sq; - sq = 1.0 / (4.0 * sq); - q.X = (row1[2] - row2[1]) * sq; - q.Y = (row2[0] - row0[2]) * sq; - q.Z = (row0[1] - row1[0]) * sq; - } - else if (row0[0] > row1[1] && row0[0] > row2[2]) - { - double sq = 2.0 * Math.Sqrt(1.0 + row0[0] - row1[1] - row2[2]); - - q.X = 0.25 * sq; - sq = 1.0 / sq; - q.W = (row2[1] - row1[2]) * sq; - q.Y = (row1[0] + row0[1]) * sq; - q.Z = (row2[0] + row0[2]) * sq; - } - else if (row1[1] > row2[2]) - { - double sq = 2.0 * Math.Sqrt(1.0 + row1[1] - row0[0] - row2[2]); - - q.Y = 0.25 * sq; - sq = 1.0 / sq; - q.W = (row2[0] - row0[2]) * sq; - q.X = (row1[0] + row0[1]) * sq; - q.Z = (row2[1] + row1[2]) * sq; - } - else - { - double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]); - - q.Z = 0.25 * sq; - sq = 1.0 / sq; - q.W = (row1[0] - row0[1]) * sq; - q.X = (row2[0] + row0[2]) * sq; - q.Y = (row2[1] + row1[2]) * sq; - } - - q.Normalize(); - return q; - } - - #endregion - - #region Static - - #region CreateFromAxisAngle - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static void CreateFromAxisAngle(Vector3d axis, double angle, out Matrix3d result) - { - //normalize and create a local copy of the vector. - axis.Normalize(); - double axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; - - //calculate angles - double cos = System.Math.Cos(-angle); - double sin = System.Math.Sin(-angle); - double t = 1.0f - cos; - - //do the conversion math once - double tXX = t * axisX * axisX, - tXY = t * axisX * axisY, - tXZ = t * axisX * axisZ, - tYY = t * axisY * axisY, - tYZ = t * axisY * axisZ, - tZZ = t * axisZ * axisZ; - - double sinX = sin * axisX, - sinY = sin * axisY, - sinZ = sin * axisZ; - - result.Row0.X = tXX + cos; - result.Row0.Y = tXY - sinZ; - result.Row0.Z = tXZ + sinY; - result.Row1.X = tXY + sinZ; - result.Row1.Y = tYY + cos; - result.Row1.Z = tYZ - sinX; - result.Row2.X = tXZ - sinY; - result.Row2.Y = tYZ + sinX; - result.Row2.Z = tZZ + cos; - } - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static Matrix3d CreateFromAxisAngle(Vector3d axis, double angle) - { - Matrix3d result; - CreateFromAxisAngle(axis, angle, out result); - return result; - } - - #endregion - - #region CreateFromQuaternion - - /// - /// Build a rotation matrix from the specified quaternion. - /// - /// Quaternion to translate. - /// Matrix result. - public static void CreateFromQuaternion(ref Quaterniond q, out Matrix3d result) - { - Vector3d axis; - double angle; - q.ToAxisAngle(out axis, out angle); - CreateFromAxisAngle(axis, angle, out result); - } - - /// - /// Build a rotation matrix from the specified quaternion. - /// - /// Quaternion to translate. - /// A matrix instance. - public static Matrix3d CreateFromQuaternion(Quaterniond q) - { - Matrix3d result; - CreateFromQuaternion(ref q, out result); - return result; - } - - #endregion - - #region CreateRotation[XYZ] - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3d instance. - public static void CreateRotationX(double angle, out Matrix3d result) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - result = Identity; - result.Row1.Y = cos; - result.Row1.Z = sin; - result.Row2.Y = -sin; - result.Row2.Z = cos; - } - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3d instance. - public static Matrix3d CreateRotationX(double angle) - { - Matrix3d result; - CreateRotationX(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3d instance. - public static void CreateRotationY(double angle, out Matrix3d result) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - result = Identity; - result.Row0.X = cos; - result.Row0.Z = -sin; - result.Row2.X = sin; - result.Row2.Z = cos; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3d instance. - public static Matrix3d CreateRotationY(double angle) - { - Matrix3d result; - CreateRotationY(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3d instance. - public static void CreateRotationZ(double angle, out Matrix3d result) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - result = Identity; - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row1.X = -sin; - result.Row1.Y = cos; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3d instance. - public static Matrix3d CreateRotationZ(double angle) - { - Matrix3d result; - CreateRotationZ(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static Matrix3d CreateScale(double scale) - { - Matrix3d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x, y, and z axes. - /// A scale matrix. - public static Matrix3d CreateScale(Vector3d scale) - { - Matrix3d result; - CreateScale(ref scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// Scale factor for the z axis. - /// A scale matrix. - public static Matrix3d CreateScale(double x, double y, double z) - { - Matrix3d result; - CreateScale(x, y, z, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(double scale, out Matrix3d result) - { - result = Identity; - result.Row0.X = scale; - result.Row1.Y = scale; - result.Row2.Z = scale; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(ref Vector3d scale, out Matrix3d result) - { - result = Identity; - result.Row0.X = scale.X; - result.Row1.Y = scale.Y; - result.Row2.Z = scale.Z; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// Scale factor for the z axis. - /// A scale matrix. - public static void CreateScale(double x, double y, double z, out Matrix3d result) - { - result = Identity; - result.Row0.X = x; - result.Row1.Y = y; - result.Row2.Z = z; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix3d Mult(Matrix3d left, Matrix3d right) - { - Matrix3d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix3d left, ref Matrix3d right, out Matrix3d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z; - - result.Row0.X = ((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31); - result.Row0.Y = ((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32); - result.Row0.Z = ((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33); - result.Row1.X = ((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31); - result.Row1.Y = ((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32); - result.Row1.Z = ((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33); - result.Row2.X = ((lM31 * rM11) + (lM32 * rM21)) + (lM33 * rM31); - result.Row2.Y = ((lM31 * rM12) + (lM32 * rM22)) + (lM33 * rM32); - result.Row2.Z = ((lM31 * rM13) + (lM32 * rM23)) + (lM33 * rM33); - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix3d is singular. - public static void Invert(ref Matrix3d mat, out Matrix3d result) - { - int[] colIdx = { 0, 0, 0 }; - int[] rowIdx = { 0, 0, 0 }; - int[] pivotIdx = { -1, -1, -1 }; - - double[,] inverse = {{mat.Row0.X, mat.Row0.Y, mat.Row0.Z}, - {mat.Row1.X, mat.Row1.Y, mat.Row1.Z}, - {mat.Row2.X, mat.Row2.Y, mat.Row2.Z}}; - - int icol = 0; - int irow = 0; - for (int i = 0; i < 3; i++) - { - double maxPivot = 0.0; - for (int j = 0; j < 3; j++) - { - if (pivotIdx[j] != 0) - { - for (int k = 0; k < 3; ++k) - { - if (pivotIdx[k] == -1) - { - double absVal = System.Math.Abs(inverse[j, k]); - if (absVal > maxPivot) - { - maxPivot = absVal; - irow = j; - icol = k; - } - } - else if (pivotIdx[k] > 0) - { - result = mat; - return; - } - } - } - } - - ++(pivotIdx[icol]); - - if (irow != icol) - { - for (int k = 0; k < 3; ++k) - { - double f = inverse[irow, k]; - inverse[irow, k] = inverse[icol, k]; - inverse[icol, k] = f; - } - } - - rowIdx[i] = irow; - colIdx[i] = icol; - - double pivot = inverse[icol, icol]; - - if (pivot == 0.0) - { - throw new InvalidOperationException("Matrix is singular and cannot be inverted."); - } - - double oneOverPivot = 1.0 / pivot; - inverse[icol, icol] = 1.0; - for (int k = 0; k < 3; ++k) - inverse[icol, k] *= oneOverPivot; - - for (int j = 0; j < 3; ++j) - { - if (icol != j) - { - double f = inverse[j, icol]; - inverse[j, icol] = 0.0; - for (int k = 0; k < 3; ++k) - inverse[j, k] -= inverse[icol, k] * f; - } - } - } - - for (int j = 2; j >= 0; --j) - { - int ir = rowIdx[j]; - int ic = colIdx[j]; - for (int k = 0; k < 3; ++k) - { - double f = inverse[k, ir]; - inverse[k, ir] = inverse[k, ic]; - inverse[k, ic] = f; - } - } - - result.Row0.X = inverse[0, 0]; - result.Row0.Y = inverse[0, 1]; - result.Row0.Z = inverse[0, 2]; - result.Row1.X = inverse[1, 0]; - result.Row1.Y = inverse[1, 1]; - result.Row1.Z = inverse[1, 2]; - result.Row2.X = inverse[2, 0]; - result.Row2.Y = inverse[2, 1]; - result.Row2.Z = inverse[2, 2]; - } - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static Matrix3d Invert(Matrix3d mat) - { - Matrix3d result; - Invert(ref mat, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The transpose of the given matrix - public static Matrix3d Transpose(Matrix3d mat) - { - return new Matrix3d(mat.Column0, mat.Column1, mat.Column2); - } - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The result of the calculation - public static void Transpose(ref Matrix3d mat, out Matrix3d result) - { - result.Row0 = mat.Column0; - result.Row1 = mat.Column1; - result.Row2 = mat.Column2; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3d which holds the result of the multiplication - public static Matrix3d operator *(Matrix3d left, Matrix3d right) - { - return Matrix3d.Mult(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix3d left, Matrix3d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix3d left, Matrix3d right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix3d. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix3d)) - return false; - - return this.Equals((Matrix3d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current matrix is equal to another matrix. - /// A matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix3d other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix3x2.cs b/OpenTK/Math/Matrix3x2.cs deleted file mode 100644 index 639f093a..00000000 --- a/OpenTK/Math/Matrix3x2.cs +++ /dev/null @@ -1,736 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 3x2 matrix. - /// - public struct Matrix3x2 : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector2 Row0; - - /// - /// Second row of the matrix. - /// - public Vector2 Row1; - - /// - /// Bottom row of the matrix. - /// - public Vector2 Row2; - - /// - /// The zero matrix. - /// - public static readonly Matrix3x2 Zero = new Matrix3x2(Vector2.Zero, Vector2.Zero, Vector2.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Second row of the matrix. - /// Bottom row of the matrix. - public Matrix3x2(Vector2 row0, Vector2 row1, Vector2 row2) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - } - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - public Matrix3x2( - float m00, float m01, - float m10, float m11, - float m20, float m21) - { - Row0 = new Vector2(m00, m01); - Row1 = new Vector2(m10, m11); - Row2 = new Vector2(m20, m21); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets or sets the first column of this matrix. - /// - public Vector3 Column0 - { - get { return new Vector3(Row0.X, Row1.X, Row2.X); } - set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; } - } - - /// - /// Gets or sets the second column of this matrix. - /// - public Vector3 Column1 - { - get { return new Vector3(Row0.Y, Row1.Y, Row2.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public float M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public float M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2 Diagonal - { - get - { - return new Vector2(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public float Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public float this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3x2 instance. - public static void CreateRotation(float angle, out Matrix3x2 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row2.X = 0; - result.Row2.Y = 0; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3x2 instance. - public static Matrix3x2 CreateRotation(float angle) - { - Matrix3x2 result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(float scale, out Matrix3x2 result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - result.Row2.X = 0; - result.Row2.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix3x2 CreateScale(float scale) - { - Matrix3x2 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2 scale, out Matrix3x2 result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - result.Row2.X = 0; - result.Row2.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix3x2 CreateScale(Vector2 scale) - { - Matrix3x2 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(float x, float y, out Matrix3x2 result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row2.X = 0; - result.Row2.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix3x2 CreateScale(float x, float y) - { - Matrix3x2 result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix3x2 left, float right, out Matrix3x2 result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - result.Row2.X = left.Row2.X * right; - result.Row2.Y = left.Row2.Y * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix3x2 Mult(Matrix3x2 left, float right) - { - Matrix3x2 result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix3x2 left, ref Matrix2 right, out Matrix3x2 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix3x2 Mult(Matrix3x2 left, Matrix2 right) - { - Matrix3x2 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix3x2 left, ref Matrix2x3 right, out Matrix3 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix3 Mult(Matrix3x2 left, Matrix2x3 right) - { - Matrix3 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix3x2 left, ref Matrix2x4 right, out Matrix3x4 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23); - result.Row2.W = (lM31 * rM14) + (lM32 * rM24); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix3x4 Mult(Matrix3x2 left, Matrix2x4 right) - { - Matrix3x4 result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix3x2 left, ref Matrix3x2 right, out Matrix3x2 result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - result.Row2.X = left.Row2.X + right.Row2.X; - result.Row2.Y = left.Row2.Y + right.Row2.Y; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix3x2 Add(Matrix3x2 left, Matrix3x2 right) - { - Matrix3x2 result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix3x2 left, ref Matrix3x2 right, out Matrix3x2 result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - result.Row2.X = left.Row2.X - right.Row2.X; - result.Row2.Y = left.Row2.Y - right.Row2.Y; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix3x2 Subtract(Matrix3x2 left, Matrix3x2 right) - { - Matrix3x2 result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix3x2 mat, out Matrix2x3 result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row0.Z = mat.Row2.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - result.Row1.Z = mat.Row2.Y; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix2x3 Transpose(Matrix3x2 mat) - { - Matrix2x3 result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2 which holds the result of the multiplication - public static Matrix3x2 operator *(float left, Matrix3x2 right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2 which holds the result of the multiplication - public static Matrix3x2 operator *(Matrix3x2 left, float right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2 which holds the result of the multiplication - public static Matrix3x2 operator *(Matrix3x2 left, Matrix2 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3 which holds the result of the multiplication - public static Matrix3 operator *(Matrix3x2 left, Matrix2x3 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4 which holds the result of the multiplication - public static Matrix3x4 operator *(Matrix3x2 left, Matrix2x4 right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2 which holds the result of the addition - public static Matrix3x2 operator +(Matrix3x2 left, Matrix3x2 right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2 which holds the result of the subtraction - public static Matrix3x2 operator -(Matrix3x2 left, Matrix3x2 right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix3x2 left, Matrix3x2 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix3x2 left, Matrix3x2 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix3d. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix3x2)) - return false; - - return this.Equals((Matrix3x2)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix3x2 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix3x2d.cs b/OpenTK/Math/Matrix3x2d.cs deleted file mode 100644 index 8f1804e9..00000000 --- a/OpenTK/Math/Matrix3x2d.cs +++ /dev/null @@ -1,736 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 3x2 matrix. - /// - public struct Matrix3x2d : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector2d Row0; - - /// - /// Second row of the matrix. - /// - public Vector2d Row1; - - /// - /// Bottom row of the matrix. - /// - public Vector2d Row2; - - /// - /// The zero matrix. - /// - public static readonly Matrix3x2d Zero = new Matrix3x2d(Vector2d.Zero, Vector2d.Zero, Vector2d.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Second row of the matrix. - /// Bottom row of the matrix. - public Matrix3x2d(Vector2d row0, Vector2d row1, Vector2d row2) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - } - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - public Matrix3x2d( - double m00, double m01, - double m10, double m11, - double m20, double m21) - { - Row0 = new Vector2d(m00, m01); - Row1 = new Vector2d(m10, m11); - Row2 = new Vector2d(m20, m21); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets or sets the first column of this matrix. - /// - public Vector3d Column0 - { - get { return new Vector3d(Row0.X, Row1.X, Row2.X); } - set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; } - } - - /// - /// Gets or sets the second column of this matrix. - /// - public Vector3d Column1 - { - get { return new Vector3d(Row0.Y, Row1.Y, Row2.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public double M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public double M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public double M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public double M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2d Diagonal - { - get - { - return new Vector2d(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public double Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public double this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3x2d instance. - public static void CreateRotation(double angle, out Matrix3x2d result) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row2.X = 0; - result.Row2.Y = 0; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3x2d instance. - public static Matrix3x2d CreateRotation(double angle) - { - Matrix3x2d result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(double scale, out Matrix3x2d result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - result.Row2.X = 0; - result.Row2.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix3x2d CreateScale(double scale) - { - Matrix3x2d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2d scale, out Matrix3x2d result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - result.Row2.X = 0; - result.Row2.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix3x2d CreateScale(Vector2d scale) - { - Matrix3x2d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(double x, double y, out Matrix3x2d result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row2.X = 0; - result.Row2.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix3x2d CreateScale(double x, double y) - { - Matrix3x2d result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix3x2d left, double right, out Matrix3x2d result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - result.Row2.X = left.Row2.X * right; - result.Row2.Y = left.Row2.Y * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix3x2d Mult(Matrix3x2d left, double right) - { - Matrix3x2d result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix3x2d left, ref Matrix2d right, out Matrix3x2d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix3x2d Mult(Matrix3x2d left, Matrix2d right) - { - Matrix3x2d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix3x2d left, ref Matrix2x3d right, out Matrix3d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix3d Mult(Matrix3x2d left, Matrix2x3d right) - { - Matrix3d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix3x2d left, ref Matrix2x4d right, out Matrix3x4d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23); - result.Row2.W = (lM31 * rM14) + (lM32 * rM24); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix3x4d Mult(Matrix3x2d left, Matrix2x4d right) - { - Matrix3x4d result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix3x2d left, ref Matrix3x2d right, out Matrix3x2d result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - result.Row2.X = left.Row2.X + right.Row2.X; - result.Row2.Y = left.Row2.Y + right.Row2.Y; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix3x2d Add(Matrix3x2d left, Matrix3x2d right) - { - Matrix3x2d result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix3x2d left, ref Matrix3x2d right, out Matrix3x2d result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - result.Row2.X = left.Row2.X - right.Row2.X; - result.Row2.Y = left.Row2.Y - right.Row2.Y; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix3x2d Subtract(Matrix3x2d left, Matrix3x2d right) - { - Matrix3x2d result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix3x2d mat, out Matrix2x3d result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row0.Z = mat.Row2.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - result.Row1.Z = mat.Row2.Y; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix2x3d Transpose(Matrix3x2d mat) - { - Matrix2x3d result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2d which holds the result of the multiplication - public static Matrix3x2d operator *(double left, Matrix3x2d right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2d which holds the result of the multiplication - public static Matrix3x2d operator *(Matrix3x2d left, double right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2d which holds the result of the multiplication - public static Matrix3x2d operator *(Matrix3x2d left, Matrix2d right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3d which holds the result of the multiplication - public static Matrix3d operator *(Matrix3x2d left, Matrix2x3d right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4 which holds the result of the multiplication - public static Matrix3x4d operator *(Matrix3x2d left, Matrix2x4d right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2d which holds the result of the addition - public static Matrix3x2d operator +(Matrix3x2d left, Matrix3x2d right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x2d which holds the result of the subtraction - public static Matrix3x2d operator -(Matrix3x2d left, Matrix3x2d right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix3x2d left, Matrix3x2d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix3x2d left, Matrix3x2d right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix3d. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix3x2d)) - return false; - - return this.Equals((Matrix3x2d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix3x2d other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix3x4.cs b/OpenTK/Math/Matrix3x4.cs deleted file mode 100644 index 7d251d57..00000000 --- a/OpenTK/Math/Matrix3x4.cs +++ /dev/null @@ -1,1000 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 3x4 Matrix - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Matrix3x4 : IEquatable - { - #region Fields - - /// - /// Top row of the matrix - /// - public Vector4 Row0; - - /// - /// 2nd row of the matrix - /// - public Vector4 Row1; - - /// - /// Bottom row of the matrix - /// - public Vector4 Row2; - - /// - /// The zero matrix - /// - public static Matrix3x4 Zero = new Matrix3x4(Vector4.Zero, Vector4.Zero, Vector4.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix - /// Second row of the matrix - /// Bottom row of the matrix - public Matrix3x4(Vector4 row0, Vector4 row1, Vector4 row2) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - } - - /// - /// Constructs a new instance. - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// Fourth item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// Fourth item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// Third item of the third row of the matrix. - /// First item of the third row of the matrix. - public Matrix3x4( - float m00, float m01, float m02, float m03, - float m10, float m11, float m12, float m13, - float m20, float m21, float m22, float m23) - { - Row0 = new Vector4(m00, m01, m02, m03); - Row1 = new Vector4(m10, m11, m12, m13); - Row2 = new Vector4(m20, m21, m22, m23); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets the first column of this matrix. - /// - public Vector3 Column0 - { - get { return new Vector3(Row0.X, Row1.X, Row2.X); } - } - - /// - /// Gets the second column of this matrix. - /// - public Vector3 Column1 - { - get { return new Vector3(Row0.Y, Row1.Y, Row2.Y); } - } - - /// - /// Gets the third column of this matrix. - /// - public Vector3 Column2 - { - get { return new Vector3(Row0.Z, Row1.Z, Row2.Z); } - } - - /// - /// Gets the fourth column of this matrix. - /// - public Vector3 Column3 - { - get { return new Vector3(Row0.W, Row1.W, Row2.W); } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public float M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 1, column 4 of this instance. - /// - public float M14 { get { return Row0.W; } set { Row0.W = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public float M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 4 of this instance. - /// - public float M24 { get { return Row1.W; } set { Row1.W = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public float M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public float M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 3 of this instance. - /// - public float M33 { get { return Row2.Z; } set { Row2.Z = value; } } - - /// - /// Gets or sets the value at row 3, column 4 of this instance. - /// - public float M34 { get { return Row2.W; } set { Row2.W = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector3 Diagonal - { - get - { - return new Vector3(Row0.X, Row1.Y, Row2.Z); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - Row2.Z = value.Z; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public float Trace { get { return Row0.X + Row1.Y + Row2.Z; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public float this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - /// - public void Invert() - { - this = Matrix3x4.Invert(this); - } - - #endregion - - #endregion - - #region Static - - #region CreateFromAxisAngle - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix3x4 result) - { - axis.Normalize(); - float axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; - - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - float t = 1.0f - cos; - - float tXX = t * axisX * axisX, - tXY = t * axisX * axisY, - tXZ = t * axisX * axisZ, - tYY = t * axisY * axisY, - tYZ = t * axisY * axisZ, - tZZ = t * axisZ * axisZ; - - float sinX = sin * axisX, - sinY = sin * axisY, - sinZ = sin * axisZ; - - result.Row0.X = tXX + cos; - result.Row0.Y = tXY - sinZ; - result.Row0.Z = tXZ + sinY; - result.Row0.W = 0; - result.Row1.X = tXY + sinZ; - result.Row1.Y = tYY + cos; - result.Row1.Z = tYZ - sinX; - result.Row1.W = 0; - result.Row2.X = tXZ - sinY; - result.Row2.Y = tYZ + sinX; - result.Row2.Z = tZZ + cos; - result.Row2.W = 0; - } - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static Matrix3x4 CreateFromAxisAngle(Vector3 axis, float angle) - { - Matrix3x4 result; - CreateFromAxisAngle(axis, angle, out result); - return result; - } - - #endregion - - #region CreateFromQuaternion - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static void CreateFromQuaternion(ref Quaternion q, out Matrix3x4 result) - { - float x = q.X, y = q.Y, z = q.Z, w = q.W, - tx = 2 * x, ty = 2 * y, tz = 2 * z, - txx = tx * x, tyy = ty * y, tzz = tz * z, - txy = tx * y, txz = tx * z, tyz = ty * z, - txw = tx * w, tyw = ty * w, tzw = tz * w; - - result.Row0.X = 1f - (tyy + tzz); - result.Row0.Y = txy + tzw; - result.Row0.Z = txz - tyw; - result.Row0.W = 0f; - result.Row1.X = txy - tzw; - result.Row1.Y = 1f - (txx + tzz); - result.Row1.Z = tyz + txw; - result.Row1.W = 0f; - result.Row2.X = txz + tyw; - result.Row2.Y = tyz - txw; - result.Row2.Z = 1f - (txx + tyy); - result.Row2.W = 0f; - - /*Vector3 axis; - float angle; - q.ToAxisAngle(out axis, out angle); - CreateFromAxisAngle(axis, angle, out result);*/ - } - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static Matrix3x4 CreateFromQuaternion(Quaternion q) - { - Matrix3x4 result; - CreateFromQuaternion(ref q, out result); - return result; - } - - #endregion - - #region CreateRotation[XYZ] - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationX(float angle, out Matrix3x4 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = cos; - result.Row1.Z = sin; - result.Row1.W = 0; - result.Row2.X = 0; - result.Row2.Y = -sin; - result.Row2.Z = cos; - result.Row2.W = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix3x4 CreateRotationX(float angle) - { - Matrix3x4 result; - CreateRotationX(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationY(float angle, out Matrix3x4 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = 0; - result.Row0.Z = -sin; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row1.W = 0; - result.Row2.X = sin; - result.Row2.Y = 0; - result.Row2.Z = cos; - result.Row2.W = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix3x4 CreateRotationY(float angle) - { - Matrix3x4 result; - CreateRotationY(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationZ(float angle, out Matrix3x4 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row1.Z = 0; - result.Row1.W = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row2.W = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix3x4 CreateRotationZ(float angle) - { - Matrix3x4 result; - CreateRotationZ(angle, out result); - return result; - } - - #endregion - - #region CreateTranslation - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - public static void CreateTranslation(float x, float y, float z, out Matrix3x4 result) - { - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = x; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row1.W = y; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row2.W = z; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - public static void CreateTranslation(ref Vector3 vector, out Matrix3x4 result) - { - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = vector.X; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row1.W = vector.Y; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row2.W = vector.Z; - } - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - public static Matrix3x4 CreateTranslation(float x, float y, float z) - { - Matrix3x4 result; - CreateTranslation(x, y, z, out result); - return result; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - public static Matrix3x4 CreateTranslation(Vector3 vector) - { - Matrix3x4 result; - CreateTranslation(vector.X, vector.Y, vector.Z, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Build a scaling matrix - /// - /// Single scale factor for x,y and z axes - /// A scaling matrix - public static Matrix3x4 CreateScale(float scale) - { - return CreateScale(scale, scale, scale); - } - - /// - /// Build a scaling matrix - /// - /// Scale factors for x,y and z axes - /// A scaling matrix - public static Matrix3x4 CreateScale(Vector3 scale) - { - return CreateScale(scale.X, scale.Y, scale.Z); - } - - /// - /// Build a scaling matrix - /// - /// Scale factor for x-axis - /// Scale factor for y-axis - /// Scale factor for z-axis - /// A scaling matrix - public static Matrix3x4 CreateScale(float x, float y, float z) - { - Matrix3x4 result; - result.Row0.X = x; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row1.Z = 0; - result.Row1.W = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = z; - result.Row2.W = 0; - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix3 Mult(Matrix3x4 left, Matrix4x3 right) - { - Matrix3 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix3x4 left, ref Matrix4x3 right, out Matrix3 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31) + (lM14 * rM41); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32) + (lM14 * rM42); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33) + (lM14 * rM43); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31) + (lM24 * rM41); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32) + (lM24 * rM42); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33) + (lM24 * rM43); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31) + (lM34 * rM41); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32) + (lM34 * rM42); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33) + (lM34 * rM43); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix3x4 Mult(Matrix3x4 left, Matrix3x4 right) - { - Matrix3x4 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix3x4 left, ref Matrix3x4 right, out Matrix3x4 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24) + (lM13 * rM34) + lM14; - result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24) + (lM23 * rM34) + lM24; - result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33); - result.Row2.W = (lM31 * rM14) + (lM32 * rM24) + (lM33 * rM34) + lM34; - - /*result.Row0 = (right.Row0 * lM11 + right.Row1 * lM12 + right.Row2 * lM13); - result.Row0.W += lM14; - - result.Row1 = (right.Row0 * lM21 + right.Row1 * lM22 + right.Row2 * lM23); - result.Row1.W += lM24; - - result.Row2 = (right.Row0 * lM31 + right.Row1 * lM32 + right.Row2 * lM33); - result.Row2.W += lM34;*/ - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix3x4 Mult(Matrix3x4 left, float right) - { - Matrix3x4 result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix3x4 left, float right, out Matrix3x4 result) - { - result.Row0 = left.Row0 * right; - result.Row1 = left.Row1 * right; - result.Row2 = left.Row2 * right; - } - - #endregion - - #region Add Functions - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix3x4 Add(Matrix3x4 left, Matrix3x4 right) - { - Matrix3x4 result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix3x4 left, ref Matrix3x4 right, out Matrix3x4 result) - { - result.Row0 = left.Row0 + right.Row0; - result.Row1 = left.Row1 + right.Row1; - result.Row2 = left.Row2 + right.Row2; - } - - #endregion - - #region Subtract Functions - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static Matrix3x4 Subtract(Matrix3x4 left, Matrix3x4 right) - { - Matrix3x4 result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static void Subtract(ref Matrix3x4 left, ref Matrix3x4 right, out Matrix3x4 result) - { - result.Row0 = left.Row0 - right.Row0; - result.Row1 = left.Row1 - right.Row1; - result.Row2 = left.Row2 - right.Row2; - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static Matrix3x4 Invert(Matrix3x4 mat) - { - Matrix3x4 result; - Invert(ref mat, out result); - return result; - } - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static void Invert(ref Matrix3x4 mat, out Matrix3x4 result) - { - Matrix3 inverseRotation = new Matrix3(mat.Column0, mat.Column1, mat.Column2); - inverseRotation.Row0 /= inverseRotation.Row0.LengthSquared; - inverseRotation.Row1 /= inverseRotation.Row1.LengthSquared; - inverseRotation.Row2 /= inverseRotation.Row2.LengthSquared; - - Vector3 translation = new Vector3(mat.Row0.W, mat.Row1.W, mat.Row2.W); - - result.Row0 = new Vector4(inverseRotation.Row0, -Vector3.Dot(inverseRotation.Row0, translation)); - result.Row1 = new Vector4(inverseRotation.Row1, -Vector3.Dot(inverseRotation.Row1, translation)); - result.Row2 = new Vector4(inverseRotation.Row2, -Vector3.Dot(inverseRotation.Row2, translation)); - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The transpose of the given matrix - public static Matrix4x3 Transpose(Matrix3x4 mat) - { - return new Matrix4x3(mat.Column0, mat.Column1, mat.Column2, mat.Column3); - } - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The result of the calculation - public static void Transpose(ref Matrix3x4 mat, out Matrix4x3 result) - { - result.Row0 = mat.Column0; - result.Row1 = mat.Column1; - result.Row2 = mat.Column2; - result.Row3 = mat.Column3; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3 which holds the result of the multiplication - public static Matrix3 operator *(Matrix3x4 left, Matrix4x3 right) - { - return Matrix3x4.Mult(left, right); - } - - /// - /// Matrix-scalar multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4 which holds the result of the multiplication - public static Matrix3x4 operator *(Matrix3x4 left, Matrix3x4 right) - { - return Matrix3x4.Mult(left, right); - } - - /// - /// Matrix-scalar multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4 which holds the result of the multiplication - public static Matrix3x4 operator *(Matrix3x4 left, float right) - { - return Matrix3x4.Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4 which holds the result of the addition - public static Matrix3x4 operator +(Matrix3x4 left, Matrix3x4 right) - { - return Matrix3x4.Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4 which holds the result of the subtraction - public static Matrix3x4 operator -(Matrix3x4 left, Matrix3x4 right) - { - return Matrix3x4.Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix3x4 left, Matrix3x4 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix3x4 left, Matrix3x4 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix4. - /// - /// The string representation of the matrix. - public override string ToString() - { - return string.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix3x4)) - return false; - - return this.Equals((Matrix3x4)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix3x4 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix3x4d.cs b/OpenTK/Math/Matrix3x4d.cs deleted file mode 100644 index fa37cfc8..00000000 --- a/OpenTK/Math/Matrix3x4d.cs +++ /dev/null @@ -1,1000 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 3x4 Matrix - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Matrix3x4d : IEquatable - { - #region Fields - - /// - /// Top row of the matrix - /// - public Vector4d Row0; - - /// - /// 2nd row of the matrix - /// - public Vector4d Row1; - - /// - /// Bottom row of the matrix - /// - public Vector4d Row2; - - /// - /// The zero matrix - /// - public static Matrix3x4d Zero = new Matrix3x4d(Vector4d.Zero, Vector4d.Zero, Vector4d.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix - /// Second row of the matrix - /// Bottom row of the matrix - public Matrix3x4d(Vector4d row0, Vector4d row1, Vector4d row2) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - } - - /// - /// Constructs a new instance. - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// Fourth item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// Fourth item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// Third item of the third row of the matrix. - /// First item of the third row of the matrix. - public Matrix3x4d( - double m00, double m01, double m02, double m03, - double m10, double m11, double m12, double m13, - double m20, double m21, double m22, double m23) - { - Row0 = new Vector4d(m00, m01, m02, m03); - Row1 = new Vector4d(m10, m11, m12, m13); - Row2 = new Vector4d(m20, m21, m22, m23); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets the first column of this matrix. - /// - public Vector3d Column0 - { - get { return new Vector3d(Row0.X, Row1.X, Row2.X); } - } - - /// - /// Gets the second column of this matrix. - /// - public Vector3d Column1 - { - get { return new Vector3d(Row0.Y, Row1.Y, Row2.Y); } - } - - /// - /// Gets the third column of this matrix. - /// - public Vector3d Column2 - { - get { return new Vector3d(Row0.Z, Row1.Z, Row2.Z); } - } - - /// - /// Gets the fourth column of this matrix. - /// - public Vector3d Column3 - { - get { return new Vector3d(Row0.W, Row1.W, Row2.W); } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public double M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public double M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 1, column 4 of this instance. - /// - public double M14 { get { return Row0.W; } set { Row0.W = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public double M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public double M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 4 of this instance. - /// - public double M24 { get { return Row1.W; } set { Row1.W = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public double M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public double M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 3 of this instance. - /// - public double M33 { get { return Row2.Z; } set { Row2.Z = value; } } - - /// - /// Gets or sets the value at row 3, column 4 of this instance. - /// - public double M34 { get { return Row2.W; } set { Row2.W = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector3d Diagonal - { - get - { - return new Vector3d(Row0.X, Row1.Y, Row2.Z); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - Row2.Z = value.Z; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public double Trace { get { return Row0.X + Row1.Y + Row2.Z; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public double this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - /// - public void Invert() - { - this = Matrix3x4d.Invert(this); - } - - #endregion - - #endregion - - #region Static - - #region CreateFromAxisAngle - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static void CreateFromAxisAngle(Vector3d axis, double angle, out Matrix3x4d result) - { - axis.Normalize(); - double axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; - - double cos = (double)System.Math.Cos(angle); - double sin = (double)System.Math.Sin(angle); - double t = 1.0f - cos; - - double tXX = t * axisX * axisX, - tXY = t * axisX * axisY, - tXZ = t * axisX * axisZ, - tYY = t * axisY * axisY, - tYZ = t * axisY * axisZ, - tZZ = t * axisZ * axisZ; - - double sinX = sin * axisX, - sinY = sin * axisY, - sinZ = sin * axisZ; - - result.Row0.X = tXX + cos; - result.Row0.Y = tXY - sinZ; - result.Row0.Z = tXZ + sinY; - result.Row0.W = 0; - result.Row1.X = tXY + sinZ; - result.Row1.Y = tYY + cos; - result.Row1.Z = tYZ - sinX; - result.Row1.W = 0; - result.Row2.X = tXZ - sinY; - result.Row2.Y = tYZ + sinX; - result.Row2.Z = tZZ + cos; - result.Row2.W = 0; - } - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static Matrix3x4d CreateFromAxisAngle(Vector3d axis, double angle) - { - Matrix3x4d result; - CreateFromAxisAngle(axis, angle, out result); - return result; - } - - #endregion - - #region CreateFromQuaternion - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static void CreateFromQuaternion(ref Quaternion q, out Matrix3x4d result) - { - double x = q.X, y = q.Y, z = q.Z, w = q.W, - tx = 2 * x, ty = 2 * y, tz = 2 * z, - txx = tx * x, tyy = ty * y, tzz = tz * z, - txy = tx * y, txz = tx * z, tyz = ty * z, - txw = tx * w, tyw = ty * w, tzw = tz * w; - - result.Row0.X = 1f - (tyy + tzz); - result.Row0.Y = txy + tzw; - result.Row0.Z = txz - tyw; - result.Row0.W = 0f; - result.Row1.X = txy - tzw; - result.Row1.Y = 1f - (txx + tzz); - result.Row1.Z = tyz + txw; - result.Row1.W = 0f; - result.Row2.X = txz + tyw; - result.Row2.Y = tyz - txw; - result.Row2.Z = 1f - (txx + tyy); - result.Row2.W = 0f; - - /*Vector3d axis; - double angle; - q.ToAxisAngle(out axis, out angle); - CreateFromAxisAngle(axis, angle, out result);*/ - } - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static Matrix3x4d CreateFromQuaternion(Quaternion q) - { - Matrix3x4d result; - CreateFromQuaternion(ref q, out result); - return result; - } - - #endregion - - #region CreateRotation[XYZ] - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationX(double angle, out Matrix3x4d result) - { - double cos = (double)System.Math.Cos(angle); - double sin = (double)System.Math.Sin(angle); - - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = cos; - result.Row1.Z = sin; - result.Row1.W = 0; - result.Row2.X = 0; - result.Row2.Y = -sin; - result.Row2.Z = cos; - result.Row2.W = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix3x4d CreateRotationX(double angle) - { - Matrix3x4d result; - CreateRotationX(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationY(double angle, out Matrix3x4d result) - { - double cos = (double)System.Math.Cos(angle); - double sin = (double)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = 0; - result.Row0.Z = -sin; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row1.W = 0; - result.Row2.X = sin; - result.Row2.Y = 0; - result.Row2.Z = cos; - result.Row2.W = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix3x4d CreateRotationY(double angle) - { - Matrix3x4d result; - CreateRotationY(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationZ(double angle, out Matrix3x4d result) - { - double cos = (double)System.Math.Cos(angle); - double sin = (double)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row1.Z = 0; - result.Row1.W = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row2.W = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix3x4d CreateRotationZ(double angle) - { - Matrix3x4d result; - CreateRotationZ(angle, out result); - return result; - } - - #endregion - - #region CreateTranslation - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - public static void CreateTranslation(double x, double y, double z, out Matrix3x4d result) - { - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = x; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row1.W = y; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row2.W = z; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - public static void CreateTranslation(ref Vector3d vector, out Matrix3x4d result) - { - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = vector.X; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row1.W = vector.Y; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row2.W = vector.Z; - } - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - public static Matrix3x4d CreateTranslation(double x, double y, double z) - { - Matrix3x4d result; - CreateTranslation(x, y, z, out result); - return result; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - public static Matrix3x4d CreateTranslation(Vector3d vector) - { - Matrix3x4d result; - CreateTranslation(vector.X, vector.Y, vector.Z, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Build a scaling matrix - /// - /// Single scale factor for x,y and z axes - /// A scaling matrix - public static Matrix3x4d CreateScale(double scale) - { - return CreateScale(scale, scale, scale); - } - - /// - /// Build a scaling matrix - /// - /// Scale factors for x,y and z axes - /// A scaling matrix - public static Matrix3x4d CreateScale(Vector3d scale) - { - return CreateScale(scale.X, scale.Y, scale.Z); - } - - /// - /// Build a scaling matrix - /// - /// Scale factor for x-axis - /// Scale factor for y-axis - /// Scale factor for z-axis - /// A scaling matrix - public static Matrix3x4d CreateScale(double x, double y, double z) - { - Matrix3x4d result; - result.Row0.X = x; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row1.Z = 0; - result.Row1.W = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = z; - result.Row2.W = 0; - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix3d Mult(Matrix3x4d left, Matrix4x3d right) - { - Matrix3d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix3x4d left, ref Matrix4x3d right, out Matrix3d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31) + (lM14 * rM41); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32) + (lM14 * rM42); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33) + (lM14 * rM43); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31) + (lM24 * rM41); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32) + (lM24 * rM42); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33) + (lM24 * rM43); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31) + (lM34 * rM41); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32) + (lM34 * rM42); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33) + (lM34 * rM43); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix3x4d Mult(Matrix3x4d left, Matrix3x4d right) - { - Matrix3x4d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix3x4d left, ref Matrix3x4d right, out Matrix3x4d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24) + (lM13 * rM34) + lM14; - result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24) + (lM23 * rM34) + lM24; - result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33); - result.Row2.W = (lM31 * rM14) + (lM32 * rM24) + (lM33 * rM34) + lM34; - - /*result.Row0 = (right.Row0 * lM11 + right.Row1 * lM12 + right.Row2 * lM13); - result.Row0.W += lM14; - - result.Row1 = (right.Row0 * lM21 + right.Row1 * lM22 + right.Row2 * lM23); - result.Row1.W += lM24; - - result.Row2 = (right.Row0 * lM31 + right.Row1 * lM32 + right.Row2 * lM33); - result.Row2.W += lM34;*/ - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix3x4d Mult(Matrix3x4d left, double right) - { - Matrix3x4d result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix3x4d left, double right, out Matrix3x4d result) - { - result.Row0 = left.Row0 * right; - result.Row1 = left.Row1 * right; - result.Row2 = left.Row2 * right; - } - - #endregion - - #region Add Functions - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix3x4d Add(Matrix3x4d left, Matrix3x4d right) - { - Matrix3x4d result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix3x4d left, ref Matrix3x4d right, out Matrix3x4d result) - { - result.Row0 = left.Row0 + right.Row0; - result.Row1 = left.Row1 + right.Row1; - result.Row2 = left.Row2 + right.Row2; - } - - #endregion - - #region Subtract Functions - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static Matrix3x4d Subtract(Matrix3x4d left, Matrix3x4d right) - { - Matrix3x4d result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static void Subtract(ref Matrix3x4d left, ref Matrix3x4d right, out Matrix3x4d result) - { - result.Row0 = left.Row0 - right.Row0; - result.Row1 = left.Row1 - right.Row1; - result.Row2 = left.Row2 - right.Row2; - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static Matrix3x4d Invert(Matrix3x4d mat) - { - Matrix3x4d result; - Invert(ref mat, out result); - return result; - } - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static void Invert(ref Matrix3x4d mat, out Matrix3x4d result) - { - Matrix3d inverseRotation = new Matrix3d(mat.Column0, mat.Column1, mat.Column2); - inverseRotation.Row0 /= inverseRotation.Row0.LengthSquared; - inverseRotation.Row1 /= inverseRotation.Row1.LengthSquared; - inverseRotation.Row2 /= inverseRotation.Row2.LengthSquared; - - Vector3d translation = new Vector3d(mat.Row0.W, mat.Row1.W, mat.Row2.W); - - result.Row0 = new Vector4d(inverseRotation.Row0, -Vector3d.Dot(inverseRotation.Row0, translation)); - result.Row1 = new Vector4d(inverseRotation.Row1, -Vector3d.Dot(inverseRotation.Row1, translation)); - result.Row2 = new Vector4d(inverseRotation.Row2, -Vector3d.Dot(inverseRotation.Row2, translation)); - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The transpose of the given matrix - public static Matrix4x3d Transpose(Matrix3x4d mat) - { - return new Matrix4x3d(mat.Column0, mat.Column1, mat.Column2, mat.Column3); - } - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The result of the calculation - public static void Transpose(ref Matrix3x4d mat, out Matrix4x3d result) - { - result.Row0 = mat.Column0; - result.Row1 = mat.Column1; - result.Row2 = mat.Column2; - result.Row3 = mat.Column3; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3d which holds the result of the multiplication - public static Matrix3d operator *(Matrix3x4d left, Matrix4x3d right) - { - return Matrix3x4d.Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4d which holds the result of the multiplication - public static Matrix3x4d operator *(Matrix3x4d left, Matrix3x4d right) - { - return Matrix3x4d.Mult(left, right); - } - - /// - /// Matrix-scalar multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4d which holds the result of the multiplication - public static Matrix3x4d operator *(Matrix3x4d left, double right) - { - return Matrix3x4d.Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4d which holds the result of the addition - public static Matrix3x4d operator +(Matrix3x4d left, Matrix3x4d right) - { - return Matrix3x4d.Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix3x4d which holds the result of the subtraction - public static Matrix3x4d operator -(Matrix3x4d left, Matrix3x4d right) - { - return Matrix3x4d.Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix3x4d left, Matrix3x4d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix3x4d left, Matrix3x4d right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix4. - /// - /// The string representation of the matrix. - public override string ToString() - { - return string.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix3x4d)) - return false; - - return this.Equals((Matrix3x4d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix3x4d other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix4.cs b/OpenTK/Math/Matrix4.cs deleted file mode 100644 index 198bf708..00000000 --- a/OpenTK/Math/Matrix4.cs +++ /dev/null @@ -1,1736 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 4x4 matrix containing 3D rotation, scale, transform, and projection. - /// - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Matrix4 : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector4 Row0; - - /// - /// 2nd row of the matrix. - /// - public Vector4 Row1; - - /// - /// 3rd row of the matrix. - /// - public Vector4 Row2; - - /// - /// Bottom row of the matrix. - /// - public Vector4 Row3; - - /// - /// The identity matrix. - /// - public static readonly Matrix4 Identity = new Matrix4(Vector4.UnitX, Vector4.UnitY, Vector4.UnitZ, Vector4.UnitW); - - /// - /// The zero matrix. - /// - public static readonly Matrix4 Zero = new Matrix4(Vector4.Zero, Vector4.Zero, Vector4.Zero, Vector4.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Second row of the matrix. - /// Third row of the matrix. - /// Bottom row of the matrix. - public Matrix4(Vector4 row0, Vector4 row1, Vector4 row2, Vector4 row3) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - Row3 = row3; - } - - /// - /// Constructs a new instance. - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// Fourth item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// Fourth item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// Third item of the third row of the matrix. - /// First item of the third row of the matrix. - /// Fourth item of the fourth row of the matrix. - /// Second item of the fourth row of the matrix. - /// Third item of the fourth row of the matrix. - /// Fourth item of the fourth row of the matrix. - public Matrix4( - float m00, float m01, float m02, float m03, - float m10, float m11, float m12, float m13, - float m20, float m21, float m22, float m23, - float m30, float m31, float m32, float m33) - { - Row0 = new Vector4(m00, m01, m02, m03); - Row1 = new Vector4(m10, m11, m12, m13); - Row2 = new Vector4(m20, m21, m22, m23); - Row3 = new Vector4(m30, m31, m32, m33); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets the determinant of this matrix. - /// - public float Determinant - { - get - { - float m11 = Row0.X, m12 = Row0.Y, m13 = Row0.Z, m14 = Row0.W, - m21 = Row1.X, m22 = Row1.Y, m23 = Row1.Z, m24 = Row1.W, - m31 = Row2.X, m32 = Row2.Y, m33 = Row2.Z, m34 = Row2.W, - m41 = Row3.X, m42 = Row3.Y, m43 = Row3.Z, m44 = Row3.W; - - return - m11 * m22 * m33 * m44 - m11 * m22 * m34 * m43 + m11 * m23 * m34 * m42 - m11 * m23 * m32 * m44 - + m11 * m24 * m32 * m43 - m11 * m24 * m33 * m42 - m12 * m23 * m34 * m41 + m12 * m23 * m31 * m44 - - m12 * m24 * m31 * m43 + m12 * m24 * m33 * m41 - m12 * m21 * m33 * m44 + m12 * m21 * m34 * m43 - + m13 * m24 * m31 * m42 - m13 * m24 * m32 * m41 + m13 * m21 * m32 * m44 - m13 * m21 * m34 * m42 - + m13 * m22 * m34 * m41 - m13 * m22 * m31 * m44 - m14 * m21 * m32 * m43 + m14 * m21 * m33 * m42 - - m14 * m22 * m33 * m41 + m14 * m22 * m31 * m43 - m14 * m23 * m31 * m42 + m14 * m23 * m32 * m41; - } - } - - /// - /// Gets the first column of this matrix. - /// - public Vector4 Column0 - { - get { return new Vector4(Row0.X, Row1.X, Row2.X, Row3.X); } - set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; Row3.X = value.W; } - } - - /// - /// Gets the second column of this matrix. - /// - public Vector4 Column1 - { - get { return new Vector4(Row0.Y, Row1.Y, Row2.Y, Row3.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; Row3.Y = value.W; } - } - - /// - /// Gets the third column of this matrix. - /// - public Vector4 Column2 - { - get { return new Vector4(Row0.Z, Row1.Z, Row2.Z, Row3.Z); } - set { Row0.Z = value.X; Row1.Z = value.Y; Row2.Z = value.Z; Row3.Z = value.W; } - } - - /// - /// Gets the fourth column of this matrix. - /// - public Vector4 Column3 - { - get { return new Vector4(Row0.W, Row1.W, Row2.W, Row3.W); } - set { Row0.W = value.X; Row1.W = value.Y; Row2.W = value.Z; Row3.W = value.W; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public float M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 1, column 4 of this instance. - /// - public float M14 { get { return Row0.W; } set { Row0.W = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public float M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 4 of this instance. - /// - public float M24 { get { return Row1.W; } set { Row1.W = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public float M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public float M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 3 of this instance. - /// - public float M33 { get { return Row2.Z; } set { Row2.Z = value; } } - - /// - /// Gets or sets the value at row 3, column 4 of this instance. - /// - public float M34 { get { return Row2.W; } set { Row2.W = value; } } - - /// - /// Gets or sets the value at row 4, column 1 of this instance. - /// - public float M41 { get { return Row3.X; } set { Row3.X = value; } } - - /// - /// Gets or sets the value at row 4, column 2 of this instance. - /// - public float M42 { get { return Row3.Y; } set { Row3.Y = value; } } - - /// - /// Gets or sets the value at row 4, column 3 of this instance. - /// - public float M43 { get { return Row3.Z; } set { Row3.Z = value; } } - - /// - /// Gets or sets the value at row 4, column 4 of this instance. - /// - public float M44 { get { return Row3.W; } set { Row3.W = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector4 Diagonal - { - get - { - return new Vector4(Row0.X, Row1.Y, Row2.Z, Row3.W); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - Row2.Z = value.Z; - Row3.W = value.W; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public float Trace { get { return Row0.X + Row1.Y + Row2.Z + Row3.W; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public float this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - else if (rowIndex == 3) return Row3[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else if (rowIndex == 3) Row3[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - /// - public void Invert() - { - this = Matrix4.Invert(this); - } - - #endregion - - #region public void Transpose() - - /// - /// Converts this instance into its transpose. - /// - public void Transpose() - { - this = Matrix4.Transpose(this); - } - - #endregion - - /// - /// Returns a normalised copy of this instance. - /// - public Matrix4 Normalized() - { - Matrix4 m = this; - m.Normalize(); - return m; - } - - /// - /// Divides each element in the Matrix by the . - /// - public void Normalize() - { - var determinant = this.Determinant; - Row0 /= determinant; - Row1 /= determinant; - Row2 /= determinant; - Row3 /= determinant; - } - - /// - /// Returns an inverted copy of this instance. - /// - public Matrix4 Inverted() - { - Matrix4 m = this; - if (m.Determinant != 0) - m.Invert(); - return m; - } - - /// - /// Returns a copy of this Matrix4 without translation. - /// - public Matrix4 ClearTranslation() - { - Matrix4 m = this; - m.Row3.Xyz = Vector3.Zero; - return m; - } - /// - /// Returns a copy of this Matrix4 without scale. - /// - public Matrix4 ClearScale() - { - Matrix4 m = this; - m.Row0.Xyz = m.Row0.Xyz.Normalized(); - m.Row1.Xyz = m.Row1.Xyz.Normalized(); - m.Row2.Xyz = m.Row2.Xyz.Normalized(); - return m; - } - /// - /// Returns a copy of this Matrix4 without rotation. - /// - public Matrix4 ClearRotation() - { - Matrix4 m = this; - m.Row0.Xyz = new Vector3(m.Row0.Xyz.Length, 0, 0); - m.Row1.Xyz = new Vector3(0, m.Row1.Xyz.Length, 0); - m.Row2.Xyz = new Vector3(0, 0, m.Row2.Xyz.Length); - return m; - } - /// - /// Returns a copy of this Matrix4 without projection. - /// - public Matrix4 ClearProjection() - { - Matrix4 m = this; - m.Column3 = Vector4.Zero; - return m; - } - - /// - /// Returns the translation component of this instance. - /// - public Vector3 ExtractTranslation() { return Row3.Xyz; } - - /// - /// Returns the scale component of this instance. - /// - public Vector3 ExtractScale() { return new Vector3(Row0.Xyz.Length, Row1.Xyz.Length, Row2.Xyz.Length); } - - /// - /// Returns the rotation component of this instance. Quite slow. - /// - /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised. - public Quaternion ExtractRotation(bool row_normalise = true) - { - var row0 = Row0.Xyz; - var row1 = Row1.Xyz; - var row2 = Row2.Xyz; - - if (row_normalise) - { - row0 = row0.Normalized(); - row1 = row1.Normalized(); - row2 = row2.Normalized(); - } - - // code below adapted from Blender - - Quaternion q = new Quaternion(); - double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0); - - if (trace > 1e-4) - { - double sq = Math.Sqrt(trace); - - q.W = (float)sq; - sq = 1.0 / (4.0 * sq); - q.X = (float)((row1[2] - row2[1]) * sq); - q.Y = (float)((row2[0] - row0[2]) * sq); - q.Z = (float)((row0[1] - row1[0]) * sq); - } - else if (row0[0] > row1[1] && row0[0] > row2[2]) - { - double sq = 2.0 * Math.Sqrt(1.0 + row0[0] - row1[1] - row2[2]); - - q.X = (float)(0.25 * sq); - sq = 1.0 / sq; - q.W = (float)((row1[2] - row2[1]) * sq); - q.Y = (float)((row1[0] + row0[1]) * sq); - q.Z = (float)((row2[0] + row0[2]) * sq); - } - else if (row1[1] > row2[2]) - { - double sq = 2.0 * Math.Sqrt(1.0 + row1[1] - row0[0] - row2[2]); - - q.Y = (float)(0.25 * sq); - sq = 1.0 / sq; - q.W = (float)((row2[0] - row0[2]) * sq); - q.X = (float)((row1[0] + row0[1]) * sq); - q.Z = (float)((row2[1] + row1[2]) * sq); - } - else - { - double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]); - - q.Z = (float)(0.25 * sq); - sq = 1.0 / sq; - q.W = (float)((row0[1] - row1[0]) * sq); - q.X = (float)((row2[0] + row0[2]) * sq); - q.Y = (float)((row2[1] + row1[2]) * sq); - } - - q.Normalize(); - return q; - } - - /// - /// Returns the projection component of this instance. - /// - public Vector4 ExtractProjection() - { - return Column3; - } - - #endregion - - #region Static - - #region CreateFromAxisAngle - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix4 result) - { - // normalize and create a local copy of the vector. - axis.Normalize(); - float axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; - - // calculate angles - float cos = (float)System.Math.Cos(-angle); - float sin = (float)System.Math.Sin(-angle); - float t = 1.0f - cos; - - // do the conversion math once - float tXX = t * axisX * axisX, - tXY = t * axisX * axisY, - tXZ = t * axisX * axisZ, - tYY = t * axisY * axisY, - tYZ = t * axisY * axisZ, - tZZ = t * axisZ * axisZ; - - float sinX = sin * axisX, - sinY = sin * axisY, - sinZ = sin * axisZ; - - result.Row0.X = tXX + cos; - result.Row0.Y = tXY - sinZ; - result.Row0.Z = tXZ + sinY; - result.Row0.W = 0; - result.Row1.X = tXY + sinZ; - result.Row1.Y = tYY + cos; - result.Row1.Z = tYZ - sinX; - result.Row1.W = 0; - result.Row2.X = tXZ - sinY; - result.Row2.Y = tYZ + sinX; - result.Row2.Z = tZZ + cos; - result.Row2.W = 0; - result.Row3 = Vector4.UnitW; - } - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static Matrix4 CreateFromAxisAngle(Vector3 axis, float angle) - { - Matrix4 result; - CreateFromAxisAngle(axis, angle, out result); - return result; - } - - #endregion - - #region CreateFromQuaternion - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static void CreateFromQuaternion(ref Quaternion q, out Matrix4 result) - { - Vector3 axis; - float angle; - q.ToAxisAngle(out axis, out angle); - CreateFromAxisAngle(axis, angle, out result); - } - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static Matrix4 CreateFromQuaternion(Quaternion q) - { - Matrix4 result; - CreateFromQuaternion(ref q, out result); - return result; - } - - #endregion - - #region CreateRotation[XYZ] - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationX(float angle, out Matrix4 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result = Identity; - result.Row1.Y = cos; - result.Row1.Z = sin; - result.Row2.Y = -sin; - result.Row2.Z = cos; - } - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix4 CreateRotationX(float angle) - { - Matrix4 result; - CreateRotationX(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationY(float angle, out Matrix4 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result = Identity; - result.Row0.X = cos; - result.Row0.Z = -sin; - result.Row2.X = sin; - result.Row2.Z = cos; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix4 CreateRotationY(float angle) - { - Matrix4 result; - CreateRotationY(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationZ(float angle, out Matrix4 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result = Identity; - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row1.X = -sin; - result.Row1.Y = cos; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix4 CreateRotationZ(float angle) - { - Matrix4 result; - CreateRotationZ(angle, out result); - return result; - } - - #endregion - - #region CreateTranslation - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - public static void CreateTranslation(float x, float y, float z, out Matrix4 result) - { - result = Identity; - result.Row3.X = x; - result.Row3.Y = y; - result.Row3.Z = z; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - public static void CreateTranslation(ref Vector3 vector, out Matrix4 result) - { - result = Identity; - result.Row3.X = vector.X; - result.Row3.Y = vector.Y; - result.Row3.Z = vector.Z; - } - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - public static Matrix4 CreateTranslation(float x, float y, float z) - { - Matrix4 result; - CreateTranslation(x, y, z, out result); - return result; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - public static Matrix4 CreateTranslation(Vector3 vector) - { - Matrix4 result; - CreateTranslation(vector.X, vector.Y, vector.Z, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static Matrix4 CreateScale(float scale) - { - Matrix4 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x, y, and z axes. - /// A scale matrix. - public static Matrix4 CreateScale(Vector3 scale) - { - Matrix4 result; - CreateScale(ref scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// Scale factor for the z axis. - /// A scale matrix. - public static Matrix4 CreateScale(float x, float y, float z) - { - Matrix4 result; - CreateScale(x, y, z, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(float scale, out Matrix4 result) - { - result = Identity; - result.Row0.X = scale; - result.Row1.Y = scale; - result.Row2.Z = scale; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(ref Vector3 scale, out Matrix4 result) - { - result = Identity; - result.Row0.X = scale.X; - result.Row1.Y = scale.Y; - result.Row2.Z = scale.Z; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// Scale factor for the z axis. - /// A scale matrix. - public static void CreateScale(float x, float y, float z, out Matrix4 result) - { - result = Identity; - result.Row0.X = x; - result.Row1.Y = y; - result.Row2.Z = z; - } - - #endregion - - #region CreateOrthographic - - /// - /// Creates an orthographic projection matrix. - /// - /// The width of the projection volume. - /// The height of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4 instance. - public static void CreateOrthographic(float width, float height, float zNear, float zFar, out Matrix4 result) - { - CreateOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, zNear, zFar, out result); - } - - /// - /// Creates an orthographic projection matrix. - /// - /// The width of the projection volume. - /// The height of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4 instance. - public static Matrix4 CreateOrthographic(float width, float height, float zNear, float zFar) - { - Matrix4 result; - CreateOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, zNear, zFar, out result); - return result; - } - - #endregion - - #region CreateOrthographicOffCenter - - /// - /// Creates an orthographic projection matrix. - /// - /// The left edge of the projection volume. - /// The right edge of the projection volume. - /// The bottom edge of the projection volume. - /// The top edge of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4 instance. - public static void CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, out Matrix4 result) - { - result = Identity; - - float invRL = 1.0f / (right - left); - float invTB = 1.0f / (top - bottom); - float invFN = 1.0f / (zFar - zNear); - - result.Row0.X = 2 * invRL; - result.Row1.Y = 2 * invTB; - result.Row2.Z = -2 * invFN; - - result.Row3.X = -(right + left) * invRL; - result.Row3.Y = -(top + bottom) * invTB; - result.Row3.Z = -(zFar + zNear) * invFN; - } - - /// - /// Creates an orthographic projection matrix. - /// - /// The left edge of the projection volume. - /// The right edge of the projection volume. - /// The bottom edge of the projection volume. - /// The top edge of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4 instance. - public static Matrix4 CreateOrthographicOffCenter(float left, float right, float bottom, float top, float zNear, float zFar) - { - Matrix4 result; - CreateOrthographicOffCenter(left, right, bottom, top, zNear, zFar, out result); - return result; - } - - #endregion - - #region CreatePerspectiveFieldOfView - - /// - /// Creates a perspective projection matrix. - /// - /// Angle of the field of view in the y direction (in radians) - /// Aspect ratio of the view (width / height) - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// fovy is zero, less than zero or larger than Math.PI - /// aspect is negative or zero - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - public static void CreatePerspectiveFieldOfView(float fovy, float aspect, float zNear, float zFar, out Matrix4 result) - { - if (fovy <= 0 || fovy > Math.PI) - throw new ArgumentOutOfRangeException("fovy"); - if (aspect <= 0) - throw new ArgumentOutOfRangeException("aspect"); - if (zNear <= 0) - throw new ArgumentOutOfRangeException("zNear"); - if (zFar <= 0) - throw new ArgumentOutOfRangeException("zFar"); - - float yMax = zNear * (float)System.Math.Tan(0.5f * fovy); - float yMin = -yMax; - float xMin = yMin * aspect; - float xMax = yMax * aspect; - - CreatePerspectiveOffCenter(xMin, xMax, yMin, yMax, zNear, zFar, out result); - } - - /// - /// Creates a perspective projection matrix. - /// - /// Angle of the field of view in the y direction (in radians) - /// Aspect ratio of the view (width / height) - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// fovy is zero, less than zero or larger than Math.PI - /// aspect is negative or zero - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - public static Matrix4 CreatePerspectiveFieldOfView(float fovy, float aspect, float zNear, float zFar) - { - Matrix4 result; - CreatePerspectiveFieldOfView(fovy, aspect, zNear, zFar, out result); - return result; - } - - #endregion - - #region CreatePerspectiveOffCenter - - /// - /// Creates an perspective projection matrix. - /// - /// Left edge of the view frustum - /// Right edge of the view frustum - /// Bottom edge of the view frustum - /// Top edge of the view frustum - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - public static void CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float zNear, float zFar, out Matrix4 result) - { - if (zNear <= 0) - throw new ArgumentOutOfRangeException("zNear"); - if (zFar <= 0) - throw new ArgumentOutOfRangeException("zFar"); - if (zNear >= zFar) - throw new ArgumentOutOfRangeException("zNear"); - - float x = (2.0f * zNear) / (right - left); - float y = (2.0f * zNear) / (top - bottom); - float a = (right + left) / (right - left); - float b = (top + bottom) / (top - bottom); - float c = -(zFar + zNear) / (zFar - zNear); - float d = -(2.0f * zFar * zNear) / (zFar - zNear); - - result.Row0.X = x; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row0.W = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row1.Z = 0; - result.Row1.W = 0; - result.Row2.X = a; - result.Row2.Y = b; - result.Row2.Z = c; - result.Row2.W = -1; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = d; - result.Row3.W = 0; - } - - /// - /// Creates an perspective projection matrix. - /// - /// Left edge of the view frustum - /// Right edge of the view frustum - /// Bottom edge of the view frustum - /// Top edge of the view frustum - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - public static Matrix4 CreatePerspectiveOffCenter(float left, float right, float bottom, float top, float zNear, float zFar) - { - Matrix4 result; - CreatePerspectiveOffCenter(left, right, bottom, top, zNear, zFar, out result); - return result; - } - - #endregion - - #region Obsolete Functions - - #region Translation Functions - - /// - /// Builds a translation matrix. - /// - /// The translation vector. - /// A new Matrix4 instance. - [Obsolete("Use CreateTranslation instead.")] - public static Matrix4 Translation(Vector3 trans) - { - return CreateTranslation(trans); - } - - /// - /// Build a translation matrix with the given translation - /// - /// X translation - /// Y translation - /// Z translation - /// A Translation matrix - [Obsolete("Use CreateTranslation instead.")] - public static Matrix4 Translation(float x, float y, float z) - { - return CreateTranslation(x, y, z); - } - - #endregion - - #region Rotation Functions - - /// - /// Build a rotation matrix that rotates about the x-axis - /// - /// angle in radians to rotate counter-clockwise around the x-axis - /// A rotation matrix - [Obsolete("Use CreateRotationX instead.")] - public static Matrix4 RotateX(float angle) - { - return CreateRotationX(angle); - } - - /// - /// Build a rotation matrix that rotates about the y-axis - /// - /// angle in radians to rotate counter-clockwise around the y-axis - /// A rotation matrix - [Obsolete("Use CreateRotationY instead.")] - public static Matrix4 RotateY(float angle) - { - return CreateRotationY(angle); - } - - /// - /// Build a rotation matrix that rotates about the z-axis - /// - /// angle in radians to rotate counter-clockwise around the z-axis - /// A rotation matrix - [Obsolete("Use CreateRotationZ instead.")] - public static Matrix4 RotateZ(float angle) - { - return CreateRotationZ(angle); - } - - /// - /// Build a rotation matrix to rotate about the given axis - /// - /// the axis to rotate about - /// angle in radians to rotate counter-clockwise (looking in the direction of the given axis) - /// A rotation matrix - [Obsolete("Use CreateFromAxisAngle instead.")] - public static Matrix4 Rotate(Vector3 axis, float angle) - { - return CreateFromAxisAngle(axis, angle); - } - - /// - /// Build a rotation matrix from a quaternion - /// - /// the quaternion - /// A rotation matrix - [Obsolete("Use CreateRotation instead.")] - public static Matrix4 Rotate(Quaternion q) - { - return CreateFromQuaternion(q); - } - - #endregion - - #region Scale Functions - - /// - /// Build a scaling matrix - /// - /// Single scale factor for x,y and z axes - /// A scaling matrix - [Obsolete("Use CreateScale instead.")] - public static Matrix4 Scale(float scale) - { - return Scale(scale, scale, scale); - } - - /// - /// Build a scaling matrix - /// - /// Scale factors for x,y and z axes - /// A scaling matrix - [Obsolete("Use CreateScale instead.")] - public static Matrix4 Scale(Vector3 scale) - { - return Scale(scale.X, scale.Y, scale.Z); - } - - /// - /// Build a scaling matrix - /// - /// Scale factor for x-axis - /// Scale factor for y-axis - /// Scale factor for z-axis - /// A scaling matrix - [Obsolete("Use CreateScale instead.")] - public static Matrix4 Scale(float x, float y, float z) - { - Matrix4 result; - result.Row0 = Vector4.UnitX * x; - result.Row1 = Vector4.UnitY * y; - result.Row2 = Vector4.UnitZ * z; - result.Row3 = Vector4.UnitW; - return result; - } - - #endregion - - #region Camera Helper Functions - - /// - /// Build a projection matrix - /// - /// Left edge of the view frustum - /// Right edge of the view frustum - /// Bottom edge of the view frustum - /// Top edge of the view frustum - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - [Obsolete("Use CreatePerspectiveOffCenter instead.")] - public static Matrix4 Frustum(float left, float right, float bottom, float top, float near, float far) - { - float invRL = 1.0f / (right - left); - float invTB = 1.0f / (top - bottom); - float invFN = 1.0f / (far - near); - return new Matrix4(new Vector4(2.0f * near * invRL, 0.0f, 0.0f, 0.0f), - new Vector4(0.0f, 2.0f * near * invTB, 0.0f, 0.0f), - new Vector4((right + left) * invRL, (top + bottom) * invTB, -(far + near) * invFN, -1.0f), - new Vector4(0.0f, 0.0f, -2.0f * far * near * invFN, 0.0f)); - } - - /// - /// Build a projection matrix - /// - /// Angle of the field of view in the y direction (in radians) - /// Aspect ratio of the view (width / height) - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - [Obsolete("Use CreatePerspectiveFieldOfView instead.")] - public static Matrix4 Perspective(float fovy, float aspect, float near, float far) - { - float yMax = near * (float)System.Math.Tan(0.5f * fovy); - float yMin = -yMax; - float xMin = yMin * aspect; - float xMax = yMax * aspect; - - return Frustum(xMin, xMax, yMin, yMax, near, far); - } - - #endregion - - #endregion - - #region Camera Helper Functions - - /// - /// Build a world space to camera space matrix - /// - /// Eye (camera) position in world space - /// Target position in world space - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// A Matrix4 that transforms world space to camera space - public static Matrix4 LookAt(Vector3 eye, Vector3 target, Vector3 up) - { - Vector3 z = Vector3.Normalize(eye - target); - Vector3 x = Vector3.Normalize(Vector3.Cross(up, z)); - Vector3 y = Vector3.Normalize(Vector3.Cross(z, x)); - - Matrix4 result; - - result.Row0.X = x.X; - result.Row0.Y = y.X; - result.Row0.Z = z.X; - result.Row0.W = 0; - result.Row1.X = x.Y; - result.Row1.Y = y.Y; - result.Row1.Z = z.Y; - result.Row1.W = 0; - result.Row2.X = x.Z; - result.Row2.Y = y.Z; - result.Row2.Z = z.Z; - result.Row2.W = 0; - result.Row3.X = -((x.X * eye.X) + (x.Y * eye.Y) + (x.Z * eye.Z)); - result.Row3.Y = -((y.X * eye.X) + (y.Y * eye.Y) + (y.Z * eye.Z)); - result.Row3.Z = -((z.X * eye.X) + (z.Y * eye.Y) + (z.Z * eye.Z)); - result.Row3.W = 1; - - return result; - } - - /// - /// Build a world space to camera space matrix - /// - /// Eye (camera) position in world space - /// Eye (camera) position in world space - /// Eye (camera) position in world space - /// Target position in world space - /// Target position in world space - /// Target position in world space - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// A Matrix4 that transforms world space to camera space - public static Matrix4 LookAt(float eyeX, float eyeY, float eyeZ, float targetX, float targetY, float targetZ, float upX, float upY, float upZ) - { - return LookAt(new Vector3(eyeX, eyeY, eyeZ), new Vector3(targetX, targetY, targetZ), new Vector3(upX, upY, upZ)); - } - - #endregion - - #region Add Functions - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix4 Add(Matrix4 left, Matrix4 right) - { - Matrix4 result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix4 left, ref Matrix4 right, out Matrix4 result) - { - result.Row0 = left.Row0 + right.Row0; - result.Row1 = left.Row1 + right.Row1; - result.Row2 = left.Row2 + right.Row2; - result.Row3 = left.Row3 + right.Row3; - } - - #endregion - - #region Subtract Functions - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static Matrix4 Subtract(Matrix4 left, Matrix4 right) - { - Matrix4 result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static void Subtract(ref Matrix4 left, ref Matrix4 right, out Matrix4 result) - { - result.Row0 = left.Row0 - right.Row0; - result.Row1 = left.Row1 - right.Row1; - result.Row2 = left.Row2 - right.Row2; - result.Row3 = left.Row3 - right.Row3; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix4 Mult(Matrix4 left, Matrix4 right) - { - Matrix4 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix4 left, ref Matrix4 right, out Matrix4 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W, - lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.Z, lM44 = left.Row3.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z, rM44 = right.Row3.W; - - result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41); - result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42); - result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43); - result.Row0.W = (((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34)) + (lM14 * rM44); - result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41); - result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42); - result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43); - result.Row1.W = (((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34)) + (lM24 * rM44); - result.Row2.X = (((lM31 * rM11) + (lM32 * rM21)) + (lM33 * rM31)) + (lM34 * rM41); - result.Row2.Y = (((lM31 * rM12) + (lM32 * rM22)) + (lM33 * rM32)) + (lM34 * rM42); - result.Row2.Z = (((lM31 * rM13) + (lM32 * rM23)) + (lM33 * rM33)) + (lM34 * rM43); - result.Row2.W = (((lM31 * rM14) + (lM32 * rM24)) + (lM33 * rM34)) + (lM34 * rM44); - result.Row3.X = (((lM41 * rM11) + (lM42 * rM21)) + (lM43 * rM31)) + (lM44 * rM41); - result.Row3.Y = (((lM41 * rM12) + (lM42 * rM22)) + (lM43 * rM32)) + (lM44 * rM42); - result.Row3.Z = (((lM41 * rM13) + (lM42 * rM23)) + (lM43 * rM33)) + (lM44 * rM43); - result.Row3.W = (((lM41 * rM14) + (lM42 * rM24)) + (lM43 * rM34)) + (lM44 * rM44); - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix4 Mult(Matrix4 left, float right) - { - Matrix4 result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix4 left, float right, out Matrix4 result) - { - result.Row0 = left.Row0 * right; - result.Row1 = left.Row1 * right; - result.Row2 = left.Row2 * right; - result.Row3 = left.Row3 * right; - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static void Invert(ref Matrix4 mat, out Matrix4 result) - { - int[] colIdx = { 0, 0, 0, 0 }; - int[] rowIdx = { 0, 0, 0, 0 }; - int[] pivotIdx = { -1, -1, -1, -1 }; - - // convert the matrix to an array for easy looping - float[,] inverse = {{mat.Row0.X, mat.Row0.Y, mat.Row0.Z, mat.Row0.W}, - {mat.Row1.X, mat.Row1.Y, mat.Row1.Z, mat.Row1.W}, - {mat.Row2.X, mat.Row2.Y, mat.Row2.Z, mat.Row2.W}, - {mat.Row3.X, mat.Row3.Y, mat.Row3.Z, mat.Row3.W} }; - int icol = 0; - int irow = 0; - for (int i = 0; i < 4; i++) - { - // Find the largest pivot value - float maxPivot = 0.0f; - for (int j = 0; j < 4; j++) - { - if (pivotIdx[j] != 0) - { - for (int k = 0; k < 4; ++k) - { - if (pivotIdx[k] == -1) - { - float absVal = System.Math.Abs(inverse[j, k]); - if (absVal > maxPivot) - { - maxPivot = absVal; - irow = j; - icol = k; - } - } - else if (pivotIdx[k] > 0) - { - result = mat; - return; - } - } - } - } - - ++(pivotIdx[icol]); - - // Swap rows over so pivot is on diagonal - if (irow != icol) - { - for (int k = 0; k < 4; ++k) - { - float f = inverse[irow, k]; - inverse[irow, k] = inverse[icol, k]; - inverse[icol, k] = f; - } - } - - rowIdx[i] = irow; - colIdx[i] = icol; - - float pivot = inverse[icol, icol]; - // check for singular matrix - if (pivot == 0.0f) - { - throw new InvalidOperationException("Matrix is singular and cannot be inverted."); - } - - // Scale row so it has a unit diagonal - float oneOverPivot = 1.0f / pivot; - inverse[icol, icol] = 1.0f; - for (int k = 0; k < 4; ++k) - inverse[icol, k] *= oneOverPivot; - - // Do elimination of non-diagonal elements - for (int j = 0; j < 4; ++j) - { - // check this isn't on the diagonal - if (icol != j) - { - float f = inverse[j, icol]; - inverse[j, icol] = 0.0f; - for (int k = 0; k < 4; ++k) - inverse[j, k] -= inverse[icol, k] * f; - } - } - } - - for (int j = 3; j >= 0; --j) - { - int ir = rowIdx[j]; - int ic = colIdx[j]; - for (int k = 0; k < 4; ++k) - { - float f = inverse[k, ir]; - inverse[k, ir] = inverse[k, ic]; - inverse[k, ic] = f; - } - } - - result.Row0.X = inverse[0, 0]; - result.Row0.Y = inverse[0, 1]; - result.Row0.Z = inverse[0, 2]; - result.Row0.W = inverse[0, 3]; - result.Row1.X = inverse[1, 0]; - result.Row1.Y = inverse[1, 1]; - result.Row1.Z = inverse[1, 2]; - result.Row1.W = inverse[1, 3]; - result.Row2.X = inverse[2, 0]; - result.Row2.Y = inverse[2, 1]; - result.Row2.Z = inverse[2, 2]; - result.Row2.W = inverse[2, 3]; - result.Row3.X = inverse[3, 0]; - result.Row3.Y = inverse[3, 1]; - result.Row3.Z = inverse[3, 2]; - result.Row3.W = inverse[3, 3]; - } - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static Matrix4 Invert(Matrix4 mat) - { - Matrix4 result; - Invert(ref mat, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The transpose of the given matrix - public static Matrix4 Transpose(Matrix4 mat) - { - return new Matrix4(mat.Column0, mat.Column1, mat.Column2, mat.Column3); - } - - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The result of the calculation - public static void Transpose(ref Matrix4 mat, out Matrix4 result) - { - result.Row0 = mat.Column0; - result.Row1 = mat.Column1; - result.Row2 = mat.Column2; - result.Row3 = mat.Column3; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4 which holds the result of the multiplication - public static Matrix4 operator *(Matrix4 left, Matrix4 right) - { - return Matrix4.Mult(left, right); - } - - /// - /// Matrix-scalar multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4 which holds the result of the multiplication - public static Matrix4 operator *(Matrix4 left, float right) - { - return Matrix4.Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4 which holds the result of the addition - public static Matrix4 operator +(Matrix4 left, Matrix4 right) - { - return Matrix4.Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4 which holds the result of the subtraction - public static Matrix4 operator -(Matrix4 left, Matrix4 right) - { - return Matrix4.Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix4 left, Matrix4 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix4 left, Matrix4 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix4. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}\n{2}\n{3}", Row0, Row1, Row2, Row3); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode() ^ Row3.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare tresult. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix4)) - return false; - - return this.Equals((Matrix4)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current matrix is equal to another matrix. - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix4 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2 && - Row3 == other.Row3; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix4d.cs b/OpenTK/Math/Matrix4d.cs deleted file mode 100644 index 785a6a12..00000000 --- a/OpenTK/Math/Matrix4d.cs +++ /dev/null @@ -1,1686 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 4x4 matrix containing 3D rotation, scale, transform, and projection with double-precision components. - /// - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Matrix4d : IEquatable - { - #region Fields - - /// - /// Top row of the matrix - /// - public Vector4d Row0; - /// - /// 2nd row of the matrix - /// - public Vector4d Row1; - /// - /// 3rd row of the matrix - /// - public Vector4d Row2; - /// - /// Bottom row of the matrix - /// - public Vector4d Row3; - - /// - /// The identity matrix - /// - public static Matrix4d Identity = new Matrix4d(Vector4d .UnitX, Vector4d .UnitY, Vector4d .UnitZ, Vector4d .UnitW); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix - /// Second row of the matrix - /// Third row of the matrix - /// Bottom row of the matrix - public Matrix4d(Vector4d row0, Vector4d row1, Vector4d row2, Vector4d row3) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - Row3 = row3; - } - - /// - /// Constructs a new instance. - /// - /// First item of the first row. - /// Second item of the first row. - /// Third item of the first row. - /// Fourth item of the first row. - /// First item of the second row. - /// Second item of the second row. - /// Third item of the second row. - /// Fourth item of the second row. - /// First item of the third row. - /// Second item of the third row. - /// Third item of the third row. - /// First item of the third row. - /// Fourth item of the fourth row. - /// Second item of the fourth row. - /// Third item of the fourth row. - /// Fourth item of the fourth row. - public Matrix4d( - double m00, double m01, double m02, double m03, - double m10, double m11, double m12, double m13, - double m20, double m21, double m22, double m23, - double m30, double m31, double m32, double m33) - { - Row0 = new Vector4d(m00, m01, m02, m03); - Row1 = new Vector4d(m10, m11, m12, m13); - Row2 = new Vector4d(m20, m21, m22, m23); - Row3 = new Vector4d(m30, m31, m32, m33); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// The determinant of this matrix - /// - public double Determinant - { - get - { - return - Row0.X * Row1.Y * Row2.Z * Row3.W - Row0.X * Row1.Y * Row2.W * Row3.Z + Row0.X * Row1.Z * Row2.W * Row3.Y - Row0.X * Row1.Z * Row2.Y * Row3.W - + Row0.X * Row1.W * Row2.Y * Row3.Z - Row0.X * Row1.W * Row2.Z * Row3.Y - Row0.Y * Row1.Z * Row2.W * Row3.X + Row0.Y * Row1.Z * Row2.X * Row3.W - - Row0.Y * Row1.W * Row2.X * Row3.Z + Row0.Y * Row1.W * Row2.Z * Row3.X - Row0.Y * Row1.X * Row2.Z * Row3.W + Row0.Y * Row1.X * Row2.W * Row3.Z - + Row0.Z * Row1.W * Row2.X * Row3.Y - Row0.Z * Row1.W * Row2.Y * Row3.X + Row0.Z * Row1.X * Row2.Y * Row3.W - Row0.Z * Row1.X * Row2.W * Row3.Y - + Row0.Z * Row1.Y * Row2.W * Row3.X - Row0.Z * Row1.Y * Row2.X * Row3.W - Row0.W * Row1.X * Row2.Y * Row3.Z + Row0.W * Row1.X * Row2.Z * Row3.Y - - Row0.W * Row1.Y * Row2.Z * Row3.X + Row0.W * Row1.Y * Row2.X * Row3.Z - Row0.W * Row1.Z * Row2.X * Row3.Y + Row0.W * Row1.Z * Row2.Y * Row3.X; - } - } - - /// - /// The first column of this matrix - /// - public Vector4d Column0 - { - get { return new Vector4d (Row0.X, Row1.X, Row2.X, Row3.X); } - set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; Row3.X = value.W; } - } - - /// - /// The second column of this matrix - /// - public Vector4d Column1 - { - get { return new Vector4d (Row0.Y, Row1.Y, Row2.Y, Row3.Y); } - set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; Row3.Y = value.W; } - } - - /// - /// The third column of this matrix - /// - public Vector4d Column2 - { - get { return new Vector4d (Row0.Z, Row1.Z, Row2.Z, Row3.Z); } - set { Row0.Z = value.X; Row1.Z = value.Y; Row2.Z = value.Z; Row3.Z = value.W; } - } - - /// - /// The fourth column of this matrix - /// - public Vector4d Column3 - { - get { return new Vector4d (Row0.W, Row1.W, Row2.W, Row3.W); } - set { Row0.W = value.X; Row1.W = value.Y; Row2.W = value.Z; Row3.W = value.W; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public double M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public double M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 1, column 4 of this instance. - /// - public double M14 { get { return Row0.W; } set { Row0.W = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public double M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public double M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 4 of this instance. - /// - public double M24 { get { return Row1.W; } set { Row1.W = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public double M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public double M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 3 of this instance. - /// - public double M33 { get { return Row2.Z; } set { Row2.Z = value; } } - - /// - /// Gets or sets the value at row 3, column 4 of this instance. - /// - public double M34 { get { return Row2.W; } set { Row2.W = value; } } - - /// - /// Gets or sets the value at row 4, column 1 of this instance. - /// - public double M41 { get { return Row3.X; } set { Row3.X = value; } } - - /// - /// Gets or sets the value at row 4, column 2 of this instance. - /// - public double M42 { get { return Row3.Y; } set { Row3.Y = value; } } - - /// - /// Gets or sets the value at row 4, column 3 of this instance. - /// - public double M43 { get { return Row3.Z; } set { Row3.Z = value; } } - - /// - /// Gets or sets the value at row 4, column 4 of this instance. - /// - public double M44 { get { return Row3.W; } set { Row3.W = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector4d Diagonal - { - get - { - return new Vector4d(Row0.X, Row1.Y, Row2.Z, Row3.W); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - Row2.Z = value.Z; - Row3.W = value.W; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public double Trace { get { return Row0.X + Row1.Y + Row2.Z + Row3.W; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public double this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - else if (rowIndex == 3) return Row3[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else if (rowIndex == 3) Row3[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - /// - public void Invert() - { - this = Matrix4d.Invert(this); - } - - #endregion - - #region public void Transpose() - - /// - /// Converts this instance into its transpose. - /// - public void Transpose() - { - this = Matrix4d.Transpose(this); - } - - #endregion - - /// - /// Returns a normalised copy of this instance. - /// - public Matrix4d Normalized() - { - Matrix4d m = this; - m.Normalize(); - return m; - } - - /// - /// Divides each element in the Matrix by the . - /// - public void Normalize() - { - var determinant = this.Determinant; - Row0 /= determinant; - Row1 /= determinant; - Row2 /= determinant; - Row3 /= determinant; - } - - /// - /// Returns an inverted copy of this instance. - /// - public Matrix4d Inverted() - { - Matrix4d m = this; - if (m.Determinant != 0) - m.Invert(); - return m; - } - - /// - /// Returns a copy of this Matrix4d without translation. - /// - public Matrix4d ClearTranslation() - { - Matrix4d m = this; - m.Row3.Xyz = Vector3d.Zero; - return m; - } - /// - /// Returns a copy of this Matrix4d without scale. - /// - public Matrix4d ClearScale() - { - Matrix4d m = this; - m.Row0.Xyz = m.Row0.Xyz.Normalized(); - m.Row1.Xyz = m.Row1.Xyz.Normalized(); - m.Row2.Xyz = m.Row2.Xyz.Normalized(); - return m; - } - /// - /// Returns a copy of this Matrix4d without rotation. - /// - public Matrix4d ClearRotation() - { - Matrix4d m = this; - m.Row0.Xyz = new Vector3d(m.Row0.Xyz.Length, 0, 0); - m.Row1.Xyz = new Vector3d(0, m.Row1.Xyz.Length, 0); - m.Row2.Xyz = new Vector3d(0, 0, m.Row2.Xyz.Length); - return m; - } - /// - /// Returns a copy of this Matrix4d without projection. - /// - public Matrix4d ClearProjection() - { - Matrix4d m = this; - m.Column3 = Vector4d.Zero; - return m; - } - - /// - /// Returns the translation component of this instance. - /// - public Vector3d ExtractTranslation() { return Row3.Xyz; } - - /// - /// Returns the scale component of this instance. - /// - public Vector3d ExtractScale() { return new Vector3d(Row0.Xyz.Length, Row1.Xyz.Length, Row2.Xyz.Length); } - - /// - /// Returns the rotation component of this instance. Quite slow. - /// - /// Whether the method should row-normalise (i.e. remove scale from) the Matrix. Pass false if you know it's already normalised. - public Quaterniond ExtractRotation(bool row_normalise = true) - { - var row0 = Row0.Xyz; - var row1 = Row1.Xyz; - var row2 = Row2.Xyz; - - if (row_normalise) - { - row0 = row0.Normalized(); - row1 = row1.Normalized(); - row2 = row2.Normalized(); - } - - // code below adapted from Blender - - Quaterniond q = new Quaterniond(); - double trace = 0.25 * (row0[0] + row1[1] + row2[2] + 1.0); - - if (trace > 0) - { - double sq = Math.Sqrt(trace); - - q.W = sq; - sq = 1.0 / (4.0 * sq); - q.X = (row1[2] - row2[1]) * sq; - q.Y = (row2[0] - row0[2]) * sq; - q.Z = (row0[1] - row1[0]) * sq; - } - else if (row0[0] > row1[1] && row0[0] > row2[2]) - { - double sq = 2.0 * Math.Sqrt(1.0 + row0[0] - row1[1] - row2[2]); - - q.X = 0.25 * sq; - sq = 1.0 / sq; - q.W = (row2[1] - row1[2]) * sq; - q.Y = (row1[0] + row0[1]) * sq; - q.Z = (row2[0] + row0[2]) * sq; - } - else if (row1[1] > row2[2]) - { - double sq = 2.0 * Math.Sqrt(1.0 + row1[1] - row0[0] - row2[2]); - - q.Y = 0.25 * sq; - sq = 1.0 / sq; - q.W = (row2[0] - row0[2]) * sq; - q.X = (row1[0] + row0[1]) * sq; - q.Z = (row2[1] + row1[2]) * sq; - } - else - { - double sq = 2.0 * Math.Sqrt(1.0 + row2[2] - row0[0] - row1[1]); - - q.Z = 0.25 * sq; - sq = 1.0 / sq; - q.W = (row1[0] - row0[1]) * sq; - q.X = (row2[0] + row0[2]) * sq; - q.Y = (row2[1] + row1[2]) * sq; - } - - q.Normalize(); - return q; - } - - /// - /// Returns the projection component of this instance. - /// - public Vector4d ExtractProjection() - { - return Column3; - } - - - #endregion - - #region Static - - #region CreateFromAxisAngle - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static void CreateFromAxisAngle(Vector3d axis, double angle, out Matrix4d result) - { - // normalize and create a local copy of the vector. - axis.Normalize(); - double axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; - - // calculate angles - double cos = System.Math.Cos(-angle); - double sin = System.Math.Sin(-angle); - double t = 1.0f - cos; - - // do the conversion math once - double tXX = t * axisX * axisX, - tXY = t * axisX * axisY, - tXZ = t * axisX * axisZ, - tYY = t * axisY * axisY, - tYZ = t * axisY * axisZ, - tZZ = t * axisZ * axisZ; - - double sinX = sin * axisX, - sinY = sin * axisY, - sinZ = sin * axisZ; - - result.Row0.X = tXX + cos; - result.Row0.Y = tXY - sinZ; - result.Row0.Z = tXZ + sinY; - result.Row0.W = 0; - result.Row1.X = tXY + sinZ; - result.Row1.Y = tYY + cos; - result.Row1.Z = tYZ - sinX; - result.Row1.W = 0; - result.Row2.X = tXZ - sinY; - result.Row2.Y = tYZ + sinX; - result.Row2.Z = tZZ + cos; - result.Row2.W = 0; - result.Row3 = Vector4d.UnitW; - } - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static Matrix4d CreateFromAxisAngle(Vector3d axis, double angle) - { - Matrix4d result; - CreateFromAxisAngle(axis, angle, out result); - return result; - } - - #endregion - - #region CreateRotation[XYZ] - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4d instance. - public static void CreateRotationX(double angle, out Matrix4d result) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - result.Row0 = Vector4d.UnitX; - result.Row1 = new Vector4d(0, cos, sin, 0); - result.Row2 = new Vector4d(0, -sin, cos, 0); - result.Row3 = Vector4d.UnitW; - } - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4d instance. - public static Matrix4d CreateRotationX(double angle) - { - Matrix4d result; - CreateRotationX(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4d instance. - public static void CreateRotationY(double angle, out Matrix4d result) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - result.Row0 = new Vector4d(cos, 0, -sin, 0); - result.Row1 = Vector4d.UnitY; - result.Row2 = new Vector4d(sin, 0, cos, 0); - result.Row3 = Vector4d.UnitW; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4d instance. - public static Matrix4d CreateRotationY(double angle) - { - Matrix4d result; - CreateRotationY(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4d instance. - public static void CreateRotationZ(double angle, out Matrix4d result) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - result.Row0 = new Vector4d(cos, sin, 0, 0); - result.Row1 = new Vector4d(-sin, cos, 0, 0); - result.Row2 = Vector4d.UnitZ; - result.Row3 = Vector4d.UnitW; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4d instance. - public static Matrix4d CreateRotationZ(double angle) - { - Matrix4d result; - CreateRotationZ(angle, out result); - return result; - } - - #endregion - - #region CreateTranslation - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4d instance. - public static void CreateTranslation(double x, double y, double z, out Matrix4d result) - { - result = Identity; - result.Row3 = new Vector4d(x, y, z, 1); - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4d instance. - public static void CreateTranslation(ref Vector3d vector, out Matrix4d result) - { - result = Identity; - result.Row3 = new Vector4d(vector.X, vector.Y, vector.Z, 1); - } - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4d instance. - public static Matrix4d CreateTranslation(double x, double y, double z) - { - Matrix4d result; - CreateTranslation(x, y, z, out result); - return result; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4d instance. - public static Matrix4d CreateTranslation(Vector3d vector) - { - Matrix4d result; - CreateTranslation(vector.X, vector.Y, vector.Z, out result); - return result; - } - - #endregion - - #region CreateOrthographic - - /// - /// Creates an orthographic projection matrix. - /// - /// The width of the projection volume. - /// The height of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4d instance. - public static void CreateOrthographic(double width, double height, double zNear, double zFar, out Matrix4d result) - { - CreateOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, zNear, zFar, out result); - } - - /// - /// Creates an orthographic projection matrix. - /// - /// The width of the projection volume. - /// The height of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4d instance. - public static Matrix4d CreateOrthographic(double width, double height, double zNear, double zFar) - { - Matrix4d result; - CreateOrthographicOffCenter(-width / 2, width / 2, -height / 2, height / 2, zNear, zFar, out result); - return result; - } - - #endregion - - #region CreateOrthographicOffCenter - - /// - /// Creates an orthographic projection matrix. - /// - /// The left edge of the projection volume. - /// The right edge of the projection volume. - /// The bottom edge of the projection volume. - /// The top edge of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4d instance. - public static void CreateOrthographicOffCenter(double left, double right, double bottom, double top, double zNear, double zFar, out Matrix4d result) - { - result = new Matrix4d(); - - double invRL = 1 / (right - left); - double invTB = 1 / (top - bottom); - double invFN = 1 / (zFar - zNear); - - result.M11 = 2 * invRL; - result.M22 = 2 * invTB; - result.M33 = -2 * invFN; - - result.M41 = -(right + left) * invRL; - result.M42 = -(top + bottom) * invTB; - result.M43 = -(zFar + zNear) * invFN; - result.M44 = 1; - } - - /// - /// Creates an orthographic projection matrix. - /// - /// The left edge of the projection volume. - /// The right edge of the projection volume. - /// The bottom edge of the projection volume. - /// The top edge of the projection volume. - /// The near edge of the projection volume. - /// The far edge of the projection volume. - /// The resulting Matrix4d instance. - public static Matrix4d CreateOrthographicOffCenter(double left, double right, double bottom, double top, double zNear, double zFar) - { - Matrix4d result; - CreateOrthographicOffCenter(left, right, bottom, top, zNear, zFar, out result); - return result; - } - - #endregion - - #region CreatePerspectiveFieldOfView - - /// - /// Creates a perspective projection matrix. - /// - /// Angle of the field of view in the y direction (in radians) - /// Aspect ratio of the view (width / height) - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// fovy is zero, less than zero or larger than Math.PI - /// aspect is negative or zero - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - public static void CreatePerspectiveFieldOfView(double fovy, double aspect, double zNear, double zFar, out Matrix4d result) - { - if (fovy <= 0 || fovy > Math.PI) - throw new ArgumentOutOfRangeException("fovy"); - if (aspect <= 0) - throw new ArgumentOutOfRangeException("aspect"); - if (zNear <= 0) - throw new ArgumentOutOfRangeException("zNear"); - if (zFar <= 0) - throw new ArgumentOutOfRangeException("zFar"); - - double yMax = zNear * System.Math.Tan(0.5 * fovy); - double yMin = -yMax; - double xMin = yMin * aspect; - double xMax = yMax * aspect; - - CreatePerspectiveOffCenter(xMin, xMax, yMin, yMax, zNear, zFar, out result); - } - - /// - /// Creates a perspective projection matrix. - /// - /// Angle of the field of view in the y direction (in radians) - /// Aspect ratio of the view (width / height) - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// fovy is zero, less than zero or larger than Math.PI - /// aspect is negative or zero - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - public static Matrix4d CreatePerspectiveFieldOfView(double fovy, double aspect, double zNear, double zFar) - { - Matrix4d result; - CreatePerspectiveFieldOfView(fovy, aspect, zNear, zFar, out result); - return result; - } - - #endregion - - #region CreatePerspectiveOffCenter - - /// - /// Creates an perspective projection matrix. - /// - /// Left edge of the view frustum - /// Right edge of the view frustum - /// Bottom edge of the view frustum - /// Top edge of the view frustum - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - public static void CreatePerspectiveOffCenter(double left, double right, double bottom, double top, double zNear, double zFar, out Matrix4d result) - { - if (zNear <= 0) - throw new ArgumentOutOfRangeException("zNear"); - if (zFar <= 0) - throw new ArgumentOutOfRangeException("zFar"); - if (zNear >= zFar) - throw new ArgumentOutOfRangeException("zNear"); - - double x = (2.0 * zNear) / (right - left); - double y = (2.0 * zNear) / (top - bottom); - double a = (right + left) / (right - left); - double b = (top + bottom) / (top - bottom); - double c = -(zFar + zNear) / (zFar - zNear); - double d = -(2.0 * zFar * zNear) / (zFar - zNear); - - result = new Matrix4d(x, 0, 0, 0, - 0, y, 0, 0, - a, b, c, -1, - 0, 0, d, 0); - } - - /// - /// Creates an perspective projection matrix. - /// - /// Left edge of the view frustum - /// Right edge of the view frustum - /// Bottom edge of the view frustum - /// Top edge of the view frustum - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - /// - /// Thrown under the following conditions: - /// - /// zNear is negative or zero - /// zFar is negative or zero - /// zNear is larger than zFar - /// - /// - public static Matrix4d CreatePerspectiveOffCenter(double left, double right, double bottom, double top, double zNear, double zFar) - { - Matrix4d result; - CreatePerspectiveOffCenter(left, right, bottom, top, zNear, zFar, out result); - return result; - } - - #endregion - - #region CreateFromQuaternion - /// - /// Build a rotation matrix from the specified quaternion. - /// - /// Quaternion to translate. - /// Matrix result. - public static void CreateFromQuaternion(ref Quaterniond q, out Matrix4d result) - { - Vector3d axis; - double angle; - q.ToAxisAngle(out axis, out angle); - CreateFromAxisAngle(axis, angle, out result); - } - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static Matrix4d CreateFromQuaternion(Quaterniond q) - { - Matrix4d result; - CreateFromQuaternion(ref q, out result); - return result; - } - - - /// - /// Build a rotation matrix from the specified quaternion. - /// - /// Quaternion to translate. - /// Matrix result. - [Obsolete("Use double-precision overload instead")] - public static void CreateFromQuaternion(ref Quaternion q,ref Matrix4 m) - { - m = Matrix4.Identity; - - float X = q.X; - float Y = q.Y; - float Z = q.Z; - float W = q.W; - - float xx = X * X; - float xy = X * Y; - float xz = X * Z; - float xw = X * W; - float yy = Y * Y; - float yz = Y * Z; - float yw = Y * W; - float zz = Z * Z; - float zw = Z * W; - - m.M11 = 1 - 2 * (yy + zz); - m.M21 = 2 * (xy - zw); - m.M31 = 2 * (xz + yw); - m.M12 = 2 * (xy + zw); - m.M22 = 1 - 2 * (xx + zz); - m.M32 = 2 * (yz - xw); - m.M13 = 2 * (xz - yw); - m.M23 = 2 * (yz + xw); - m.M33 = 1 - 2 * (xx + yy); - } - - /// - /// Build a rotation matrix from the specified quaternion. - /// - /// Quaternion to translate. - /// A matrix instance. - [Obsolete("Use double-precision overload instead")] - public static Matrix4 CreateFromQuaternion(ref Quaternion q) - { - Matrix4 result = Matrix4.Identity; - - float X = q.X; - float Y = q.Y; - float Z = q.Z; - float W = q.W; - - float xx = X * X; - float xy = X * Y; - float xz = X * Z; - float xw = X * W; - float yy = Y * Y; - float yz = Y * Z; - float yw = Y * W; - float zz = Z * Z; - float zw = Z * W; - - result.M11 = 1 - 2 * (yy + zz); - result.M21 = 2 * (xy - zw); - result.M31 = 2 * (xz + yw); - result.M12 = 2 * (xy + zw); - result.M22 = 1 - 2 * (xx + zz); - result.M32 = 2 * (yz - xw); - result.M13 = 2 * (xz - yw); - result.M23 = 2 * (yz + xw); - result.M33 = 1 - 2 * (xx + yy); - return result; - } - - #endregion - - #region Obsolete Functions - - #region Translation Functions - - /// - /// Build a translation matrix with the given translation - /// - /// The vector to translate along - /// A Translation matrix - [Obsolete("Use CreateTranslation instead.")] - public static Matrix4d Translation(Vector3d trans) - { - return Translation(trans.X, trans.Y, trans.Z); - } - - /// - /// Build a translation matrix with the given translation - /// - /// X translation - /// Y translation - /// Z translation - /// A Translation matrix - [Obsolete("Use CreateTranslation instead.")] - public static Matrix4d Translation(double x, double y, double z) - { - Matrix4d result = Identity; - result.Row3 = new Vector4d(x, y, z, 1.0); - return result; - } - - #endregion - - #endregion - - #region Scale Functions - - /// - /// Build a scaling matrix - /// - /// Single scale factor for x,y and z axes - /// A scaling matrix - public static Matrix4d Scale(double scale) - { - return Scale(scale, scale, scale); - } - - /// - /// Build a scaling matrix - /// - /// Scale factors for x,y and z axes - /// A scaling matrix - public static Matrix4d Scale(Vector3d scale) - { - return Scale(scale.X, scale.Y, scale.Z); - } - - /// - /// Build a scaling matrix - /// - /// Scale factor for x-axis - /// Scale factor for y-axis - /// Scale factor for z-axis - /// A scaling matrix - public static Matrix4d Scale(double x, double y, double z) - { - Matrix4d result; - result.Row0 = Vector4d .UnitX * x; - result.Row1 = Vector4d .UnitY * y; - result.Row2 = Vector4d .UnitZ * z; - result.Row3 = Vector4d .UnitW; - return result; - } - - #endregion - - #region Rotation Functions - - /// - /// Build a rotation matrix that rotates about the x-axis - /// - /// angle in radians to rotate counter-clockwise around the x-axis - /// A rotation matrix - public static Matrix4d RotateX(double angle) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - Matrix4d result; - result.Row0 = Vector4d .UnitX; - result.Row1 = new Vector4d (0.0, cos, sin, 0.0); - result.Row2 = new Vector4d (0.0, -sin, cos, 0.0); - result.Row3 = Vector4d .UnitW; - return result; - } - - /// - /// Build a rotation matrix that rotates about the y-axis - /// - /// angle in radians to rotate counter-clockwise around the y-axis - /// A rotation matrix - public static Matrix4d RotateY(double angle) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - Matrix4d result; - result.Row0 = new Vector4d (cos, 0.0, -sin, 0.0); - result.Row1 = Vector4d .UnitY; - result.Row2 = new Vector4d (sin, 0.0, cos, 0.0); - result.Row3 = Vector4d .UnitW; - return result; - } - - /// - /// Build a rotation matrix that rotates about the z-axis - /// - /// angle in radians to rotate counter-clockwise around the z-axis - /// A rotation matrix - public static Matrix4d RotateZ(double angle) - { - double cos = System.Math.Cos(angle); - double sin = System.Math.Sin(angle); - - Matrix4d result; - result.Row0 = new Vector4d (cos, sin, 0.0, 0.0); - result.Row1 = new Vector4d (-sin, cos, 0.0, 0.0); - result.Row2 = Vector4d .UnitZ; - result.Row3 = Vector4d .UnitW; - return result; - } - - /// - /// Build a rotation matrix to rotate about the given axis - /// - /// the axis to rotate about - /// angle in radians to rotate counter-clockwise (looking in the direction of the given axis) - /// A rotation matrix - public static Matrix4d Rotate(Vector3d axis, double angle) - { - double cos = System.Math.Cos(-angle); - double sin = System.Math.Sin(-angle); - double t = 1.0 - cos; - - axis.Normalize(); - - Matrix4d result; - result.Row0 = new Vector4d (t * axis.X * axis.X + cos, t * axis.X * axis.Y - sin * axis.Z, t * axis.X * axis.Z + sin * axis.Y, 0.0); - result.Row1 = new Vector4d (t * axis.X * axis.Y + sin * axis.Z, t * axis.Y * axis.Y + cos, t * axis.Y * axis.Z - sin * axis.X, 0.0); - result.Row2 = new Vector4d (t * axis.X * axis.Z - sin * axis.Y, t * axis.Y * axis.Z + sin * axis.X, t * axis.Z * axis.Z + cos, 0.0); - result.Row3 = Vector4d .UnitW; - return result; - } - - /// - /// Build a rotation matrix from a quaternion - /// - /// the quaternion - /// A rotation matrix - public static Matrix4d Rotate(Quaterniond q) - { - Vector3d axis; - double angle; - q.ToAxisAngle(out axis, out angle); - return Rotate(axis, angle); - } - - #endregion - - #region Camera Helper Functions - - /// - /// Build a world space to camera space matrix - /// - /// Eye (camera) position in world space - /// Target position in world space - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// A Matrix that transforms world space to camera space - public static Matrix4d LookAt(Vector3d eye, Vector3d target, Vector3d up) - { - Vector3d z = Vector3d.Normalize(eye - target); - Vector3d x = Vector3d.Normalize(Vector3d.Cross(up, z)); - Vector3d y = Vector3d.Normalize(Vector3d.Cross(z, x)); - - Matrix4d rot = new Matrix4d(new Vector4d (x.X, y.X, z.X, 0.0), - new Vector4d (x.Y, y.Y, z.Y, 0.0), - new Vector4d (x.Z, y.Z, z.Z, 0.0), - Vector4d .UnitW); - - Matrix4d trans = Matrix4d.CreateTranslation(-eye); - - return trans * rot; - } - - /// - /// Build a world space to camera space matrix - /// - /// Eye (camera) position in world space - /// Eye (camera) position in world space - /// Eye (camera) position in world space - /// Target position in world space - /// Target position in world space - /// Target position in world space - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// Up vector in world space (should not be parallel to the camera direction, that is target - eye) - /// A Matrix4 that transforms world space to camera space - public static Matrix4d LookAt(double eyeX, double eyeY, double eyeZ, double targetX, double targetY, double targetZ, double upX, double upY, double upZ) - { - return LookAt(new Vector3d(eyeX, eyeY, eyeZ), new Vector3d(targetX, targetY, targetZ), new Vector3d(upX, upY, upZ)); - } - - /// - /// Build a projection matrix - /// - /// Left edge of the view frustum - /// Right edge of the view frustum - /// Bottom edge of the view frustum - /// Top edge of the view frustum - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - public static Matrix4d Frustum(double left, double right, double bottom, double top, double near, double far) - { - double invRL = 1.0 / (right - left); - double invTB = 1.0 / (top - bottom); - double invFN = 1.0 / (far - near); - return new Matrix4d(new Vector4d (2.0 * near * invRL, 0.0, 0.0, 0.0), - new Vector4d (0.0, 2.0 * near * invTB, 0.0, 0.0), - new Vector4d ((right + left) * invRL, (top + bottom) * invTB, -(far + near) * invFN, -1.0), - new Vector4d (0.0, 0.0, -2.0 * far * near * invFN, 0.0)); - } - - /// - /// Build a projection matrix - /// - /// Angle of the field of view in the y direction (in radians) - /// Aspect ratio of the view (width / height) - /// Distance to the near clip plane - /// Distance to the far clip plane - /// A projection matrix that transforms camera space to raster space - public static Matrix4d Perspective(double fovy, double aspect, double near, double far) - { - double yMax = near * System.Math.Tan(0.5f * fovy); - double yMin = -yMax; - double xMin = yMin * aspect; - double xMax = yMax * aspect; - - return Frustum(xMin, xMax, yMin, yMax, near, far); - } - - #endregion - - #region Add Functions - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix4d Add(Matrix4d left, Matrix4d right) - { - Matrix4d result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix4d left, ref Matrix4d right, out Matrix4d result) - { - result.Row0 = left.Row0 + right.Row0; - result.Row1 = left.Row1 + right.Row1; - result.Row2 = left.Row2 + right.Row2; - result.Row3 = left.Row3 + right.Row3; - } - - #endregion - - #region Subtract Functions - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static Matrix4d Subtract(Matrix4d left, Matrix4d right) - { - Matrix4d result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static void Subtract(ref Matrix4d left, ref Matrix4d right, out Matrix4d result) - { - result.Row0 = left.Row0 - right.Row0; - result.Row1 = left.Row1 - right.Row1; - result.Row2 = left.Row2 - right.Row2; - result.Row3 = left.Row3 - right.Row3; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix4d Mult(Matrix4d left, Matrix4d right) - { - Matrix4d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix4d left, ref Matrix4d right, out Matrix4d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, lM14 = left.Row0.W, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, lM24 = left.Row1.W, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, lM34 = left.Row2.W, - lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.Z, lM44 = left.Row3.W, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z, rM44 = right.Row3.W; - - result.Row0.X = (((lM11 * rM11) + (lM12 * rM21)) + (lM13 * rM31)) + (lM14 * rM41); - result.Row0.Y = (((lM11 * rM12) + (lM12 * rM22)) + (lM13 * rM32)) + (lM14 * rM42); - result.Row0.Z = (((lM11 * rM13) + (lM12 * rM23)) + (lM13 * rM33)) + (lM14 * rM43); - result.Row0.W = (((lM11 * rM14) + (lM12 * rM24)) + (lM13 * rM34)) + (lM14 * rM44); - result.Row1.X = (((lM21 * rM11) + (lM22 * rM21)) + (lM23 * rM31)) + (lM24 * rM41); - result.Row1.Y = (((lM21 * rM12) + (lM22 * rM22)) + (lM23 * rM32)) + (lM24 * rM42); - result.Row1.Z = (((lM21 * rM13) + (lM22 * rM23)) + (lM23 * rM33)) + (lM24 * rM43); - result.Row1.W = (((lM21 * rM14) + (lM22 * rM24)) + (lM23 * rM34)) + (lM24 * rM44); - result.Row2.X = (((lM31 * rM11) + (lM32 * rM21)) + (lM33 * rM31)) + (lM34 * rM41); - result.Row2.Y = (((lM31 * rM12) + (lM32 * rM22)) + (lM33 * rM32)) + (lM34 * rM42); - result.Row2.Z = (((lM31 * rM13) + (lM32 * rM23)) + (lM33 * rM33)) + (lM34 * rM43); - result.Row2.W = (((lM31 * rM14) + (lM32 * rM24)) + (lM33 * rM34)) + (lM34 * rM44); - result.Row3.X = (((lM41 * rM11) + (lM42 * rM21)) + (lM43 * rM31)) + (lM44 * rM41); - result.Row3.Y = (((lM41 * rM12) + (lM42 * rM22)) + (lM43 * rM32)) + (lM44 * rM42); - result.Row3.Z = (((lM41 * rM13) + (lM42 * rM23)) + (lM43 * rM33)) + (lM44 * rM43); - result.Row3.W = (((lM41 * rM14) + (lM42 * rM24)) + (lM43 * rM34)) + (lM44 * rM44); - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix4d Mult(Matrix4d left, double right) - { - Matrix4d result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix4d left, double right, out Matrix4d result) - { - result.Row0 = left.Row0 * right; - result.Row1 = left.Row1 * right; - result.Row2 = left.Row2 * right; - result.Row3 = left.Row3 * right; - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4d is singular. - public static Matrix4d Invert(Matrix4d mat) - { - int[] colIdx = { 0, 0, 0, 0 }; - int[] rowIdx = { 0, 0, 0, 0 }; - int[] pivotIdx = { -1, -1, -1, -1 }; - - // convert the matrix to an array for easy looping - double[,] inverse = {{mat.Row0.X, mat.Row0.Y, mat.Row0.Z, mat.Row0.W}, - {mat.Row1.X, mat.Row1.Y, mat.Row1.Z, mat.Row1.W}, - {mat.Row2.X, mat.Row2.Y, mat.Row2.Z, mat.Row2.W}, - {mat.Row3.X, mat.Row3.Y, mat.Row3.Z, mat.Row3.W} }; - int icol = 0; - int irow = 0; - for (int i = 0; i < 4; i++) - { - // Find the largest pivot value - double maxPivot = 0.0; - for (int j = 0; j < 4; j++) - { - if (pivotIdx[j] != 0) - { - for (int k = 0; k < 4; ++k) - { - if (pivotIdx[k] == -1) - { - double absVal = System.Math.Abs(inverse[j, k]); - if (absVal > maxPivot) - { - maxPivot = absVal; - irow = j; - icol = k; - } - } - else if (pivotIdx[k] > 0) - { - return mat; - } - } - } - } - - ++(pivotIdx[icol]); - - // Swap rows over so pivot is on diagonal - if (irow != icol) - { - for (int k = 0; k < 4; ++k) - { - double f = inverse[irow, k]; - inverse[irow, k] = inverse[icol, k]; - inverse[icol, k] = f; - } - } - - rowIdx[i] = irow; - colIdx[i] = icol; - - double pivot = inverse[icol, icol]; - // check for singular matrix - if (pivot == 0.0) - { - throw new InvalidOperationException("Matrix is singular and cannot be inverted."); - //return mat; - } - - // Scale row so it has a unit diagonal - double oneOverPivot = 1.0 / pivot; - inverse[icol, icol] = 1.0; - for (int k = 0; k < 4; ++k) - inverse[icol, k] *= oneOverPivot; - - // Do elimination of non-diagonal elements - for (int j = 0; j < 4; ++j) - { - // check this isn't on the diagonal - if (icol != j) - { - double f = inverse[j, icol]; - inverse[j, icol] = 0.0; - for (int k = 0; k < 4; ++k) - inverse[j, k] -= inverse[icol, k] * f; - } - } - } - - for (int j = 3; j >= 0; --j) - { - int ir = rowIdx[j]; - int ic = colIdx[j]; - for (int k = 0; k < 4; ++k) - { - double f = inverse[k, ir]; - inverse[k, ir] = inverse[k, ic]; - inverse[k, ic] = f; - } - } - - mat.Row0 = new Vector4d (inverse[0, 0], inverse[0, 1], inverse[0, 2], inverse[0, 3]); - mat.Row1 = new Vector4d (inverse[1, 0], inverse[1, 1], inverse[1, 2], inverse[1, 3]); - mat.Row2 = new Vector4d (inverse[2, 0], inverse[2, 1], inverse[2, 2], inverse[2, 3]); - mat.Row3 = new Vector4d (inverse[3, 0], inverse[3, 1], inverse[3, 2], inverse[3, 3]); - return mat; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The transpose of the given matrix - public static Matrix4d Transpose(Matrix4d mat) - { - return new Matrix4d(mat.Column0, mat.Column1, mat.Column2, mat.Column3); - } - - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The result of the calculation - public static void Transpose(ref Matrix4d mat, out Matrix4d result) - { - result.Row0 = mat.Column0; - result.Row1 = mat.Column1; - result.Row2 = mat.Column2; - result.Row3 = mat.Column3; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4d which holds the result of the multiplication - public static Matrix4d operator *(Matrix4d left, Matrix4d right) - { - return Matrix4d.Mult(left, right); - } - - /// - /// Matrix-scalar multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4d which holds the result of the multiplication - public static Matrix4d operator *(Matrix4d left, float right) - { - return Matrix4d.Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4d which holds the result of the addition - public static Matrix4d operator +(Matrix4d left, Matrix4d right) - { - return Matrix4d.Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4d which holds the result of the subtraction - public static Matrix4d operator -(Matrix4d left, Matrix4d right) - { - return Matrix4d.Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix4d left, Matrix4d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix4d left, Matrix4d right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix44. - /// - /// - public override string ToString() - { - return String.Format("{0}\n{1}\n{2}\n{3}", Row0, Row1, Row2, Row3); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode() ^ Row3.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix4d)) - return false; - - return this.Equals((Matrix4d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current matrix is equal to another matrix. - /// A matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix4d other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2 && - Row3 == other.Row3; - } - - #endregion - } -} \ No newline at end of file diff --git a/OpenTK/Math/Matrix4x2.cs b/OpenTK/Math/Matrix4x2.cs deleted file mode 100644 index d548efda..00000000 --- a/OpenTK/Math/Matrix4x2.cs +++ /dev/null @@ -1,786 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 4x2 matrix. - /// - public struct Matrix4x2 : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector2 Row0; - - /// - /// Second row of the matrix. - /// - public Vector2 Row1; - - /// - /// Third row of the matrix. - /// - public Vector2 Row2; - - /// - /// Bottom row of the matrix. - /// - public Vector2 Row3; - - /// - /// The zero matrix. - /// - public static readonly Matrix4x2 Zero = new Matrix4x2(Vector2.Zero, Vector2.Zero, Vector2.Zero, Vector2.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Second row of the matrix. - /// Third row of the matrix. - /// Bottom row of the matrix. - public Matrix4x2(Vector2 row0, Vector2 row1, Vector2 row2, Vector2 row3) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - Row3 = row3; - } - - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// First item of the fourth row of the matrix. - /// Second item of the fourth row of the matrix. - public Matrix4x2( - float m00, float m01, - float m10, float m11, - float m20, float m21, - float m30, float m31) - { - Row0 = new Vector2(m00, m01); - Row1 = new Vector2(m10, m11); - Row2 = new Vector2(m20, m21); - Row3 = new Vector2(m30, m31); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets or sets the first column of this matrix. - /// - public Vector4 Column0 - { - get { return new Vector4(Row0.X, Row1.X, Row2.X, Row3.X); } - set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; Row3.X = value.W; } - } - - /// - /// Gets or sets the second column of this matrix. - /// - public Vector4 Column1 - { - get { return new Vector4(Row0.Y, Row1.Y, Row2.Y, Row3.X); } - set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; Row3.Y = value.W; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public float M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public float M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 4, column 1 of this instance. - /// - public float M41 { get { return Row3.X; } set { Row3.X = value; } } - - /// - /// Gets or sets the value at row 4, column 2 of this instance. - /// - public float M42 { get { return Row3.Y; } set { Row3.Y = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2 Diagonal - { - get - { - return new Vector2(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public float Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public float this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - else if (rowIndex == 3) return Row3[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else if (rowIndex == 3) Row3[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3x2 instance. - public static void CreateRotation(float angle, out Matrix4x2 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row3.X = 0; - result.Row3.Y = 0; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3x2 instance. - public static Matrix4x2 CreateRotation(float angle) - { - Matrix4x2 result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(float scale, out Matrix4x2 result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row3.X = 0; - result.Row3.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix4x2 CreateScale(float scale) - { - Matrix4x2 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2 scale, out Matrix4x2 result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row3.X = 0; - result.Row3.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix4x2 CreateScale(Vector2 scale) - { - Matrix4x2 result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(float x, float y, out Matrix4x2 result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row3.X = 0; - result.Row3.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix4x2 CreateScale(float x, float y) - { - Matrix4x2 result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix4x2 left, float right, out Matrix4x2 result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - result.Row2.X = left.Row2.X * right; - result.Row2.Y = left.Row2.Y * right; - result.Row3.X = left.Row3.X * right; - result.Row3.Y = left.Row3.Y * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix4x2 Mult(Matrix4x2 left, float right) - { - Matrix4x2 result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix4x2 left, ref Matrix2 right, out Matrix4x2 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - lM41 = left.Row3.X, lM42 = left.Row3.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row3.X = (lM41 * rM11) + (lM42 * rM21); - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix4x2 Mult(Matrix4x2 left, Matrix2 right) - { - Matrix4x2 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix4x2 left, ref Matrix2x3 right, out Matrix4x3 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - lM41 = left.Row3.X, lM42 = left.Row3.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23); - result.Row3.X = (lM41 * rM11) + (lM42 * rM21); - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22); - result.Row3.Z = (lM41 * rM13) + (lM42 * rM23); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix4x3 Mult(Matrix4x2 left, Matrix2x3 right) - { - Matrix4x3 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix4x2 left, ref Matrix2x4 right, out Matrix4 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - lM41 = left.Row3.X, lM42 = left.Row3.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23); - result.Row2.W = (lM31 * rM14) + (lM32 * rM24); - result.Row3.X = (lM41 * rM11) + (lM42 * rM21); - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22); - result.Row3.Z = (lM41 * rM13) + (lM42 * rM23); - result.Row3.W = (lM41 * rM14) + (lM42 * rM24); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix4 Mult(Matrix4x2 left, Matrix2x4 right) - { - Matrix4 result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix4x2 left, ref Matrix4x2 right, out Matrix4x2 result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - result.Row2.X = left.Row2.X + right.Row2.X; - result.Row2.Y = left.Row2.Y + right.Row2.Y; - result.Row3.X = left.Row3.X + right.Row3.X; - result.Row3.Y = left.Row3.Y + right.Row3.Y; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix4x2 Add(Matrix4x2 left, Matrix4x2 right) - { - Matrix4x2 result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix4x2 left, ref Matrix4x2 right, out Matrix4x2 result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - result.Row2.X = left.Row2.X - right.Row2.X; - result.Row2.Y = left.Row2.Y - right.Row2.Y; - result.Row3.X = left.Row3.X - right.Row3.X; - result.Row3.Y = left.Row3.Y - right.Row3.Y; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix4x2 Subtract(Matrix4x2 left, Matrix4x2 right) - { - Matrix4x2 result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix4x2 mat, out Matrix2x4 result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row0.Z = mat.Row2.X; - result.Row0.W = mat.Row3.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - result.Row1.Z = mat.Row2.Y; - result.Row1.W = mat.Row3.Y; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix2x4 Transpose(Matrix4x2 mat) - { - Matrix2x4 result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x2 which holds the result of the multiplication - public static Matrix4x2 operator *(float left, Matrix4x2 right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x2 which holds the result of the multiplication - public static Matrix4x2 operator *(Matrix4x2 left, float right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2 which holds the result of the multiplication - public static Matrix4x2 operator *(Matrix4x2 left, Matrix2 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3 which holds the result of the multiplication - public static Matrix4x3 operator *(Matrix4x2 left, Matrix2x3 right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4 which holds the result of the multiplication - public static Matrix4 operator *(Matrix4x2 left, Matrix2x4 right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x2 which holds the result of the addition - public static Matrix4x2 operator +(Matrix4x2 left, Matrix4x2 right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x2 which holds the result of the subtraction - public static Matrix4x2 operator -(Matrix4x2 left, Matrix4x2 right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix4x2 left, Matrix4x2 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix4x2 left, Matrix4x2 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix3d. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}\n{2}\n{3}", Row0, Row1, Row2, Row3); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode() ^ Row3.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix4x2)) - return false; - - return this.Equals((Matrix4x2)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix4x2 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2 && - Row3 == other.Row3; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix4x2d.cs b/OpenTK/Math/Matrix4x2d.cs deleted file mode 100644 index bf494a19..00000000 --- a/OpenTK/Math/Matrix4x2d.cs +++ /dev/null @@ -1,786 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 4x2 matrix. - /// - public struct Matrix4x2d : IEquatable - { - #region Fields - - /// - /// Top row of the matrix. - /// - public Vector2d Row0; - - /// - /// Second row of the matrix. - /// - public Vector2d Row1; - - /// - /// Third row of the matrix. - /// - public Vector2d Row2; - - /// - /// Bottom row of the matrix. - /// - public Vector2d Row3; - - /// - /// The zero matrix. - /// - public static readonly Matrix4x2d Zero = new Matrix4x2d(Vector2d.Zero, Vector2d.Zero, Vector2d.Zero, Vector2d.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix. - /// Second row of the matrix. - /// Third row of the matrix. - /// Bottom row of the matrix. - public Matrix4x2d(Vector2d row0, Vector2d row1, Vector2d row2, Vector2d row3) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - Row3 = row3; - } - - - /// - /// Constructs a new instance - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// First item of the fourth row of the matrix. - /// Second item of the fourth row of the matrix. - public Matrix4x2d( - double m00, double m01, - double m10, double m11, - double m20, double m21, - double m30, double m31) - { - Row0 = new Vector2d(m00, m01); - Row1 = new Vector2d(m10, m11); - Row2 = new Vector2d(m20, m21); - Row3 = new Vector2d(m30, m31); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets or sets the first column of this matrix. - /// - public Vector4d Column0 - { - get { return new Vector4d(Row0.X, Row1.X, Row2.X, Row3.X); } - set { Row0.X = value.X; Row1.X = value.Y; Row2.X = value.Z; Row3.X = value.W; } - } - - /// - /// Gets or sets the second column of this matrix. - /// - public Vector4d Column1 - { - get { return new Vector4d(Row0.Y, Row1.Y, Row2.Y, Row3.X); } - set { Row0.Y = value.X; Row1.Y = value.Y; Row2.Y = value.Z; Row3.Y = value.W; } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public double M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public double M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public double M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public double M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 4, column 1 of this instance. - /// - public double M41 { get { return Row3.X; } set { Row3.X = value; } } - - /// - /// Gets or sets the value at row 4, column 2 of this instance. - /// - public double M42 { get { return Row3.Y; } set { Row3.Y = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector2d Diagonal - { - get - { - return new Vector2d(Row0.X, Row1.Y); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public double Trace { get { return Row0.X + Row1.Y; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public double this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - else if (rowIndex == 3) return Row3[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else if (rowIndex == 3) Row3[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Static - - #region CreateRotation - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3x2 instance. - public static void CreateRotation(double angle, out Matrix4x2d result) - { - double cos = (double)System.Math.Cos(angle); - double sin = (double)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row3.X = 0; - result.Row3.Y = 0; - } - - /// - /// Builds a rotation matrix. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix3x2 instance. - public static Matrix4x2d CreateRotation(double angle) - { - Matrix4x2d result; - CreateRotation(angle, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x, y, and z axes. - /// A scale matrix. - public static void CreateScale(double scale, out Matrix4x2d result) - { - result.Row0.X = scale; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row3.X = 0; - result.Row3.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Single scale factor for the x and y axes. - /// A scale matrix. - public static Matrix4x2d CreateScale(double scale) - { - Matrix4x2d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static void CreateScale(Vector2d scale, out Matrix4x2d result) - { - result.Row0.X = scale.X; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = scale.Y; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row3.X = 0; - result.Row3.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factors for the x and y axes. - /// A scale matrix. - public static Matrix4x2d CreateScale(Vector2d scale) - { - Matrix4x2d result; - CreateScale(scale, out result); - return result; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static void CreateScale(double x, double y, out Matrix4x2d result) - { - result.Row0.X = x; - result.Row0.Y = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row3.X = 0; - result.Row3.Y = 0; - } - - /// - /// Creates a scale matrix. - /// - /// Scale factor for the x axis. - /// Scale factor for the y axis. - /// A scale matrix. - public static Matrix4x2d CreateScale(double x, double y) - { - Matrix4x2d result; - CreateScale(x, y, out result); - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix4x2d left, double right, out Matrix4x2d result) - { - result.Row0.X = left.Row0.X * right; - result.Row0.Y = left.Row0.Y * right; - result.Row1.X = left.Row1.X * right; - result.Row1.Y = left.Row1.Y * right; - result.Row2.X = left.Row2.X * right; - result.Row2.Y = left.Row2.Y * right; - result.Row3.X = left.Row3.X * right; - result.Row3.Y = left.Row3.Y * right; - } - - /// - /// Multiplies and instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix4x2d Mult(Matrix4x2d left, double right) - { - Matrix4x2d result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix4x2d left, ref Matrix2d right, out Matrix4x2d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - lM41 = left.Row3.X, lM42 = left.Row3.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, - rM21 = right.Row1.X, rM22 = right.Row1.Y; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row3.X = (lM41 * rM11) + (lM42 * rM21); - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix4x2d Mult(Matrix4x2d left, Matrix2d right) - { - Matrix4x2d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix4x2d left, ref Matrix2x3d right, out Matrix4x3d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - lM41 = left.Row3.X, lM42 = left.Row3.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23); - result.Row3.X = (lM41 * rM11) + (lM42 * rM21); - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22); - result.Row3.Z = (lM41 * rM13) + (lM42 * rM23); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix4x3d Mult(Matrix4x2d left, Matrix2x3d right) - { - Matrix4x3d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static void Mult(ref Matrix4x2d left, ref Matrix2x4d right, out Matrix4d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, - lM21 = left.Row1.X, lM22 = left.Row1.Y, - lM31 = left.Row2.X, lM32 = left.Row2.Y, - lM41 = left.Row3.X, lM42 = left.Row3.Y, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23); - result.Row2.W = (lM31 * rM14) + (lM32 * rM24); - result.Row3.X = (lM41 * rM11) + (lM42 * rM21); - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22); - result.Row3.Z = (lM41 * rM13) + (lM42 * rM23); - result.Row3.W = (lM41 * rM14) + (lM42 * rM24); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication. - public static Matrix4d Mult(Matrix4x2d left, Matrix2x4d right) - { - Matrix4d result; - Mult(ref left, ref right, out result); - return result; - } - - #endregion - - #region Add - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix4x2d left, ref Matrix4x2d right, out Matrix4x2d result) - { - result.Row0.X = left.Row0.X + right.Row0.X; - result.Row0.Y = left.Row0.Y + right.Row0.Y; - result.Row1.X = left.Row1.X + right.Row1.X; - result.Row1.Y = left.Row1.Y + right.Row1.Y; - result.Row2.X = left.Row2.X + right.Row2.X; - result.Row2.Y = left.Row2.Y + right.Row2.Y; - result.Row3.X = left.Row3.X + right.Row3.X; - result.Row3.Y = left.Row3.Y + right.Row3.Y; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix4x2d Add(Matrix4x2d left, Matrix4x2d right) - { - Matrix4x2d result; - Add(ref left, ref right, out result); - return result; - } - - #endregion - - #region Subtract - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static void Subtract(ref Matrix4x2d left, ref Matrix4x2d right, out Matrix4x2d result) - { - result.Row0.X = left.Row0.X - right.Row0.X; - result.Row0.Y = left.Row0.Y - right.Row0.Y; - result.Row1.X = left.Row1.X - right.Row1.X; - result.Row1.Y = left.Row1.Y - right.Row1.Y; - result.Row2.X = left.Row2.X - right.Row2.X; - result.Row2.Y = left.Row2.Y - right.Row2.Y; - result.Row3.X = left.Row3.X - right.Row3.X; - result.Row3.Y = left.Row3.Y - right.Row3.Y; - } - - /// - /// Subtracts two instances. - /// - /// The left operand of the subtraction. - /// The right operand of the subtraction. - /// A new instance that is the result of the subtraction. - public static Matrix4x2d Subtract(Matrix4x2d left, Matrix4x2d right) - { - Matrix4x2d result; - Subtract(ref left, ref right, out result); - return result; - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static void Transpose(ref Matrix4x2d mat, out Matrix2x4d result) - { - result.Row0.X = mat.Row0.X; - result.Row0.Y = mat.Row1.X; - result.Row0.Z = mat.Row2.X; - result.Row0.W = mat.Row3.X; - result.Row1.X = mat.Row0.Y; - result.Row1.Y = mat.Row1.Y; - result.Row1.Z = mat.Row2.Y; - result.Row1.W = mat.Row3.Y; - } - - /// - /// Calculate the transpose of the given matrix. - /// - /// The matrix to transpose. - /// The transpose of the given matrix. - public static Matrix2x4d Transpose(Matrix4x2d mat) - { - Matrix2x4d result; - Transpose(ref mat, out result); - return result; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x2d which holds the result of the multiplication - public static Matrix4x2d operator *(double left, Matrix4x2d right) - { - return Mult(right, left); - } - - /// - /// Scalar multiplication. - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x2d which holds the result of the multiplication - public static Matrix4x2d operator *(Matrix4x2d left, double right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix2d which holds the result of the multiplication - public static Matrix4x2d operator *(Matrix4x2d left, Matrix2d right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3d which holds the result of the multiplication - public static Matrix4x3d operator *(Matrix4x2d left, Matrix2x3d right) - { - return Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4d which holds the result of the multiplication - public static Matrix4d operator *(Matrix4x2d left, Matrix2x4d right) - { - return Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x2d which holds the result of the addition - public static Matrix4x2d operator +(Matrix4x2d left, Matrix4x2d right) - { - return Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x2d which holds the result of the subtraction - public static Matrix4x2d operator -(Matrix4x2d left, Matrix4x2d right) - { - return Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix4x2d left, Matrix4x2d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix4x2d left, Matrix4x2d right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix3d. - /// - /// The string representation of the matrix. - public override string ToString() - { - return String.Format("{0}\n{1}\n{2}\n{3}", Row0, Row1, Row2, Row3); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode() ^ Row3.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix4x2d)) - return false; - - return this.Equals((Matrix4x2d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether the current matrix is equal to another matrix. - /// - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix4x2d other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2 && - Row3 == other.Row3; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix4x3.cs b/OpenTK/Math/Matrix4x3.cs deleted file mode 100644 index e7fd6788..00000000 --- a/OpenTK/Math/Matrix4x3.cs +++ /dev/null @@ -1,1007 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 3x4 matrix. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Matrix4x3 : IEquatable - { - #region Fields - - /// - /// Top row of the matrix - /// - public Vector3 Row0; - - /// - /// 2nd row of the matrix - /// - public Vector3 Row1; - - /// - /// 3rd row of the matrix - /// - public Vector3 Row2; - - /// - /// Bottom row of the matrix - /// - public Vector3 Row3; - - /// - /// The zero matrix - /// - public static readonly Matrix4x3 Zero = new Matrix4x3(Vector3.Zero, Vector3.Zero, Vector3.Zero, Vector3.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix - /// Second row of the matrix - /// Third row of the matrix - /// Bottom row of the matrix - public Matrix4x3(Vector3 row0, Vector3 row1, Vector3 row2, Vector3 row3) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - Row3 = row3; - } - - /// - /// Constructs a new instance. - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// Third item of the third row of the matrix. - /// First item of the fourth row of the matrix. - /// Second item of the fourth row of the matrix. - /// Third item of the fourth row of the matrix. - public Matrix4x3( - float m00, float m01, float m02, - float m10, float m11, float m12, - float m20, float m21, float m22, - float m30, float m31, float m32) - { - Row0 = new Vector3(m00, m01, m02); - Row1 = new Vector3(m10, m11, m12); - Row2 = new Vector3(m20, m21, m22); - Row3 = new Vector3(m30, m31, m32); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets the first column of this matrix. - /// - public Vector4 Column0 - { - get { return new Vector4(Row0.X, Row1.X, Row2.X, Row3.X); } - } - - /// - /// Gets the second column of this matrix. - /// - public Vector4 Column1 - { - get { return new Vector4(Row0.Y, Row1.Y, Row2.Y, Row3.Y); } - } - - /// - /// Gets the third column of this matrix. - /// - public Vector4 Column2 - { - get { return new Vector4(Row0.Z, Row1.Z, Row2.Z, Row3.Z); } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public float M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public float M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public float M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public float M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public float M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public float M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public float M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public float M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 3 of this instance. - /// - public float M33 { get { return Row2.Z; } set { Row2.Z = value; } } - - /// - /// Gets or sets the value at row 4, column 1 of this instance. - /// - public float M41 { get { return Row3.X; } set { Row3.X = value; } } - - /// - /// Gets or sets the value at row 4, column 2 of this instance. - /// - public float M42 { get { return Row3.Y; } set { Row3.Y = value; } } - - /// - /// Gets or sets the value at row 4, column 3 of this instance. - /// - public float M43 { get { return Row3.Z; } set { Row3.Z = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector3 Diagonal - { - get - { - return new Vector3(Row0.X, Row1.Y, Row2.Z); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - Row2.Z = value.Z; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public float Trace { get { return Row0.X + Row1.Y + Row2.Z; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public float this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - else if (rowIndex == 3) return Row3[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else if (rowIndex == 3) Row3[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Invert() - - /// - /// Converts this instance into it's inverse by inverting the upper-left 3x3 and replacing Row3. - /// - public void Invert() - { - this = Matrix4x3.Invert(this); - } - - #endregion - - #endregion - - #region Static - - #region CreateFromAxisAngle - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static void CreateFromAxisAngle(Vector3 axis, float angle, out Matrix4x3 result) - { - axis.Normalize(); - float axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; - - float cos = (float)System.Math.Cos(-angle); - float sin = (float)System.Math.Sin(-angle); - float t = 1.0f - cos; - - float tXX = t * axisX * axisX, - tXY = t * axisX * axisY, - tXZ = t * axisX * axisZ, - tYY = t * axisY * axisY, - tYZ = t * axisY * axisZ, - tZZ = t * axisZ * axisZ; - - float sinX = sin * axisX, - sinY = sin * axisY, - sinZ = sin * axisZ; - - result.Row0.X = tXX + cos; - result.Row0.Y = tXY - sinZ; - result.Row0.Z = tXZ + sinY; - result.Row1.X = tXY + sinZ; - result.Row1.Y = tYY + cos; - result.Row1.Z = tYZ - sinX; - result.Row2.X = tXZ - sinY; - result.Row2.Y = tYZ + sinX; - result.Row2.Z = tZZ + cos; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - } - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static Matrix4x3 CreateFromAxisAngle(Vector3 axis, float angle) - { - Matrix4x3 result; - CreateFromAxisAngle(axis, angle, out result); - return result; - } - - #endregion - - #region CreateFromQuaternion - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static void CreateFromQuaternion(ref Quaternion q, out Matrix4x3 result) - { - float x = q.X, y = q.Y, z = q.Z, w = q.W, - tx = 2 * x, ty = 2 * y, tz = 2 * z, - txx = tx * x, tyy = ty * y, tzz = tz * z, - txy = tx * y, txz = tx * z, tyz = ty * z, - twx = w * tx, twy = w * ty, twz = w * tz; - - result.Row0.X = 1f - tyy - tzz; - result.Row0.Y = txy - twz; - result.Row0.Z = txz + twy; - result.Row1.X = txy + twz; - result.Row1.Y = 1f - txx - tzz; - result.Row1.Z = tyz - twx; - result.Row2.X = txz - twy; - result.Row2.Y = tyz + twx; - result.Row2.Z = 1f - txx - tyy; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - - /*Vector3 axis; - float angle; - q.ToAxisAngle(out axis, out angle); - CreateFromAxisAngle(axis, angle, out result);*/ - } - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static Matrix4x3 CreateFromQuaternion(Quaternion q) - { - Matrix4x3 result; - CreateFromQuaternion(ref q, out result); - return result; - } - - #endregion - - #region CreateRotation[XYZ] - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationX(float angle, out Matrix4x3 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = cos; - result.Row1.Z = sin; - result.Row2.X = 0; - result.Row2.Y = -sin; - result.Row2.Z = cos; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix4x3 CreateRotationX(float angle) - { - Matrix4x3 result; - CreateRotationX(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationY(float angle, out Matrix4x3 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = 0; - result.Row0.Z = -sin; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row2.X = sin; - result.Row2.Y = 0; - result.Row2.Z = cos; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix4x3 CreateRotationY(float angle) - { - Matrix4x3 result; - CreateRotationY(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static void CreateRotationZ(float angle, out Matrix4x3 result) - { - float cos = (float)System.Math.Cos(angle); - float sin = (float)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row0.Z = 0; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row1.Z = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4 instance. - public static Matrix4x3 CreateRotationZ(float angle) - { - Matrix4x3 result; - CreateRotationZ(angle, out result); - return result; - } - - #endregion - - #region CreateTranslation - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - public static void CreateTranslation(float x, float y, float z, out Matrix4x3 result) - { - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row3.X = x; - result.Row3.Y = y; - result.Row3.Z = z; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - public static void CreateTranslation(ref Vector3 vector, out Matrix4x3 result) - { - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row3.X = vector.X; - result.Row3.Y = vector.Y; - result.Row3.Z = vector.Z; - } - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4 instance. - public static Matrix4x3 CreateTranslation(float x, float y, float z) - { - Matrix4x3 result; - CreateTranslation(x, y, z, out result); - return result; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4 instance. - public static Matrix4x3 CreateTranslation(Vector3 vector) - { - Matrix4x3 result; - CreateTranslation(vector.X, vector.Y, vector.Z, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Build a scaling matrix - /// - /// Single scale factor for x,y and z axes - /// A scaling matrix - public static Matrix4x3 CreateScale(float scale) - { - return CreateScale(scale, scale, scale); - } - - /// - /// Build a scaling matrix - /// - /// Scale factors for x,y and z axes - /// A scaling matrix - public static Matrix4x3 CreateScale(Vector3 scale) - { - return CreateScale(scale.X, scale.Y, scale.Z); - } - - /// - /// Build a scaling matrix - /// - /// Scale factor for x-axis - /// Scale factor for y-axis - /// Scale factor for z-axis - /// A scaling matrix - public static Matrix4x3 CreateScale(float x, float y, float z) - { - Matrix4x3 result; - result.Row0.X = x; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row1.Z = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = z; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// This isn't quite a multiply, but the result may be useful in some situations. - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix4 Mult(Matrix4x3 left, Matrix3x4 right) - { - Matrix4 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// This isn't quite a multiply, but the result may be useful in some situations. - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix4x3 left, ref Matrix3x4 right, out Matrix4 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, - lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24) + (lM13 * rM34); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24) + (lM23 * rM34); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33); - result.Row2.W = (lM31 * rM14) + (lM32 * rM24) + (lM33 * rM34); - result.Row3.X = (lM41 * rM11) + (lM42 * rM21) + (lM43 * rM31); - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22) + (lM43 * rM32); - result.Row3.Z = (lM41 * rM13) + (lM42 * rM23) + (lM43 * rM33); - result.Row3.W = (lM41 * rM14) + (lM42 * rM24) + (lM43 * rM34); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix4x3 Mult(Matrix4x3 left, Matrix4x3 right) - { - Matrix4x3 result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// This isn't quite a multiply, but the result may be useful in some situations. - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix4x3 left, ref Matrix4x3 right, out Matrix4x3 result) - { - float lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, - lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31) + rM41; - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32) + rM42; - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33) + rM43; - result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31) + rM41; - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32) + rM42; - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33) + rM43; - result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31) + rM41; - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32) + rM42; - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33) + rM43; - result.Row3.X = (lM41 * rM11) + (lM42 * rM21) + (lM43 * rM31) + rM41; - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22) + (lM43 * rM32) + rM42; - result.Row3.Z = (lM41 * rM13) + (lM42 * rM23) + (lM43 * rM33) + rM43; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix4x3 Mult(Matrix4x3 left, float right) - { - Matrix4x3 result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix4x3 left, float right, out Matrix4x3 result) - { - result.Row0 = left.Row0 * right; - result.Row1 = left.Row1 * right; - result.Row2 = left.Row2 * right; - result.Row3 = left.Row3 * right; - } - - #endregion - - #region Add Functions - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix4x3 Add(Matrix4x3 left, Matrix4x3 right) - { - Matrix4x3 result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix4x3 left, ref Matrix4x3 right, out Matrix4x3 result) - { - result.Row0 = left.Row0 + right.Row0; - result.Row1 = left.Row1 + right.Row1; - result.Row2 = left.Row2 + right.Row2; - result.Row3 = left.Row3 + right.Row3; - } - - #endregion - - #region Subtract Functions - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static Matrix4x3 Subtract(Matrix4x3 left, Matrix4x3 right) - { - Matrix4x3 result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static void Subtract(ref Matrix4x3 left, ref Matrix4x3 right, out Matrix4x3 result) - { - result.Row0 = left.Row0 - right.Row0; - result.Row1 = left.Row1 - right.Row1; - result.Row2 = left.Row2 - right.Row2; - result.Row3 = left.Row3 - right.Row3; - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static Matrix4x3 Invert(Matrix4x3 mat) - { - Matrix4x3 result; - Invert(ref mat, out result); - return result; - } - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static void Invert(ref Matrix4x3 mat, out Matrix4x3 result) - { - Matrix3 inverseRotation = new Matrix3(mat.Column0.Xyz, mat.Column1.Xyz, mat.Column2.Xyz); - inverseRotation.Row0 /= inverseRotation.Row0.LengthSquared; - inverseRotation.Row1 /= inverseRotation.Row1.LengthSquared; - inverseRotation.Row2 /= inverseRotation.Row2.LengthSquared; - - Vector3 translation = mat.Row3; - - result.Row0 = inverseRotation.Row0; - result.Row1 = inverseRotation.Row1; - result.Row2 = inverseRotation.Row2; - result.Row3 = new Vector3(-Vector3.Dot(inverseRotation.Row0, translation), -Vector3.Dot(inverseRotation.Row1, translation), -Vector3.Dot(inverseRotation.Row2, translation)); - } - - #endregion - - #region Transpose - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The transpose of the given matrix - public static Matrix3x4 Transpose(Matrix4x3 mat) - { - return new Matrix3x4(mat.Column0, mat.Column1, mat.Column2); - } - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The result of the calculation - public static void Transpose(ref Matrix4x3 mat, out Matrix3x4 result) - { - result.Row0 = mat.Column0; - result.Row1 = mat.Column1; - result.Row2 = mat.Column2; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4 which holds the result of the multiplication - public static Matrix4 operator *(Matrix4x3 left, Matrix3x4 right) - { - return Matrix4x3.Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3 which holds the result of the multiplication - public static Matrix4x3 operator *(Matrix4x3 left, Matrix4x3 right) - { - return Matrix4x3.Mult(left, right); - } - - /// - /// Matrix-scalar multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3 which holds the result of the multiplication - public static Matrix4x3 operator *(Matrix4x3 left, float right) - { - return Matrix4x3.Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3 which holds the result of the addition - public static Matrix4x3 operator +(Matrix4x3 left, Matrix4x3 right) - { - return Matrix4x3.Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3 which holds the result of the subtraction - public static Matrix4x3 operator -(Matrix4x3 left, Matrix4x3 right) - { - return Matrix4x3.Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix4x3 left, Matrix4x3 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix4x3 left, Matrix4x3 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix4x3. - /// - /// The string representation of the matrix. - public override string ToString() - { - return string.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare tresult. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix4x3)) - return false; - - return this.Equals((Matrix4x3)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current matrix is equal to another matrix. - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix4x3 other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2 && - Row3 == other.Row3; - } - - #endregion - } -} diff --git a/OpenTK/Math/Matrix4x3d.cs b/OpenTK/Math/Matrix4x3d.cs deleted file mode 100644 index 908477fd..00000000 --- a/OpenTK/Math/Matrix4x3d.cs +++ /dev/null @@ -1,1007 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; - -namespace OpenTK -{ - /// - /// Represents a 3x4 matrix. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Matrix4x3d : IEquatable - { - #region Fields - - /// - /// Top row of the matrix - /// - public Vector3d Row0; - - /// - /// 2nd row of the matrix - /// - public Vector3d Row1; - - /// - /// 3rd row of the matrix - /// - public Vector3d Row2; - - /// - /// Bottom row of the matrix - /// - public Vector3d Row3; - - /// - /// The zero matrix - /// - public static Matrix4x3d Zero = new Matrix4x3d(Vector3d.Zero, Vector3d.Zero, Vector3d.Zero, Vector3d.Zero); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// Top row of the matrix - /// Second row of the matrix - /// Third row of the matrix - /// Bottom row of the matrix - public Matrix4x3d(Vector3d row0, Vector3d row1, Vector3d row2, Vector3d row3) - { - Row0 = row0; - Row1 = row1; - Row2 = row2; - Row3 = row3; - } - - /// - /// Constructs a new instance. - /// - /// First item of the first row of the matrix. - /// Second item of the first row of the matrix. - /// Third item of the first row of the matrix. - /// First item of the second row of the matrix. - /// Second item of the second row of the matrix. - /// Third item of the second row of the matrix. - /// First item of the third row of the matrix. - /// Second item of the third row of the matrix. - /// Third item of the third row of the matrix. - /// First item of the fourth row of the matrix. - /// Second item of the fourth row of the matrix. - /// Third item of the fourth row of the matrix. - public Matrix4x3d( - double m00, double m01, double m02, - double m10, double m11, double m12, - double m20, double m21, double m22, - double m30, double m31, double m32) - { - Row0 = new Vector3d(m00, m01, m02); - Row1 = new Vector3d(m10, m11, m12); - Row2 = new Vector3d(m20, m21, m22); - Row3 = new Vector3d(m30, m31, m32); - } - - #endregion - - #region Public Members - - #region Properties - - /// - /// Gets the first column of this matrix. - /// - public Vector4d Column0 - { - get { return new Vector4d(Row0.X, Row1.X, Row2.X, Row3.X); } - } - - /// - /// Gets the second column of this matrix. - /// - public Vector4d Column1 - { - get { return new Vector4d(Row0.Y, Row1.Y, Row2.Y, Row3.Y); } - } - - /// - /// Gets the third column of this matrix. - /// - public Vector4d Column2 - { - get { return new Vector4d(Row0.Z, Row1.Z, Row2.Z, Row3.Z); } - } - - /// - /// Gets or sets the value at row 1, column 1 of this instance. - /// - public double M11 { get { return Row0.X; } set { Row0.X = value; } } - - /// - /// Gets or sets the value at row 1, column 2 of this instance. - /// - public double M12 { get { return Row0.Y; } set { Row0.Y = value; } } - - /// - /// Gets or sets the value at row 1, column 3 of this instance. - /// - public double M13 { get { return Row0.Z; } set { Row0.Z = value; } } - - /// - /// Gets or sets the value at row 2, column 1 of this instance. - /// - public double M21 { get { return Row1.X; } set { Row1.X = value; } } - - /// - /// Gets or sets the value at row 2, column 2 of this instance. - /// - public double M22 { get { return Row1.Y; } set { Row1.Y = value; } } - - /// - /// Gets or sets the value at row 2, column 3 of this instance. - /// - public double M23 { get { return Row1.Z; } set { Row1.Z = value; } } - - /// - /// Gets or sets the value at row 3, column 1 of this instance. - /// - public double M31 { get { return Row2.X; } set { Row2.X = value; } } - - /// - /// Gets or sets the value at row 3, column 2 of this instance. - /// - public double M32 { get { return Row2.Y; } set { Row2.Y = value; } } - - /// - /// Gets or sets the value at row 3, column 3 of this instance. - /// - public double M33 { get { return Row2.Z; } set { Row2.Z = value; } } - - /// - /// Gets or sets the value at row 4, column 1 of this instance. - /// - public double M41 { get { return Row3.X; } set { Row3.X = value; } } - - /// - /// Gets or sets the value at row 4, column 2 of this instance. - /// - public double M42 { get { return Row3.Y; } set { Row3.Y = value; } } - - /// - /// Gets or sets the value at row 4, column 3 of this instance. - /// - public double M43 { get { return Row3.Z; } set { Row3.Z = value; } } - - /// - /// Gets or sets the values along the main diagonal of the matrix. - /// - public Vector3d Diagonal - { - get - { - return new Vector3d(Row0.X, Row1.Y, Row2.Z); - } - set - { - Row0.X = value.X; - Row1.Y = value.Y; - Row2.Z = value.Z; - } - } - - /// - /// Gets the trace of the matrix, the sum of the values along the diagonal. - /// - public double Trace { get { return Row0.X + Row1.Y + Row2.Z; } } - - #endregion - - #region Indexers - - /// - /// Gets or sets the value at a specified row and column. - /// - public double this[int rowIndex, int columnIndex] - { - get - { - if (rowIndex == 0) return Row0[columnIndex]; - else if (rowIndex == 1) return Row1[columnIndex]; - else if (rowIndex == 2) return Row2[columnIndex]; - else if (rowIndex == 3) return Row3[columnIndex]; - throw new IndexOutOfRangeException("You tried to access this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - set - { - if (rowIndex == 0) Row0[columnIndex] = value; - else if (rowIndex == 1) Row1[columnIndex] = value; - else if (rowIndex == 2) Row2[columnIndex] = value; - else if (rowIndex == 3) Row3[columnIndex] = value; - else throw new IndexOutOfRangeException("You tried to set this matrix at: (" + rowIndex + ", " + columnIndex + ")"); - } - } - - #endregion - - #region Instance - - #region public void Invert() - - /// - /// Converts this instance into its inverse. - /// - public void Invert() - { - this = Matrix4x3d.Invert(this); - } - - #endregion - - #endregion - - #region Static - - #region CreateFromAxisAngle - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static void CreateFromAxisAngle(Vector3d axis, double angle, out Matrix4x3d result) - { - axis.Normalize(); - double axisX = axis.X, axisY = axis.Y, axisZ = axis.Z; - - double cos = (double)System.Math.Cos(-angle); - double sin = (double)System.Math.Sin(-angle); - double t = 1.0f - cos; - - double tXX = t * axisX * axisX, - tXY = t * axisX * axisY, - tXZ = t * axisX * axisZ, - tYY = t * axisY * axisY, - tYZ = t * axisY * axisZ, - tZZ = t * axisZ * axisZ; - - double sinX = sin * axisX, - sinY = sin * axisY, - sinZ = sin * axisZ; - - result.Row0.X = tXX + cos; - result.Row0.Y = tXY - sinZ; - result.Row0.Z = tXZ + sinY; - result.Row1.X = tXY + sinZ; - result.Row1.Y = tYY + cos; - result.Row1.Z = tYZ - sinX; - result.Row2.X = tXZ - sinY; - result.Row2.Y = tYZ + sinX; - result.Row2.Z = tZZ + cos; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - } - - /// - /// Build a rotation matrix from the specified axis/angle rotation. - /// - /// The axis to rotate about. - /// Angle in radians to rotate counter-clockwise (looking in the direction of the given axis). - /// A matrix instance. - public static Matrix4x3d CreateFromAxisAngle(Vector3d axis, double angle) - { - Matrix4x3d result; - CreateFromAxisAngle(axis, angle, out result); - return result; - } - - #endregion - - #region CreateFromQuaternion - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static void CreateFromQuaternion(ref Quaternion q, out Matrix4x3d result) - { - double x = q.X, y = q.Y, z = q.Z, w = q.W, - tx = 2 * x, ty = 2 * y, tz = 2 * z, - txx = tx * x, tyy = ty * y, tzz = tz * z, - txy = tx * y, txz = tx * z, tyz = ty * z, - twx = w * tx, twy = w * ty, twz = w * tz; - - result.Row0.X = 1f - tyy - tzz; - result.Row0.Y = txy - twz; - result.Row0.Z = txz + twy; - result.Row1.X = txy + twz; - result.Row1.Y = 1f - txx - tzz; - result.Row1.Z = tyz - twx; - result.Row2.X = txz - twy; - result.Row2.Y = tyz + twx; - result.Row2.Z = 1f - txx - tyy; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - - /*Vector3d axis; - double angle; - q.ToAxisAngle(out axis, out angle); - CreateFromAxisAngle(axis, angle, out result);*/ - } - - /// - /// Builds a rotation matrix from a quaternion. - /// - /// The quaternion to rotate by. - /// A matrix instance. - public static Matrix4x3d CreateFromQuaternion(Quaternion q) - { - Matrix4x3d result; - CreateFromQuaternion(ref q, out result); - return result; - } - - #endregion - - #region CreateRotation[XYZ] - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4dinstance. - public static void CreateRotationX(double angle, out Matrix4x3d result) - { - double cos = (double)System.Math.Cos(angle); - double sin = (double)System.Math.Sin(angle); - - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = cos; - result.Row1.Z = sin; - result.Row2.X = 0; - result.Row2.Y = -sin; - result.Row2.Z = cos; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the x-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4dinstance. - public static Matrix4x3d CreateRotationX(double angle) - { - Matrix4x3d result; - CreateRotationX(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4dinstance. - public static void CreateRotationY(double angle, out Matrix4x3d result) - { - double cos = (double)System.Math.Cos(angle); - double sin = (double)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = 0; - result.Row0.Z = -sin; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row2.X = sin; - result.Row2.Y = 0; - result.Row2.Z = cos; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the y-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4dinstance. - public static Matrix4x3d CreateRotationY(double angle) - { - Matrix4x3d result; - CreateRotationY(angle, out result); - return result; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4dinstance. - public static void CreateRotationZ(double angle, out Matrix4x3d result) - { - double cos = (double)System.Math.Cos(angle); - double sin = (double)System.Math.Sin(angle); - - result.Row0.X = cos; - result.Row0.Y = sin; - result.Row0.Z = 0; - result.Row1.X = -sin; - result.Row1.Y = cos; - result.Row1.Z = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - } - - /// - /// Builds a rotation matrix for a rotation around the z-axis. - /// - /// The counter-clockwise angle in radians. - /// The resulting Matrix4dinstance. - public static Matrix4x3d CreateRotationZ(double angle) - { - Matrix4x3d result; - CreateRotationZ(angle, out result); - return result; - } - - #endregion - - #region CreateTranslation - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4dinstance. - public static void CreateTranslation(double x, double y, double z, out Matrix4x3d result) - { - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row3.X = x; - result.Row3.Y = y; - result.Row3.Z = z; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4dinstance. - public static void CreateTranslation(ref Vector3d vector, out Matrix4x3d result) - { - result.Row0.X = 1; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = 1; - result.Row1.Z = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = 1; - result.Row3.X = vector.X; - result.Row3.Y = vector.Y; - result.Row3.Z = vector.Z; - } - - /// - /// Creates a translation matrix. - /// - /// X translation. - /// Y translation. - /// Z translation. - /// The resulting Matrix4dinstance. - public static Matrix4x3d CreateTranslation(double x, double y, double z) - { - Matrix4x3d result; - CreateTranslation(x, y, z, out result); - return result; - } - - /// - /// Creates a translation matrix. - /// - /// The translation vector. - /// The resulting Matrix4dinstance. - public static Matrix4x3d CreateTranslation(Vector3d vector) - { - Matrix4x3d result; - CreateTranslation(vector.X, vector.Y, vector.Z, out result); - return result; - } - - #endregion - - #region CreateScale - - /// - /// Build a scaling matrix - /// - /// Single scale factor for x,y and z axes - /// A scaling matrix - public static Matrix4x3d CreateScale(double scale) - { - return CreateScale(scale, scale, scale); - } - - /// - /// Build a scaling matrix - /// - /// Scale factors for x,y and z axes - /// A scaling matrix - public static Matrix4x3d CreateScale(Vector3d scale) - { - return CreateScale(scale.X, scale.Y, scale.Z); - } - - /// - /// Build a scaling matrix - /// - /// Scale factor for x-axis - /// Scale factor for y-axis - /// Scale factor for z-axis - /// A scaling matrix - public static Matrix4x3d CreateScale(double x, double y, double z) - { - Matrix4x3d result; - result.Row0.X = x; - result.Row0.Y = 0; - result.Row0.Z = 0; - result.Row1.X = 0; - result.Row1.Y = y; - result.Row1.Z = 0; - result.Row2.X = 0; - result.Row2.Y = 0; - result.Row2.Z = z; - result.Row3.X = 0; - result.Row3.Y = 0; - result.Row3.Z = 0; - return result; - } - - #endregion - - #region Multiply Functions - - /// - /// This isn't quite a multiply, but the result may be useful in some situations. - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix4d Mult(Matrix4x3d left, Matrix3x4d right) - { - Matrix4d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// This isn't quite a multiply, but the result may be useful in some situations. - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix4x3d left, ref Matrix3x4d right, out Matrix4d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, - lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, rM14 = right.Row0.W, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, rM24 = right.Row1.W, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, rM34 = right.Row2.W; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31); - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32); - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33); - result.Row0.W = (lM11 * rM14) + (lM12 * rM24) + (lM13 * rM34); - result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31); - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32); - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33); - result.Row1.W = (lM21 * rM14) + (lM22 * rM24) + (lM23 * rM34); - result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31); - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32); - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33); - result.Row2.W = (lM31 * rM14) + (lM32 * rM24) + (lM33 * rM34); - result.Row3.X = (lM41 * rM11) + (lM42 * rM21) + (lM43 * rM31); - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22) + (lM43 * rM32); - result.Row3.Z = (lM41 * rM13) + (lM42 * rM23) + (lM43 * rM33); - result.Row3.W = (lM41 * rM14) + (lM42 * rM24) + (lM43 * rM34); - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix4x3d Mult(Matrix4x3d left, Matrix4x3d right) - { - Matrix4x3d result; - Mult(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix4x3d left, ref Matrix4x3d right, out Matrix4x3d result) - { - double lM11 = left.Row0.X, lM12 = left.Row0.Y, lM13 = left.Row0.Z, - lM21 = left.Row1.X, lM22 = left.Row1.Y, lM23 = left.Row1.Z, - lM31 = left.Row2.X, lM32 = left.Row2.Y, lM33 = left.Row2.Z, - lM41 = left.Row3.X, lM42 = left.Row3.Y, lM43 = left.Row3.Z, - rM11 = right.Row0.X, rM12 = right.Row0.Y, rM13 = right.Row0.Z, - rM21 = right.Row1.X, rM22 = right.Row1.Y, rM23 = right.Row1.Z, - rM31 = right.Row2.X, rM32 = right.Row2.Y, rM33 = right.Row2.Z, - rM41 = right.Row3.X, rM42 = right.Row3.Y, rM43 = right.Row3.Z; - - result.Row0.X = (lM11 * rM11) + (lM12 * rM21) + (lM13 * rM31) + rM41; - result.Row0.Y = (lM11 * rM12) + (lM12 * rM22) + (lM13 * rM32) + rM42; - result.Row0.Z = (lM11 * rM13) + (lM12 * rM23) + (lM13 * rM33) + rM43; - result.Row1.X = (lM21 * rM11) + (lM22 * rM21) + (lM23 * rM31) + rM41; - result.Row1.Y = (lM21 * rM12) + (lM22 * rM22) + (lM23 * rM32) + rM42; - result.Row1.Z = (lM21 * rM13) + (lM22 * rM23) + (lM23 * rM33) + rM43; - result.Row2.X = (lM31 * rM11) + (lM32 * rM21) + (lM33 * rM31) + rM41; - result.Row2.Y = (lM31 * rM12) + (lM32 * rM22) + (lM33 * rM32) + rM42; - result.Row2.Z = (lM31 * rM13) + (lM32 * rM23) + (lM33 * rM33) + rM43; - result.Row3.X = (lM41 * rM11) + (lM42 * rM21) + (lM43 * rM31) + rM41; - result.Row3.Y = (lM41 * rM12) + (lM42 * rM22) + (lM43 * rM32) + rM42; - result.Row3.Z = (lM41 * rM13) + (lM42 * rM23) + (lM43 * rM33) + rM43; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static Matrix4x3d Mult(Matrix4x3d left, double right) - { - Matrix4x3d result; - Mult(ref left, right, out result); - return result; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The left operand of the multiplication. - /// The right operand of the multiplication. - /// A new instance that is the result of the multiplication - public static void Mult(ref Matrix4x3d left, double right, out Matrix4x3d result) - { - result.Row0 = left.Row0 * right; - result.Row1 = left.Row1 * right; - result.Row2 = left.Row2 * right; - result.Row3 = left.Row3 * right; - } - - #endregion - - #region Add Functions - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static Matrix4x3d Add(Matrix4x3d left, Matrix4x3d right) - { - Matrix4x3d result; - Add(ref left, ref right, out result); - return result; - } - - /// - /// Adds two instances. - /// - /// The left operand of the addition. - /// The right operand of the addition. - /// A new instance that is the result of the addition. - public static void Add(ref Matrix4x3d left, ref Matrix4x3d right, out Matrix4x3d result) - { - result.Row0 = left.Row0 + right.Row0; - result.Row1 = left.Row1 + right.Row1; - result.Row2 = left.Row2 + right.Row2; - result.Row3 = left.Row3 + right.Row3; - } - - #endregion - - #region Subtract Functions - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static Matrix4x3d Subtract(Matrix4x3d left, Matrix4x3d right) - { - Matrix4x3d result; - Subtract(ref left, ref right, out result); - return result; - } - - /// - /// Subtracts one instance from another. - /// - /// The left operand of the subraction. - /// The right operand of the subraction. - /// A new instance that is the result of the subraction. - public static void Subtract(ref Matrix4x3d left, ref Matrix4x3d right, out Matrix4x3d result) - { - result.Row0 = left.Row0 - right.Row0; - result.Row1 = left.Row1 - right.Row1; - result.Row2 = left.Row2 - right.Row2; - result.Row3 = left.Row3 - right.Row3; - } - - #endregion - - #region Invert Functions - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static Matrix4x3d Invert(Matrix4x3d mat) - { - Matrix4x3d result; - Invert(ref mat, out result); - return result; - } - - /// - /// Calculate the inverse of the given matrix - /// - /// The matrix to invert - /// The inverse of the given matrix if it has one, or the input if it is singular - /// Thrown if the Matrix4 is singular. - public static void Invert(ref Matrix4x3d mat, out Matrix4x3d result) - { - Matrix3d inverseRotation = new Matrix3d(mat.Column0.Xyz, mat.Column1.Xyz, mat.Column2.Xyz); - inverseRotation.Row0 /= inverseRotation.Row0.LengthSquared; - inverseRotation.Row1 /= inverseRotation.Row1.LengthSquared; - inverseRotation.Row2 /= inverseRotation.Row2.LengthSquared; - - Vector3d translation = mat.Row3; - - result.Row0 = inverseRotation.Row0; - result.Row1 = inverseRotation.Row1; - result.Row2 = inverseRotation.Row2; - result.Row3 = new Vector3d(-Vector3d.Dot(inverseRotation.Row0, translation), -Vector3d.Dot(inverseRotation.Row1, translation), -Vector3d.Dot(inverseRotation.Row2, translation)); - } - - #endregion - - #region Transpose - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The transpose of the given matrix - public static Matrix3x4d Transpose(Matrix4x3d mat) - { - return new Matrix3x4d(mat.Column0, mat.Column1, mat.Column2); - } - - /// - /// Calculate the transpose of the given matrix - /// - /// The matrix to transpose - /// The result of the calculation - public static void Transpose(ref Matrix4x3d mat, out Matrix3x4d result) - { - result.Row0 = mat.Column0; - result.Row1 = mat.Column1; - result.Row2 = mat.Column2; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4d which holds the result of the multiplication - public static Matrix4d operator *(Matrix4x3d left, Matrix3x4d right) - { - return Matrix4x3d.Mult(left, right); - } - - /// - /// Matrix multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3d which holds the result of the multiplication - public static Matrix4x3d operator *(Matrix4x3d left, Matrix4x3d right) - { - return Matrix4x3d.Mult(left, right); - } - - /// - /// Matrix-scalar multiplication - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3d which holds the result of the multiplication - public static Matrix4x3d operator *(Matrix4x3d left, double right) - { - return Matrix4x3d.Mult(left, right); - } - - /// - /// Matrix addition - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3d which holds the result of the addition - public static Matrix4x3d operator +(Matrix4x3d left, Matrix4x3d right) - { - return Matrix4x3d.Add(left, right); - } - - /// - /// Matrix subtraction - /// - /// left-hand operand - /// right-hand operand - /// A new Matrix4x3d which holds the result of the subtraction - public static Matrix4x3d operator -(Matrix4x3d left, Matrix4x3d right) - { - return Matrix4x3d.Subtract(left, right); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Matrix4x3d left, Matrix4x3d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Matrix4x3d left, Matrix4x3d right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Matrix4x3d. - /// - /// The string representation of the matrix. - public override string ToString() - { - return string.Format("{0}\n{1}\n{2}", Row0, Row1, Row2); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return Row0.GetHashCode() ^ Row1.GetHashCode() ^ Row2.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare tresult. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Matrix4x3d)) - return false; - - return this.Equals((Matrix4x3d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current matrix is equal to another matrix. - /// An matrix to compare with this matrix. - /// true if the current matrix is equal to the matrix parameter; otherwise, false. - public bool Equals(Matrix4x3d other) - { - return - Row0 == other.Row0 && - Row1 == other.Row1 && - Row2 == other.Row2 && - Row3 == other.Row3; - } - - #endregion - } -} diff --git a/OpenTK/Math/Point.cs b/OpenTK/Math/Point.cs deleted file mode 100644 index 67613933..00000000 --- a/OpenTK/Math/Point.cs +++ /dev/null @@ -1,235 +0,0 @@ -#region License - // - // The Open Toolkit Library License - // - // Copyright (c) 2006 - 2009 the Open Toolkit library. - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to deal - // in the Software without restriction, including without limitation the rights to - // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - // the Software, and to permit persons to whom the Software is furnished to do - // so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in all - // copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - // OTHER DEALINGS IN THE SOFTWARE. - // - #endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenTK -{ -#if NO_SYSDRAWING - /// - /// Defines a point on a two-dimensional plane. - /// - public struct Point : IEquatable - { - #region Fields - - int x, y; - - #endregion - - #region Constructors - - /// - /// Constructs a new Point instance. - /// - /// The X coordinate of this instance. - /// The Y coordinate of this instance. - public Point(int x, int y) - : this() - { - X = x; - Y = y; - } - - #endregion - - #region Public Members - - /// - /// Gets a that indicates whether this instance is empty or zero. - /// - public bool IsEmpty { get { return X == 0 && Y == 0; } } - - /// - /// Gets or sets the X coordinate of this instance. - /// - public int X { get { return x; } set { x = value; } } - - /// - /// Gets or sets the Y coordinate of this instance. - /// - public int Y { get { return y; } set { y = value; } } - - /// - /// Returns the Point (0, 0). - /// - public static readonly Point Zero = new Point(); - - /// - /// Returns the Point (0, 0). - /// - public static readonly Point Empty = new Point(); - - /// - /// Translates the specified Point by the specified Size. - /// - /// - /// The instance to translate. - /// - /// - /// The instance to translate point with. - /// - /// - /// A new instance translated by size. - /// - public static Point operator +(Point point, Size size) - { - return new Point(point.X + size.Width, point.Y + size.Height); - } - - /// - /// Translates the specified Point by the negative of the specified Size. - /// - /// - /// The instance to translate. - /// - /// - /// The instance to translate point with. - /// - /// - /// A new instance translated by size. - /// - public static Point operator -(Point point, Size size) - { - return new Point(point.X - size.Width, point.Y - size.Height); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left is equal to right; false otherwise. - public static bool operator ==(Point left, Point right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left is not equal to right; false otherwise. - public static bool operator !=(Point left, Point right) - { - return !left.Equals(right); - } - - /// - /// Converts an OpenTK.Point instance to a System.Drawing.Point. - /// - /// - /// The instance to convert. - /// - /// - /// A instance equivalent to point. - /// - public static implicit operator System.Drawing.Point(Point point) - { - return new System.Drawing.Point(point.X, point.Y); - } - - /// - /// Converts a System.Drawing.Point instance to an OpenTK.Point. - /// - /// - /// The instance to convert. - /// - /// - /// A instance equivalent to point. - /// - public static implicit operator Point(System.Drawing.Point point) - { - return new Point(point.X, point.Y); - } - - /// - /// Converts an OpenTK.Point instance to a System.Drawing.PointF. - /// - /// - /// The instance to convert. - /// - /// - /// A instance equivalent to point. - /// - public static implicit operator System.Drawing.PointF(Point point) - { - return new System.Drawing.PointF(point.X, point.Y); - } - - /// - /// Indicates whether this instance is equal to the specified object. - /// - /// The object instance to compare to. - /// True, if both instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (obj is Point) - return Equals((Point)obj); - - return false; - } - - /// - /// Returns the hash code for this instance. - /// - /// A that represents the hash code for this instance./> - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode(); - } - - /// - /// Returns a that describes this instance. - /// - /// A that describes this instance. - public override string ToString() - { - return String.Format("{{{0}, {1}}}", X, Y); - } - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether this instance is equal to the specified Point. - /// - /// The instance to compare to. - /// True, if both instances are equal; false otherwise. - public bool Equals(Point other) - { - return X == other.X && Y == other.Y; - } - - #endregion - } -#endif -} diff --git a/OpenTK/Math/Quaternion.cs b/OpenTK/Math/Quaternion.cs deleted file mode 100644 index 922a4f79..00000000 --- a/OpenTK/Math/Quaternion.cs +++ /dev/null @@ -1,804 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; -using System.ComponentModel; -using System.Xml.Serialization; - -namespace OpenTK -{ - /// - /// Represents a Quaternion. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Quaternion : IEquatable - { - #region Fields - - Vector3 xyz; - float w; - - #endregion - - #region Constructors - - /// - /// Construct a new Quaternion from vector and w components - /// - /// The vector part - /// The w part - public Quaternion(Vector3 v, float w) - { - this.xyz = v; - this.w = w; - } - - /// - /// Construct a new Quaternion - /// - /// The x component - /// The y component - /// The z component - /// The w component - public Quaternion(float x, float y, float z, float w) - : this(new Vector3(x, y, z), w) - { } - - #endregion - - #region Public Members - - #region Properties - - #pragma warning disable 3005 // Identifier differing only in case is not CLS-compliant, compiler bug in Mono 3.4.0 - - /// - /// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance. - /// - [Obsolete("Use Xyz property instead.")] - [EditorBrowsable(EditorBrowsableState.Never)] - [XmlIgnore] - [CLSCompliant(false)] - public Vector3 XYZ { get { return Xyz; } set { Xyz = value; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the X, Y and Z components of this instance. - /// - [CLSCompliant(false)] - public Vector3 Xyz { get { return xyz; } set { xyz = value; } } - - #pragma warning restore 3005 - - /// - /// Gets or sets the X component of this instance. - /// - [XmlIgnore] - public float X { get { return xyz.X; } set { xyz.X = value; } } - - /// - /// Gets or sets the Y component of this instance. - /// - [XmlIgnore] - public float Y { get { return xyz.Y; } set { xyz.Y = value; } } - - /// - /// Gets or sets the Z component of this instance. - /// - [XmlIgnore] - public float Z { get { return xyz.Z; } set { xyz.Z = value; } } - - /// - /// Gets or sets the W component of this instance. - /// - public float W { get { return w; } set { w = value; } } - - #endregion - - #region Instance - - #region ToAxisAngle - - /// - /// Convert the current quaternion to axis angle representation - /// - /// The resultant axis - /// The resultant angle - public void ToAxisAngle(out Vector3 axis, out float angle) - { - Vector4 result = ToAxisAngle(); - axis = result.Xyz; - angle = result.W; - } - - /// - /// Convert this instance to an axis-angle representation. - /// - /// A Vector4 that is the axis-angle representation of this quaternion. - public Vector4 ToAxisAngle() - { - Quaternion q = this; - if (Math.Abs(q.W) > 1.0f) - q.Normalize(); - - Vector4 result = new Vector4(); - - result.W = 2.0f * (float)System.Math.Acos(q.W); // angle - float den = (float)System.Math.Sqrt(1.0 - q.W * q.W); - if (den > 0.0001f) - { - result.Xyz = q.Xyz / den; - } - else - { - // This occurs when the angle is zero. - // Not a problem: just set an arbitrary normalized axis. - result.Xyz = Vector3.UnitX; - } - - return result; - } - - #endregion - - #region public float Length - - /// - /// Gets the length (magnitude) of the quaternion. - /// - /// - public float Length - { - get - { - return (float)System.Math.Sqrt(W * W + Xyz.LengthSquared); - } - } - - #endregion - - #region public float LengthSquared - - /// - /// Gets the square of the quaternion length (magnitude). - /// - public float LengthSquared - { - get - { - return W * W + Xyz.LengthSquared; - } - } - - #endregion - - /// - /// Returns a copy of the Quaternion scaled to unit length. - /// - public Quaternion Normalized() - { - Quaternion q = this; - q.Normalize(); - return q; - } - - /// - /// Reverses the rotation angle of this Quaterniond. - /// - public void Invert() - { - W = -W; - } - - /// - /// Returns a copy of this Quaterniond with its rotation angle reversed. - /// - public Quaternion Inverted() - { - var q = this; - q.Invert(); - return q; - } - - #region public void Normalize() - - /// - /// Scales the Quaternion to unit length. - /// - public void Normalize() - { - float scale = 1.0f / this.Length; - Xyz *= scale; - W *= scale; - } - - #endregion - - #region public void Conjugate() - - /// - /// Inverts the Vector3 component of this Quaternion. - /// - public void Conjugate() - { - Xyz = -Xyz; - } - - #endregion - - #endregion - - #region Static - - #region Fields - - /// - /// Defines the identity quaternion. - /// - public static readonly Quaternion Identity = new Quaternion(0, 0, 0, 1); - - #endregion - - #region Add - - /// - /// Add two quaternions - /// - /// The first operand - /// The second operand - /// The result of the addition - public static Quaternion Add(Quaternion left, Quaternion right) - { - return new Quaternion( - left.Xyz + right.Xyz, - left.W + right.W); - } - - /// - /// Add two quaternions - /// - /// The first operand - /// The second operand - /// The result of the addition - public static void Add(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - result = new Quaternion( - left.Xyz + right.Xyz, - left.W + right.W); - } - - #endregion - - #region Sub - - /// - /// Subtracts two instances. - /// - /// The left instance. - /// The right instance. - /// The result of the operation. - public static Quaternion Sub(Quaternion left, Quaternion right) - { - return new Quaternion( - left.Xyz - right.Xyz, - left.W - right.W); - } - - /// - /// Subtracts two instances. - /// - /// The left instance. - /// The right instance. - /// The result of the operation. - public static void Sub(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - result = new Quaternion( - left.Xyz - right.Xyz, - left.W - right.W); - } - - #endregion - - #region Mult - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - [Obsolete("Use Multiply instead.")] - public static Quaternion Mult(Quaternion left, Quaternion right) - { - return new Quaternion( - right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz), - left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz)); - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - [Obsolete("Use Multiply instead.")] - public static void Mult(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - result = new Quaternion( - right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz), - left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz)); - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - public static Quaternion Multiply(Quaternion left, Quaternion right) - { - Quaternion result; - Multiply(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - public static void Multiply(ref Quaternion left, ref Quaternion right, out Quaternion result) - { - result = new Quaternion( - right.W * left.Xyz + left.W * right.Xyz + Vector3.Cross(left.Xyz, right.Xyz), - left.W * right.W - Vector3.Dot(left.Xyz, right.Xyz)); - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - public static void Multiply(ref Quaternion quaternion, float scale, out Quaternion result) - { - result = new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale); - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - public static Quaternion Multiply(Quaternion quaternion, float scale) - { - return new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale); - } - - #endregion - - #region Conjugate - - /// - /// Get the conjugate of the given quaternion - /// - /// The quaternion - /// The conjugate of the given quaternion - public static Quaternion Conjugate(Quaternion q) - { - return new Quaternion(-q.Xyz, q.W); - } - - /// - /// Get the conjugate of the given quaternion - /// - /// The quaternion - /// The conjugate of the given quaternion - public static void Conjugate(ref Quaternion q, out Quaternion result) - { - result = new Quaternion(-q.Xyz, q.W); - } - - #endregion - - #region Invert - - /// - /// Get the inverse of the given quaternion - /// - /// The quaternion to invert - /// The inverse of the given quaternion - public static Quaternion Invert(Quaternion q) - { - Quaternion result; - Invert(ref q, out result); - return result; - } - - /// - /// Get the inverse of the given quaternion - /// - /// The quaternion to invert - /// The inverse of the given quaternion - public static void Invert(ref Quaternion q, out Quaternion result) - { - float lengthSq = q.LengthSquared; - if (lengthSq != 0.0) - { - float i = 1.0f / lengthSq; - result = new Quaternion(q.Xyz * -i, q.W * i); - } - else - { - result = q; - } - } - - #endregion - - #region Normalize - - /// - /// Scale the given quaternion to unit length - /// - /// The quaternion to normalize - /// The normalized quaternion - public static Quaternion Normalize(Quaternion q) - { - Quaternion result; - Normalize(ref q, out result); - return result; - } - - /// - /// Scale the given quaternion to unit length - /// - /// The quaternion to normalize - /// The normalized quaternion - public static void Normalize(ref Quaternion q, out Quaternion result) - { - float scale = 1.0f / q.Length; - result = new Quaternion(q.Xyz * scale, q.W * scale); - } - - #endregion - - #region FromAxisAngle - - /// - /// Build a quaternion from the given axis and angle - /// - /// The axis to rotate about - /// The rotation angle in radians - /// The equivalent quaternion - public static Quaternion FromAxisAngle(Vector3 axis, float angle) - { - if (axis.LengthSquared == 0.0f) - return Identity; - - Quaternion result = Identity; - - angle *= 0.5f; - axis.Normalize(); - result.Xyz = axis * (float)System.Math.Sin(angle); - result.W = (float)System.Math.Cos(angle); - - return Normalize(result); - } - - #endregion - - #region FromMatrix - - /// - /// Builds a quaternion from the given rotation matrix - /// - /// A rotation matrix - /// The equivalent quaternion - public static Quaternion FromMatrix(Matrix3 matrix) - { - Quaternion result; - FromMatrix(ref matrix, out result); - return result; - } - - /// - /// Builds a quaternion from the given rotation matrix - /// - /// A rotation matrix - /// The equivalent quaternion - public static void FromMatrix(ref Matrix3 matrix, out Quaternion result) - { - float trace = matrix.Trace; - - if (trace > 0) - { - float s = (float)Math.Sqrt(trace + 1) * 2; - float invS = 1f / s; - - result.w = s * 0.25f; - result.xyz.X = (matrix.Row2.Y - matrix.Row1.Z) * invS; - result.xyz.Y = (matrix.Row0.Z - matrix.Row2.X) * invS; - result.xyz.Z = (matrix.Row1.X - matrix.Row0.Y) * invS; - } - else - { - float m00 = matrix.Row0.X, m11 = matrix.Row1.Y, m22 = matrix.Row2.Z; - - if (m00 > m11 && m00 > m22) - { - float s = (float)Math.Sqrt(1 + m00 - m11 - m22) * 2; - float invS = 1f / s; - - result.w = (matrix.Row2.Y - matrix.Row1.Z) * invS; - result.xyz.X = s * 0.25f; - result.xyz.Y = (matrix.Row0.Y + matrix.Row1.X) * invS; - result.xyz.Z = (matrix.Row0.Z + matrix.Row2.X) * invS; - } - else if (m11 > m22) - { - float s = (float)Math.Sqrt(1 + m11 - m00 - m22) * 2; - float invS = 1f / s; - - result.w = (matrix.Row0.Z - matrix.Row2.X) * invS; - result.xyz.X = (matrix.Row0.Y + matrix.Row1.X) * invS; - result.xyz.Y = s * 0.25f; - result.xyz.Z = (matrix.Row1.Z + matrix.Row2.Y) * invS; - } - else - { - float s = (float)Math.Sqrt(1 + m22 - m00 - m11) * 2; - float invS = 1f / s; - - result.w = (matrix.Row1.X - matrix.Row0.Y) * invS; - result.xyz.X = (matrix.Row0.Z + matrix.Row2.X) * invS; - result.xyz.Y = (matrix.Row1.Z + matrix.Row2.Y) * invS; - result.xyz.Z = s * 0.25f; - } - } - } - - #endregion - - #region Slerp - - /// - /// Do Spherical linear interpolation between two quaternions - /// - /// The first quaternion - /// The second quaternion - /// The blend factor - /// A smooth blend between the given quaternions - public static Quaternion Slerp(Quaternion q1, Quaternion q2, float blend) - { - // if either input is zero, return the other. - if (q1.LengthSquared == 0.0f) - { - if (q2.LengthSquared == 0.0f) - { - return Identity; - } - return q2; - } - else if (q2.LengthSquared == 0.0f) - { - return q1; - } - - - float cosHalfAngle = q1.W * q2.W + Vector3.Dot(q1.Xyz, q2.Xyz); - - if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f) - { - // angle = 0.0f, so just return one input. - return q1; - } - else if (cosHalfAngle < 0.0f) - { - q2.Xyz = -q2.Xyz; - q2.W = -q2.W; - cosHalfAngle = -cosHalfAngle; - } - - float blendA; - float blendB; - if (cosHalfAngle < 0.99f) - { - // do proper slerp for big angles - float halfAngle = (float)System.Math.Acos(cosHalfAngle); - float sinHalfAngle = (float)System.Math.Sin(halfAngle); - float oneOverSinHalfAngle = 1.0f / sinHalfAngle; - blendA = (float)System.Math.Sin(halfAngle * (1.0f - blend)) * oneOverSinHalfAngle; - blendB = (float)System.Math.Sin(halfAngle * blend) * oneOverSinHalfAngle; - } - else - { - // do lerp if angle is really small. - blendA = 1.0f - blend; - blendB = blend; - } - - Quaternion result = new Quaternion(blendA * q1.Xyz + blendB * q2.Xyz, blendA * q1.W + blendB * q2.W); - if (result.LengthSquared > 0.0f) - return Normalize(result); - else - return Identity; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Adds two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Quaternion operator +(Quaternion left, Quaternion right) - { - left.Xyz += right.Xyz; - left.W += right.W; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Quaternion operator -(Quaternion left, Quaternion right) - { - left.Xyz -= right.Xyz; - left.W -= right.W; - return left; - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Quaternion operator *(Quaternion left, Quaternion right) - { - Multiply(ref left, ref right, out left); - return left; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - public static Quaternion operator *(Quaternion quaternion, float scale) - { - Multiply(ref quaternion, scale, out quaternion); - return quaternion; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - public static Quaternion operator *(float scale, Quaternion quaternion) - { - return new Quaternion(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Quaternion left, Quaternion right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Quaternion left, Quaternion right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Quaternion. - /// - /// - public override string ToString() - { - return String.Format("V: {0}, W: {1}", Xyz, W); - } - - #endregion - - #region public override bool Equals (object o) - - /// - /// Compares this object instance to another object for equality. - /// - /// The other object to be used in the comparison. - /// True if both objects are Quaternions of equal value. Otherwise it returns false. - public override bool Equals(object other) - { - if (other is Quaternion == false) return false; - return this == (Quaternion)other; - } - - #endregion - - #region public override int GetHashCode () - - /// - /// Provides the hash code for this object. - /// - /// A hash code formed from the bitwise XOR of this objects members. - public override int GetHashCode() - { - return Xyz.GetHashCode() ^ W.GetHashCode(); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// - /// Compares this Quaternion instance to another Quaternion for equality. - /// - /// The other Quaternion to be used in the comparison. - /// True if both instances are equal; false otherwise. - public bool Equals(Quaternion other) - { - return Xyz == other.Xyz && W == other.W; - } - - #endregion - } -} diff --git a/OpenTK/Math/Quaterniond.cs b/OpenTK/Math/Quaterniond.cs deleted file mode 100644 index 792dddde..00000000 --- a/OpenTK/Math/Quaterniond.cs +++ /dev/null @@ -1,1428 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#endregion - -using System; -using System.Runtime.InteropServices; -using System.ComponentModel; -using System.Xml.Serialization; - -namespace OpenTK -{ - /// - /// Represents a double-precision Quaternion. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Quaterniond : IEquatable - { - #region Fields - - Vector3d xyz; - double w; - - #endregion - - #region Constructors - - /// - /// Construct a new Quaterniond from vector and w components - /// - /// The vector part - /// The w part - public Quaterniond(Vector3d v, double w) - { - this.xyz = v; - this.w = w; - } - - /// - /// Construct a new Quaterniond - /// - /// The x component - /// The y component - /// The z component - /// The w component - public Quaterniond(double x, double y, double z, double w) - : this(new Vector3d(x, y, z), w) - { } - - #endregion - - #region Public Members - - #region Properties - - #pragma warning disable 3005 // Identifier differing only in case is not CLS-compliant, compiler bug in Mono 3.4.0 - - /// - /// Gets or sets an OpenTK.Vector3d with the X, Y and Z components of this instance. - /// - [Obsolete("Use Xyz property instead.")] - [CLSCompliant(false)] - [EditorBrowsable(EditorBrowsableState.Never)] - [XmlIgnore] - public Vector3d XYZ { get { return Xyz; } set { Xyz = value; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the X, Y and Z components of this instance. - /// - public Vector3d Xyz { get { return xyz; } set { xyz = value; } } - - #pragma warning restore 3005 - - /// - /// Gets or sets the X component of this instance. - /// - [XmlIgnore] - public double X { get { return xyz.X; } set { xyz.X = value; } } - - /// - /// Gets or sets the Y component of this instance. - /// - [XmlIgnore] - public double Y { get { return xyz.Y; } set { xyz.Y = value; } } - - /// - /// Gets or sets the Z component of this instance. - /// - [XmlIgnore] - public double Z { get { return xyz.Z; } set { xyz.Z = value; } } - - /// - /// Gets or sets the W component of this instance. - /// - public double W { get { return w; } set { w = value; } } - - #endregion - - #region Instance - - #region ToAxisAngle - - /// - /// Convert the current quaternion to axis angle representation - /// - /// The resultant axis - /// The resultant angle - public void ToAxisAngle(out Vector3d axis, out double angle) - { - Vector4d result = ToAxisAngle(); - axis = result.Xyz; - angle = result.W; - } - - /// - /// Convert this instance to an axis-angle representation. - /// - /// A Vector4 that is the axis-angle representation of this quaternion. - public Vector4d ToAxisAngle() - { - Quaterniond q = this; - if (Math.Abs(q.W) > 1.0f) - q.Normalize(); - - Vector4d result = new Vector4d(); - - result.W = 2.0f * (float)System.Math.Acos(q.W); // angle - float den = (float)System.Math.Sqrt(1.0 - q.W * q.W); - if (den > 0.0001f) - { - result.Xyz = q.Xyz / den; - } - else - { - // This occurs when the angle is zero. - // Not a problem: just set an arbitrary normalized axis. - result.Xyz = Vector3d.UnitX; - } - - return result; - } - - #endregion - - #region public double Length - - /// - /// Gets the length (magnitude) of the Quaterniond. - /// - /// - public double Length - { - get - { - return (double)System.Math.Sqrt(W * W + Xyz.LengthSquared); - } - } - - #endregion - - #region public double LengthSquared - - /// - /// Gets the square of the Quaterniond length (magnitude). - /// - public double LengthSquared - { - get - { - return W * W + Xyz.LengthSquared; - } - } - - #endregion - - /// - /// Returns a copy of the Quaterniond scaled to unit length. - /// - public Quaterniond Normalized() - { - Quaterniond q = this; - q.Normalize(); - return q; - } - - /// - /// Reverses the rotation angle of this Quaterniond. - /// - public void Invert() - { - W = -W; - } - - /// - /// Returns a copy of this Quaterniond with its rotation angle reversed. - /// - public Quaterniond Inverted() - { - var q = this; - q.Invert(); - return q; - } - - #region public void Normalize() - - /// - /// Scales the Quaterniond to unit length. - /// - public void Normalize() - { - double scale = 1.0f / this.Length; - Xyz *= scale; - W *= scale; - } - - #endregion - - #region public void Conjugate() - - /// - /// Inverts the Vector3d component of this Quaterniond. - /// - public void Conjugate() - { - Xyz = -Xyz; - } - - #endregion - - #endregion - - #region Static - - #region Fields - - /// - /// Defines the identity quaternion. - /// - public readonly static Quaterniond Identity = new Quaterniond(0, 0, 0, 1); - - #endregion - - #region Add - - /// - /// Add two quaternions - /// - /// The first operand - /// The second operand - /// The result of the addition - public static Quaterniond Add(Quaterniond left, Quaterniond right) - { - return new Quaterniond( - left.Xyz + right.Xyz, - left.W + right.W); - } - - /// - /// Add two quaternions - /// - /// The first operand - /// The second operand - /// The result of the addition - public static void Add(ref Quaterniond left, ref Quaterniond right, out Quaterniond result) - { - result = new Quaterniond( - left.Xyz + right.Xyz, - left.W + right.W); - } - - #endregion - - #region Sub - - /// - /// Subtracts two instances. - /// - /// The left instance. - /// The right instance. - /// The result of the operation. - public static Quaterniond Sub(Quaterniond left, Quaterniond right) - { - return new Quaterniond( - left.Xyz - right.Xyz, - left.W - right.W); - } - - /// - /// Subtracts two instances. - /// - /// The left instance. - /// The right instance. - /// The result of the operation. - public static void Sub(ref Quaterniond left, ref Quaterniond right, out Quaterniond result) - { - result = new Quaterniond( - left.Xyz - right.Xyz, - left.W - right.W); - } - - #endregion - - #region Mult - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - [Obsolete("Use Multiply instead.")] - public static Quaterniond Mult(Quaterniond left, Quaterniond right) - { - return new Quaterniond( - right.W * left.Xyz + left.W * right.Xyz + Vector3d.Cross(left.Xyz, right.Xyz), - left.W * right.W - Vector3d.Dot(left.Xyz, right.Xyz)); - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - [Obsolete("Use Multiply instead.")] - public static void Mult(ref Quaterniond left, ref Quaterniond right, out Quaterniond result) - { - result = new Quaterniond( - right.W * left.Xyz + left.W * right.Xyz + Vector3d.Cross(left.Xyz, right.Xyz), - left.W * right.W - Vector3d.Dot(left.Xyz, right.Xyz)); - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - public static Quaterniond Multiply(Quaterniond left, Quaterniond right) - { - Quaterniond result; - Multiply(ref left, ref right, out result); - return result; - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// A new instance containing the result of the calculation. - public static void Multiply(ref Quaterniond left, ref Quaterniond right, out Quaterniond result) - { - result = new Quaterniond( - right.W * left.Xyz + left.W * right.Xyz + Vector3d.Cross(left.Xyz, right.Xyz), - left.W * right.W - Vector3d.Dot(left.Xyz, right.Xyz)); - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - public static void Multiply(ref Quaterniond quaternion, double scale, out Quaterniond result) - { - result = new Quaterniond(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale); - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - public static Quaterniond Multiply(Quaterniond quaternion, double scale) - { - return new Quaterniond(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale); - } - - #endregion - - #region Conjugate - - /// - /// Get the conjugate of the given Quaterniond - /// - /// The Quaterniond - /// The conjugate of the given Quaterniond - public static Quaterniond Conjugate(Quaterniond q) - { - return new Quaterniond(-q.Xyz, q.W); - } - - /// - /// Get the conjugate of the given Quaterniond - /// - /// The Quaterniond - /// The conjugate of the given Quaterniond - public static void Conjugate(ref Quaterniond q, out Quaterniond result) - { - result = new Quaterniond(-q.Xyz, q.W); - } - - #endregion - - #region Invert - - /// - /// Get the inverse of the given Quaterniond - /// - /// The Quaterniond to invert - /// The inverse of the given Quaterniond - public static Quaterniond Invert(Quaterniond q) - { - Quaterniond result; - Invert(ref q, out result); - return result; - } - - /// - /// Get the inverse of the given Quaterniond - /// - /// The Quaterniond to invert - /// The inverse of the given Quaterniond - public static void Invert(ref Quaterniond q, out Quaterniond result) - { - double lengthSq = q.LengthSquared; - if (lengthSq != 0.0) - { - double i = 1.0f / lengthSq; - result = new Quaterniond(q.Xyz * -i, q.W * i); - } - else - { - result = q; - } - } - - #endregion - - #region Normalize - - /// - /// Scale the given Quaterniond to unit length - /// - /// The Quaterniond to normalize - /// The normalized Quaterniond - public static Quaterniond Normalize(Quaterniond q) - { - Quaterniond result; - Normalize(ref q, out result); - return result; - } - - /// - /// Scale the given Quaterniond to unit length - /// - /// The Quaterniond to normalize - /// The normalized Quaterniond - public static void Normalize(ref Quaterniond q, out Quaterniond result) - { - double scale = 1.0f / q.Length; - result = new Quaterniond(q.Xyz * scale, q.W * scale); - } - - #endregion - - #region FromAxisAngle - - /// - /// Build a Quaterniond from the given axis and angle - /// - /// The axis to rotate about - /// The rotation angle in radians - /// - public static Quaterniond FromAxisAngle(Vector3d axis, double angle) - { - if (axis.LengthSquared == 0.0f) - return Identity; - - Quaterniond result = Identity; - - angle *= 0.5f; - axis.Normalize(); - result.Xyz = axis * (double)System.Math.Sin(angle); - result.W = (double)System.Math.Cos(angle); - - return Normalize(result); - } - - #endregion - - #region FromMatrix - - /// - /// Builds a quaternion from the given rotation matrix - /// - /// A rotation matrix - /// The equivalent quaternion - public static Quaterniond FromMatrix(Matrix3d matrix) - { - Quaterniond result; - FromMatrix(ref matrix, out result); - return result; - } - - /// - /// Builds a quaternion from the given rotation matrix - /// - /// A rotation matrix - /// The equivalent quaternion - public static void FromMatrix(ref Matrix3d matrix, out Quaterniond result) - { - double trace = matrix.Trace; - - if (trace > 0) - { - double s = Math.Sqrt(trace + 1) * 2; - double invS = 1.0 / s; - - result.w = s * 0.25; - result.xyz.X = (matrix.Row2.Y - matrix.Row1.Z) * invS; - result.xyz.Y = (matrix.Row0.Z - matrix.Row2.X) * invS; - result.xyz.Z = (matrix.Row1.X - matrix.Row0.Y) * invS; - } - else - { - double m00 = matrix.Row0.X, m11 = matrix.Row1.Y, m22 = matrix.Row2.Z; - - if (m00 > m11 && m00 > m22) - { - double s = Math.Sqrt(1 + m00 - m11 - m22) * 2; - double invS = 1.0 / s; - - result.w = (matrix.Row2.Y - matrix.Row1.Z) * invS; - result.xyz.X = s * 0.25; - result.xyz.Y = (matrix.Row0.Y + matrix.Row1.X) * invS; - result.xyz.Z = (matrix.Row0.Z + matrix.Row2.X) * invS; - } - else if (m11 > m22) - { - double s = Math.Sqrt(1 + m11 - m00 - m22) * 2; - double invS = 1.0 / s; - - result.w = (matrix.Row0.Z - matrix.Row2.X) * invS; - result.xyz.X = (matrix.Row0.Y + matrix.Row1.X) * invS; - result.xyz.Y = s * 0.25; - result.xyz.Z = (matrix.Row1.Z + matrix.Row2.Y) * invS; - } - else - { - double s = Math.Sqrt(1 + m22 - m00 - m11) * 2; - double invS = 1.0 / s; - - result.w = (matrix.Row1.X - matrix.Row0.Y) * invS; - result.xyz.X = (matrix.Row0.Z + matrix.Row2.X) * invS; - result.xyz.Y = (matrix.Row1.Z + matrix.Row2.Y) * invS; - result.xyz.Z = s * 0.25; - } - } - } - - #endregion - - #region Slerp - - /// - /// Do Spherical linear interpolation between two quaternions - /// - /// The first Quaterniond - /// The second Quaterniond - /// The blend factor - /// A smooth blend between the given quaternions - public static Quaterniond Slerp(Quaterniond q1, Quaterniond q2, double blend) - { - // if either input is zero, return the other. - if (q1.LengthSquared == 0.0f) - { - if (q2.LengthSquared == 0.0f) - { - return Identity; - } - return q2; - } - else if (q2.LengthSquared == 0.0f) - { - return q1; - } - - - double cosHalfAngle = q1.W * q2.W + Vector3d.Dot(q1.Xyz, q2.Xyz); - - if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f) - { - // angle = 0.0f, so just return one input. - return q1; - } - else if (cosHalfAngle < 0.0f) - { - q2.Xyz = -q2.Xyz; - q2.W = -q2.W; - cosHalfAngle = -cosHalfAngle; - } - - double blendA; - double blendB; - if (cosHalfAngle < 0.99f) - { - // do proper slerp for big angles - double halfAngle = (double)System.Math.Acos(cosHalfAngle); - double sinHalfAngle = (double)System.Math.Sin(halfAngle); - double oneOverSinHalfAngle = 1.0f / sinHalfAngle; - blendA = (double)System.Math.Sin(halfAngle * (1.0f - blend)) * oneOverSinHalfAngle; - blendB = (double)System.Math.Sin(halfAngle * blend) * oneOverSinHalfAngle; - } - else - { - // do lerp if angle is really small. - blendA = 1.0f - blend; - blendB = blend; - } - - Quaterniond result = new Quaterniond(blendA * q1.Xyz + blendB * q2.Xyz, blendA * q1.W + blendB * q2.W); - if (result.LengthSquared > 0.0f) - return Normalize(result); - else - return Identity; - } - - #endregion - - #endregion - - #region Operators - - /// - /// Adds two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Quaterniond operator +(Quaterniond left, Quaterniond right) - { - left.Xyz += right.Xyz; - left.W += right.W; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Quaterniond operator -(Quaterniond left, Quaterniond right) - { - left.Xyz -= right.Xyz; - left.W -= right.W; - return left; - } - - /// - /// Multiplies two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Quaterniond operator *(Quaterniond left, Quaterniond right) - { - Multiply(ref left, ref right, out left); - return left; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - public static Quaterniond operator *(Quaterniond quaternion, double scale) - { - Multiply(ref quaternion, scale, out quaternion); - return quaternion; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// A new instance containing the result of the calculation. - public static Quaterniond operator *(double scale, Quaterniond quaternion) - { - return new Quaterniond(quaternion.X * scale, quaternion.Y * scale, quaternion.Z * scale, quaternion.W * scale); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Quaterniond left, Quaterniond right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equal right; false otherwise. - public static bool operator !=(Quaterniond left, Quaterniond right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - /// - /// Returns a System.String that represents the current Quaterniond. - /// - /// - public override string ToString() - { - return String.Format("V: {0}, W: {1}", Xyz, W); - } - - #endregion - - #region public override bool Equals (object o) - - /// - /// Compares this object instance to another object for equality. - /// - /// The other object to be used in the comparison. - /// True if both objects are Quaternions of equal value. Otherwise it returns false. - public override bool Equals(object other) - { - if (other is Quaterniond == false) return false; - return this == (Quaterniond)other; - } - - #endregion - - #region public override int GetHashCode () - - /// - /// Provides the hash code for this object. - /// - /// A hash code formed from the bitwise XOR of this objects members. - public override int GetHashCode() - { - return Xyz.GetHashCode() ^ W.GetHashCode(); - } - - #endregion - - #endregion - - #endregion - -#if false - - #region Fields - - /// The W component of the Quaterniond. - public double W; - - /// The X component of the Quaterniond. - public double X; - - /// The Y component of the Quaterniond. - public double Y; - - /// The Z component of the Quaterniond. - public double Z; - - #endregion - - #region Constructors - - /// Constructs left Quaterniond that is left copy of the given Quaterniond. - /// The Quaterniond to copy. - public Quaterniond(ref Quaterniond Quaterniond) : this(Quaterniond.W, Quaterniond.X, Quaterniond.Y, Quaterniond.Z) { } - - /// Constructs left Quaterniond from the given components. - /// The W component for the Quaterniond. - /// A Vector representing the X, Y, and Z componets for the quaterion. - public Quaterniond(double w, ref Vector3d vector3d) : this(w, vector3d.X, vector3d.Y, vector3d.Z) { } - - /// Constructs left Quaterniond from the given axis and angle. - /// The axis for the Quaterniond. - /// The angle for the quaternione. - public Quaterniond(ref Vector3d axis, double angle) - { - double halfAngle = Functions.DTOR * angle / 2; - - this.W = System.Math.Cos(halfAngle); - - double sin = System.Math.Sin(halfAngle); - Vector3d axisNormalized; - Vector3d.Normalize(ref axis, out axisNormalized); - this.X = axisNormalized.X * sin; - this.Y = axisNormalized.Y * sin; - this.Z = axisNormalized.Z * sin; - } - - /// Constructs left Quaterniond from the given components. - /// The W component for the Quaterniond. - /// The X component for the Quaterniond. - /// The Y component for the Quaterniond. - /// The Z component for the Quaterniond. - public Quaterniond(double w, double x, double y, double z) - { - this.W = w; - this.X = x; - this.Y = y; - this.Z = z; - } - - /// Constructs left Quaterniond from the given array of double-precision floating-point numbers. - /// The array of doubles for the components of the Quaterniond. - public Quaterniond(double[] doubleArray) - { - if (doubleArray == null || doubleArray.GetLength(0) < 4) throw new MissingFieldException(); - - this.W = doubleArray[0]; - this.X = doubleArray[1]; - this.Y = doubleArray[2]; - this.Z = doubleArray[3]; - } - - /// Constructs left Quaterniond from the given matrix. Only contains rotation information. - /// The matrix for the components of the Quaterniond. - public Quaterniond(ref Matrix4d matrix) - { - double scale = System.Math.Pow(matrix.Determinant, 1.0d/3.0d); - - W = System.Math.Sqrt(System.Math.Max(0, scale + matrix[0, 0] + matrix[1, 1] + matrix[2, 2])) / 2; - X = System.Math.Sqrt(System.Math.Max(0, scale + matrix[0, 0] - matrix[1, 1] - matrix[2, 2])) / 2; - Y = System.Math.Sqrt(System.Math.Max(0, scale - matrix[0, 0] + matrix[1, 1] - matrix[2, 2])) / 2; - Z = System.Math.Sqrt(System.Math.Max(0, scale - matrix[0, 0] - matrix[1, 1] + matrix[2, 2])) / 2; - if( matrix[2,1] - matrix[1,2] < 0 ) X = -X; - if( matrix[0,2] - matrix[2,0] < 0 ) Y = -Y; - if( matrix[1,0] - matrix[0,1] < 0 ) Z = -Z; - } - - public Quaterniond(ref Matrix3d matrix) - { - double scale = System.Math.Pow(matrix.Determinant, 1.0d / 3.0d); - - W = System.Math.Sqrt(System.Math.Max(0, scale + matrix[0, 0] + matrix[1, 1] + matrix[2, 2])) / 2; - X = System.Math.Sqrt(System.Math.Max(0, scale + matrix[0, 0] - matrix[1, 1] - matrix[2, 2])) / 2; - Y = System.Math.Sqrt(System.Math.Max(0, scale - matrix[0, 0] + matrix[1, 1] - matrix[2, 2])) / 2; - Z = System.Math.Sqrt(System.Math.Max(0, scale - matrix[0, 0] - matrix[1, 1] + matrix[2, 2])) / 2; - if (matrix[2, 1] - matrix[1, 2] < 0) X = -X; - if (matrix[0, 2] - matrix[2, 0] < 0) Y = -Y; - if (matrix[1, 0] - matrix[0, 1] < 0) Z = -Z; - } - - #endregion - - #region Arithmetic Operators - - public void Add(ref Quaterniond Quaterniond) - { - W = W + Quaterniond.W; - X = X + Quaterniond.X; - Y = Y + Quaterniond.Y; - Z = Z + Quaterniond.Z; - } - public void Add(ref Quaterniond Quaterniond, out Quaterniond result) - { - result.W = W + Quaterniond.W; - result.X = X + Quaterniond.X; - result.Y = Y + Quaterniond.Y; - result.Z = Z + Quaterniond.Z; - } - public static void Add(ref Quaterniond left, ref Quaterniond right, out Quaterniond result) - { - result.W = left.W + right.W; - result.X = left.X + right.X; - result.Y = left.Y + right.Y; - result.Z = left.Z + right.Z; - } - - public void Subtract(ref Quaterniond Quaterniond) - { - W = W - Quaterniond.W; - X = X - Quaterniond.X; - Y = Y - Quaterniond.Y; - Z = Z - Quaterniond.Z; - } - public void Subtract(ref Quaterniond Quaterniond, out Quaterniond result) - { - result.W = W - Quaterniond.W; - result.X = X - Quaterniond.X; - result.Y = Y - Quaterniond.Y; - result.Z = Z - Quaterniond.Z; - } - public static void Subtract(ref Quaterniond left, ref Quaterniond right, out Quaterniond result) - { - result.W = left.W - right.W; - result.X = left.X - right.X; - result.Y = left.Y - right.Y; - result.Z = left.Z - right.Z; - } - - public void Multiply(ref Quaterniond Quaterniond) - { - double w = W * Quaterniond.W - X * Quaterniond.X - Y * Quaterniond.Y - Z * Quaterniond.Z; - double x = W * Quaterniond.X + X * Quaterniond.W + Y * Quaterniond.Z - Z * Quaterniond.Y; - double y = W * Quaterniond.Y + Y * Quaterniond.W + Z * Quaterniond.X - X * Quaterniond.Z; - Z = W * Quaterniond.Z + Z * Quaterniond.W + X * Quaterniond.Y - Y * Quaterniond.X; - W = w; - X = x; - Y = y; - } - public void Multiply(ref Quaterniond Quaterniond, out Quaterniond result) - { - result.W = W * Quaterniond.W - X * Quaterniond.X - Y * Quaterniond.Y - Z * Quaterniond.Z; - result.X = W * Quaterniond.X + X * Quaterniond.W + Y * Quaterniond.Z - Z * Quaterniond.Y; - result.Y = W * Quaterniond.Y + Y * Quaterniond.W + Z * Quaterniond.X - X * Quaterniond.Z; - result.Z = W * Quaterniond.Z + Z * Quaterniond.W + X * Quaterniond.Y - Y * Quaterniond.X; - } - public static void Multiply(ref Quaterniond left, ref Quaterniond right, out Quaterniond result) - { - result.W = left.W * right.W - left.X * right.X - left.Y * right.Y - left.Z * right.Z; - result.X = left.W * right.X + left.X * right.W + left.Y * right.Z - left.Z * right.Y; - result.Y = left.W * right.Y + left.Y * right.W + left.Z * right.X - left.X * right.Z; - result.Z = left.W * right.Z + left.Z * right.W + left.X * right.Y - left.Y * right.X; - } - - public void Multiply(double scalar) - { - W = W * scalar; - X = X * scalar; - Y = Y * scalar; - Z = Z * scalar; - } - public void Multiply(double scalar, out Quaterniond result) - { - result.W = W * scalar; - result.X = X * scalar; - result.Y = Y * scalar; - result.Z = Z * scalar; - } - public static void Multiply(ref Quaterniond Quaterniond, double scalar, out Quaterniond result) - { - result.W = Quaterniond.W * scalar; - result.X = Quaterniond.X * scalar; - result.Y = Quaterniond.Y * scalar; - result.Z = Quaterniond.Z * scalar; - } - - public void Divide(double scalar) - { - if (scalar == 0) throw new DivideByZeroException(); - W = W / scalar; - X = X / scalar; - Y = Y / scalar; - Z = Z / scalar; - } - public void Divide(double scalar, out Quaterniond result) - { - if (scalar == 0) throw new DivideByZeroException(); - result.W = W / scalar; - result.X = X / scalar; - result.Y = Y / scalar; - result.Z = Z / scalar; - } - public static void Divide(ref Quaterniond Quaterniond, double scalar, out Quaterniond result) - { - if (scalar == 0) throw new DivideByZeroException(); - result.W = Quaterniond.W / scalar; - result.X = Quaterniond.X / scalar; - result.Y = Quaterniond.Y / scalar; - result.Z = Quaterniond.Z / scalar; - } - - #endregion - - #region Functions - - public double Modulus - { - get - { - return System.Math.Sqrt(W * W + X * X + Y * Y + Z * Z); - } - } - public double ModulusSquared - { - get - { - return W * W + X * X + Y * Y + Z * Z; - } - } - - public static double DotProduct(Quaterniond left, Quaterniond right) - { - return left.W * right.W + left.X * right.X + left.Y * right.Y + left.Z * right.Z; - } - - public void Normalize() - { - double modulus = System.Math.Sqrt(W * W + X * X + Y * Y + Z * Z); - if (modulus == 0) throw new DivideByZeroException(); - W = W / modulus; - X = X / modulus; - Y = Y / modulus; - Z = Z / modulus; - } - public void Normalize( out Quaterniond result ) - { - double modulus = System.Math.Sqrt(W * W + X * X + Y * Y + Z * Z); - if (modulus == 0) throw new DivideByZeroException(); - result.W = W / modulus; - result.X = X / modulus; - result.Y = Y / modulus; - result.Z = Z / modulus; - } - public static void Normalize(ref Quaterniond Quaterniond, out Quaterniond result) - { - double modulus = System.Math.Sqrt(Quaterniond.W * Quaterniond.W + Quaterniond.X * Quaterniond.X + Quaterniond.Y * Quaterniond.Y + Quaterniond.Z * Quaterniond.Z); - if (modulus == 0) throw new DivideByZeroException(); - result.W = Quaterniond.W / modulus; - result.X = Quaterniond.X / modulus; - result.Y = Quaterniond.Y / modulus; - result.Z = Quaterniond.Z / modulus; - } - - public void Conjugate() - { - X = -X; - Y = -Y; - Z = -Z; - } - public void Conjugate( out Quaterniond result ) - { - result.W = W; - result.X = -X; - result.Y = -Y; - result.Z = -Z; - } - public static void Conjugate(ref Quaterniond Quaterniond, out Quaterniond result) - { - result.W = Quaterniond.W; - result.X = -Quaterniond.X; - result.Y = -Quaterniond.Y; - result.Z = -Quaterniond.Z; - } - - public void Inverse() - { - double modulusSquared = W * W + X * X + Y * Y + Z * Z; - if (modulusSquared <= 0) throw new InvalidOperationException(); - double inverseModulusSquared = 1.0 / modulusSquared; - W = W * inverseModulusSquared; - X = X * -inverseModulusSquared; - Y = Y * -inverseModulusSquared; - Z = Z * -inverseModulusSquared; - } - public void Inverse( out Quaterniond result ) - { - double modulusSquared = W * W + X * X + Y * Y + Z * Z; - if (modulusSquared <= 0) throw new InvalidOperationException(); - double inverseModulusSquared = 1.0 / modulusSquared; - result.W = W * inverseModulusSquared; - result.X = X * -inverseModulusSquared; - result.Y = Y * -inverseModulusSquared; - result.Z = Z * -inverseModulusSquared; - } - public static void Inverse(ref Quaterniond Quaterniond, out Quaterniond result) - { - double modulusSquared = Quaterniond.W * Quaterniond.W + Quaterniond.X * Quaterniond.X + Quaterniond.Y * Quaterniond.Y + Quaterniond.Z * Quaterniond.Z; - if (modulusSquared <= 0) throw new InvalidOperationException(); - double inverseModulusSquared = 1.0 / modulusSquared; - result.W = Quaterniond.W * inverseModulusSquared; - result.X = Quaterniond.X * -inverseModulusSquared; - result.Y = Quaterniond.Y * -inverseModulusSquared; - result.Z = Quaterniond.Z * -inverseModulusSquared; - } - - public void Log() - { - if (System.Math.Abs(W) < 1.0) - { - double angle = System.Math.Acos(W); - double sin = System.Math.Sin(angle); - - if (System.Math.Abs(sin) >= 0) - { - double coefficient = angle / sin; - X = X * coefficient; - Y = Y * coefficient; - Z = Z * coefficient; - } - } - else - { - X = 0; - Y = 0; - Z = 0; - } - - W = 0; - } - public void Log( out Quaterniond result ) - { - if (System.Math.Abs(W) < 1.0) - { - double angle = System.Math.Acos(W); - double sin = System.Math.Sin(angle); - - if (System.Math.Abs(sin) >= 0) - { - double coefficient = angle / sin; - result.X = X * coefficient; - result.Y = Y * coefficient; - result.Z = Z * coefficient; - } - else - { - result.X = X; - result.Y = Y; - result.Z = Z; - } - } - else - { - result.X = 0; - result.Y = 0; - result.Z = 0; - } - - result.W = 0; - } - public static void Log(ref Quaterniond Quaterniond, out Quaterniond result) - { - if (System.Math.Abs(Quaterniond.W) < 1.0) - { - double angle = System.Math.Acos(Quaterniond.W); - double sin = System.Math.Sin(angle); - - if (System.Math.Abs(sin) >= 0) - { - double coefficient = angle / sin; - result.X = Quaterniond.X * coefficient; - result.Y = Quaterniond.Y * coefficient; - result.Z = Quaterniond.Z * coefficient; - } - else - { - result.X = Quaterniond.X; - result.Y = Quaterniond.Y; - result.Z = Quaterniond.Z; - } - } - else - { - result.X = 0; - result.Y = 0; - result.Z = 0; - } - - result.W = 0; - } - - public void Exp() - { - double angle = System.Math.Sqrt(X * X + Y * Y + Z * Z); - double sin = System.Math.Sin(angle); - - if (System.Math.Abs(sin) > 0) - { - double coefficient = angle / sin; - W = 0; - X = X * coefficient; - Y = Y * coefficient; - Z = Z * coefficient; - } - else - { - W = 0; - } - } - public void Exp(out Quaterniond result) - { - double angle = System.Math.Sqrt(X * X + Y * Y + Z * Z); - double sin = System.Math.Sin(angle); - - if (System.Math.Abs(sin) > 0) - { - double coefficient = angle / sin; - result.W = 0; - result.X = X * coefficient; - result.Y = Y * coefficient; - result.Z = Z * coefficient; - } - else - { - result.W = 0; - result.X = X; - result.Y = Y; - result.Z = Z; - } - } - public static void Exp(ref Quaterniond Quaterniond, out Quaterniond result) - { - double angle = System.Math.Sqrt(Quaterniond.X * Quaterniond.X + Quaterniond.Y * Quaterniond.Y + Quaterniond.Z * Quaterniond.Z); - double sin = System.Math.Sin(angle); - - if (System.Math.Abs(sin) > 0) - { - double coefficient = angle / sin; - result.W = 0; - result.X = Quaterniond.X * coefficient; - result.Y = Quaterniond.Y * coefficient; - result.Z = Quaterniond.Z * coefficient; - } - else - { - result.W = 0; - result.X = Quaterniond.X; - result.Y = Quaterniond.Y; - result.Z = Quaterniond.Z; - } - } - - /// Returns left matrix for this Quaterniond. - public void Matrix4d(out Matrix4d result) - { - // TODO Expand - result = new Matrix4d(ref this); - } - - public void GetAxisAndAngle(out Vector3d axis, out double angle) - { - Quaterniond Quaterniond; - Normalize(out Quaterniond); - double cos = Quaterniond.W; - angle = System.Math.Acos(cos) * 2 * Functions.RTOD; - double sin = System.Math.Sqrt( 1.0d - cos * cos ); - if ( System.Math.Abs( sin ) < 0.0001 ) sin = 1; - axis = new Vector3d(X / sin, Y / sin, Z / sin); - } - - public static void Slerp(ref Quaterniond start, ref Quaterniond end, double blend, out Quaterniond result) - { - if (start.W == 0 && start.X == 0 && start.Y == 0 && start.Z == 0) - { - if (end.W == 0 && end.X == 0 && end.Y == 0 && end.Z == 0) - { - result.W = 1; - result.X = 0; - result.Y = 0; - result.Z = 0; - } - else - { - result = end; - } - } - else if (end.W == 0 && end.X == 0 && end.Y == 0 && end.Z == 0) - { - result = start; - } - - Vector3d startVector = new Vector3d(start.X, start.Y, start.Z); - Vector3d endVector = new Vector3d(end.X, end.Y, end.Z); - double cosHalfAngle = start.W * end.W + Vector3d.Dot(startVector, endVector); - - if (cosHalfAngle >= 1.0f || cosHalfAngle <= -1.0f) - { - // angle = 0.0f, so just return one input. - result = start; - } - else if (cosHalfAngle < 0.0f) - { - end.W = -end.W; - end.X = -end.X; - end.Y = -end.Y; - end.Z = -end.Z; - cosHalfAngle = -cosHalfAngle; - } - - double blendA; - double blendB; - if (cosHalfAngle < 0.99f) - { - // do proper slerp for big angles - double halfAngle = (double)System.Math.Acos(cosHalfAngle); - double sinHalfAngle = (double)System.Math.Sin(halfAngle); - double oneOverSinHalfAngle = 1.0f / sinHalfAngle; - blendA = (double)System.Math.Sin(halfAngle * (1.0f - blend)) * oneOverSinHalfAngle; - blendB = (double)System.Math.Sin(halfAngle * blend) * oneOverSinHalfAngle; - } - else - { - // do lerp if angle is really small. - blendA = 1.0f - blend; - blendB = blend; - } - - result.W = blendA * start.W + blendB * end.W; - result.X = blendA * start.X + blendB * end.X; - result.Y = blendA * start.Y + blendB * end.Y; - result.Z = blendA * start.Z + blendB * end.Z; - - if (result.W != 0 || result.X != 0 || result.Y != 0 || result.Z != 0) - { - result.Normalize(); - } - else - { - result.W = 1; - result.X = 0; - result.Y = 0; - result.Z = 0; - } - } - - #endregion - - #region HashCode - - /// Returns the hash code for this instance. - /// A 32-bit signed integer that is the hash code for this instance. - public override int GetHashCode() - { - base.GetHashCode(); - return W.GetHashCode() ^ X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); - } - - #endregion - - #region String and Parse - - /// Returns the fully qualified type name of this instance. - /// A System.String containing left fully qualified type name. - public override string ToString() - { - return string.Format("({0}, {1}, {2}, {3})", W, X, Y, Z); - } - - /// Parses left string, converting it to left Quaterniond. - /// The string to parse. - /// The Quaterniond represented by the string. - public static void Parse(string str, out Quaterniond result) - { - Match match = new Regex(@"\((?.*),(?.*),(?.*),(?.*)\)", RegexOptions.None).Match(str); - if (!match.Success) throw new Exception("Parse failed!"); - - result.W = double.Parse(match.Result("${w}")); - result.X = double.Parse(match.Result("${x}")); - result.Y = double.Parse(match.Result("${y}")); - result.Z = double.Parse(match.Result("${z}")); - } - - #endregion - - #region Constants - - /// A quaterion with all zero components. - public static readonly Quaterniond Zero = new Quaterniond(0, 0, 0, 0); - - /// A quaterion representing an identity. - public static readonly Quaterniond Identity = new Quaterniond(1, 0, 0, 0); - - /// A quaterion representing the W axis. - public static readonly Quaterniond WAxis = new Quaterniond(1, 0, 0, 0); - - /// A quaterion representing the X axis. - public static readonly Quaterniond XAxis = new Quaterniond(0, 1, 0, 0); - - /// A quaterion representing the Y axis. - public static readonly Quaterniond YAxis = new Quaterniond(0, 0, 1, 0); - - /// A quaterion representing the Z axis. - public static readonly Quaterniond ZAxis = new Quaterniond(0, 0, 0, 1); - - #endregion - -#endif - - #region IEquatable Members - - /// - /// Compares this Quaterniond instance to another Quaterniond for equality. - /// - /// The other Quaterniond to be used in the comparison. - /// True if both instances are equal; false otherwise. - public bool Equals(Quaterniond other) - { - return Xyz == other.Xyz && W == other.W; - } - - #endregion - } -} \ No newline at end of file diff --git a/OpenTK/Math/Rectangle.cs b/OpenTK/Math/Rectangle.cs deleted file mode 100644 index 0b3a28dd..00000000 --- a/OpenTK/Math/Rectangle.cs +++ /dev/null @@ -1,323 +0,0 @@ -#region License - // - // The Open Toolkit Library License - // - // Copyright (c) 2006 - 2009 the Open Toolkit library. - // - // Permission is hereby granted, free of charge, to any person obtaining a copy - // of this software and associated documentation files (the "Software"), to deal - // in the Software without restriction, including without limitation the rights to - // use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of - // the Software, and to permit persons to whom the Software is furnished to do - // so, subject to the following conditions: - // - // The above copyright notice and this permission notice shall be included in all - // copies or substantial portions of the Software. - // - // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES - // OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT - // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, - // WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR - // OTHER DEALINGS IN THE SOFTWARE. - // - #endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenTK -{ -#if NO_SYSDRAWING - /// - /// Represents a rectangular region on a two-dimensional plane. - /// - public struct Rectangle : IEquatable - { - #region Fields - - Point location; - Size size; - - #endregion - - #region Constructors - - /// - /// Constructs a new Rectangle instance. - /// - /// The top-left corner of the Rectangle. - /// The width and height of the Rectangle. - public Rectangle(Point location, Size size) - : this() - { - Location = location; - Size = size; - } - - /// - /// Constructs a new Rectangle instance. - /// - /// The x coordinate of the Rectangle. - /// The y coordinate of the Rectangle. - /// The width coordinate of the Rectangle. - /// The height coordinate of the Rectangle. - public Rectangle(int x, int y, int width, int height) - : this(new Point(x, y), new Size(width, height)) - { } - - #endregion - - #region Public Members - - /// - /// Gets or sets the x coordinate of the Rectangle. - /// - public int X - { - get { return Location.X; } - set { Location = new Point (value, Y); } - } - - /// - /// Gets or sets the y coordinate of the Rectangle. - /// - public int Y - { - get { return Location.Y; } - set { Location = new Point (X, value); } - } - - /// - /// Gets or sets the width of the Rectangle. - /// - public int Width - { - get { return Size.Width; } - set { Size = new Size (value, Height); } - } - - /// - /// Gets or sets the height of the Rectangle. - /// - public int Height - { - get { return Size.Height; } - set { Size = new Size(Width, value); } - } - - /// - /// Gets or sets a representing the x and y coordinates - /// of the Rectangle. - /// - public Point Location - { - get { return location; } - set { location = value; } - } - - /// - /// Gets or sets a representing the width and height - /// of the Rectangle. - /// - public Size Size - { - get { return size; } - set { size = value; } - } - - /// - /// Gets the y coordinate of the top edge of this Rectangle. - /// - public int Top { get { return Y; } } - - /// - /// Gets the x coordinate of the right edge of this Rectangle. - /// - public int Right { get { return X + Width; } } - - /// - /// Gets the y coordinate of the bottom edge of this Rectangle. - /// - public int Bottom { get { return Y + Height; } } - - /// - /// Gets the x coordinate of the left edge of this Rectangle. - /// - public int Left { get { return X; } } - - /// - /// Gets a that indicates whether this - /// Rectangle is equal to the empty Rectangle. - /// - public bool IsEmpty - { - get { return Location.IsEmpty && Size.IsEmpty; } - } - - /// - /// Defines the empty Rectangle. - /// - public static readonly Rectangle Zero = new Rectangle(); - - /// - /// Defines the empty Rectangle. - /// - public static readonly Rectangle Empty = new Rectangle(); - - /// - /// Constructs a new instance with the specified edges. - /// - /// The left edge of the Rectangle. - /// The top edge of the Rectangle. - /// The right edge of the Rectangle. - /// The bottom edge of the Rectangle. - /// A new Rectangle instance with the specified edges. - public static Rectangle FromLTRB(int left, int top, int right, int bottom) - { - return new Rectangle(new Point(left, top), new Size(right - left, bottom - top)); - } - - /// - /// Tests whether this instance contains the specified Point. - /// - /// The to test. - /// True if this instance contains point; false otherwise. - /// The left and top edges are inclusive. The right and bottom edges - /// are exclusive. - public bool Contains(Point point) - { - return point.X >= Left && point.X < Right && - point.Y >= Top && point.Y < Bottom; - } - - /// - /// Tests whether this instance contains the specified Rectangle. - /// - /// The to test. - /// True if this instance contains rect; false otherwise. - /// The left and top edges are inclusive. The right and bottom edges - /// are exclusive. - public bool Contains(Rectangle rect) - { - return Contains(rect.Location) && Contains(rect.Location + rect.Size); - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left is equal to right; false otherwise. - public static bool operator ==(Rectangle left, Rectangle right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left is not equal to right; false otherwise. - public static bool operator !=(Rectangle left, Rectangle right) - { - return !left.Equals(right); - } - - /// - /// Converts an OpenTK.Rectangle instance to a System.Drawing.Rectangle. - /// - /// - /// The instance to convert. - /// - /// - /// A instance equivalent to rect. - /// - public static implicit operator System.Drawing.Rectangle(Rectangle rect) - { - return new System.Drawing.Rectangle(rect.Location, rect.Size); - } - - /// - /// Converts a System.Drawing.Rectangle instance to an OpenTK.Rectangle. - /// - /// - /// The instance to convert. - /// - /// - /// A instance equivalent to point. - /// - public static implicit operator Rectangle(System.Drawing.Rectangle rect) - { - return new Rectangle(rect.Location, rect.Size); - } - - /// - /// Converts an OpenTK.Rectangle instance to a System.Drawing.RectangleF. - /// - /// - /// The instance to convert. - /// - /// - /// A instance equivalent to rect. - /// - public static implicit operator System.Drawing.RectangleF(Rectangle rect) - { - return new System.Drawing.RectangleF(rect.Location, rect.Size); - } - - /// - /// Indicates whether this instance is equal to the specified object. - /// - /// The object instance to compare to. - /// True, if both instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (obj is Rectangle) - return Equals((Rectangle)obj); - - return false; - } - - /// - /// Returns the hash code for this instance. - /// - /// A that represents the hash code for this instance./> - public override int GetHashCode() - { - return Location.GetHashCode() & Size.GetHashCode(); - } - - /// - /// Returns a that describes this instance. - /// - /// A that describes this instance. - public override string ToString() - { - return String.Format("{{{0}-{1}}}", Location, Location + Size); - } - - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether this instance is equal to the specified Rectangle. - /// - /// The instance to compare to. - /// True, if both instances are equal; false otherwise. - public bool Equals(Rectangle other) - { - return Location.Equals(other.Location) && - Size.Equals(other.Size); - } - - #endregion - } -#endif -} diff --git a/OpenTK/Math/Size.cs b/OpenTK/Math/Size.cs deleted file mode 100644 index baadb4bc..00000000 --- a/OpenTK/Math/Size.cs +++ /dev/null @@ -1,222 +0,0 @@ -#region License -// -// The Open Toolkit Library License -// -// Copyright (c) 2006 - 2009 the Open Toolkit library. -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights to -// use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of -// the Software, and to permit persons to whom the Software is furnished to do -// so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -// OTHER DEALINGS IN THE SOFTWARE. -// -#endregion - -using System; -using System.Collections.Generic; -using System.Text; - -namespace OpenTK -{ -#if NO_SYSDRAWING - /// - /// Stores the width and height of a rectangle. - /// - public struct Size : IEquatable - { - #region Fields - - int width, height; - - #endregion - - #region Constructors - - /// - /// Constructs a new Size instance. - /// - /// The width of this instance. - /// The height of this instance. - public Size(int width, int height) - : this() - { - Width = width; - Height = height; - } - - #endregion - - #region Public Members - - /// - /// Gets or sets the width of this instance. - /// - public int Width - { - get { return width; } - set - { - if (width < 0) - throw new ArgumentOutOfRangeException(); - width = value; - } - } - - /// - /// Gets or sets the height of this instance. - /// - public int Height - { - get { return height; } - set - { - if (height < 0) - throw new ArgumentOutOfRangeException(); - height = value; - } - } - - /// - /// Gets a that indicates whether this instance is empty or zero. - /// - public bool IsEmpty - { - get { return Width == 0 && Height == 0; } - } - - /// - /// Returns a Size instance equal to (0, 0). - /// - public static readonly Size Empty = new Size(); - - /// - /// Returns a Size instance equal to (0, 0). - /// - public static readonly Size Zero = new Size(); - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left is equal to right; false otherwise. - public static bool operator ==(Size left, Size right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left is not equal to right; false otherwise. - public static bool operator !=(Size left, Size right) - { - return !left.Equals(right); - } - - /// - /// Converts an OpenTK.Size instance to a System.Drawing.Size. - /// - /// - /// The instance to convert. - /// - /// - /// A instance equivalent to size. - /// - public static implicit operator System.Drawing.Size(Size size) -{ - return new System.Drawing.Size(size.Width, size.Height); - } - - /// - /// Converts a System.Drawing.Size instance to an OpenTK.Size. - /// - /// - /// The instance to convert. - /// - /// - /// A instance equivalent to size. - /// - public static implicit operator Size(System.Drawing.Size size) - { - return new Size(size.Width, size.Height); - } - - /// - /// Converts an OpenTK.Point instance to a System.Drawing.SizeF. - /// - /// - /// The instance to convert. - /// - /// - /// A instance equivalent to size. - /// - public static implicit operator System.Drawing.SizeF(Size size) - { - return new System.Drawing.SizeF(size.Width, size.Height); - } - - /// - /// Indicates whether this instance is equal to the specified object. - /// - /// The object instance to compare to. - /// True, if both instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (obj is Size) - return Equals((Size)obj); - - return false; - } - - /// - /// Returns the hash code for this instance. - /// - /// A that represents the hash code for this instance./> - public override int GetHashCode() - { - return Width.GetHashCode() ^ Height.GetHashCode(); - } - - /// - /// Returns a that describes this instance. - /// - /// A that describes this instance. - public override string ToString() - { - return String.Format("{{{0}, {1}}}", Width, Height); - } - - #endregion - - #region IEquatable Members - - /// - /// Indicates whether this instance is equal to the specified Size. - /// - /// The instance to compare to. - /// True, if both instances are equal; false otherwise. - public bool Equals(Size other) - { - return Width == other.Width && Height == other.Height; - } - - #endregion - } -#endif -} diff --git a/OpenTK/Math/Vector2.cs b/OpenTK/Math/Vector2.cs deleted file mode 100644 index 4d1064a6..00000000 --- a/OpenTK/Math/Vector2.cs +++ /dev/null @@ -1,1180 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; -using System.Xml.Serialization; - -namespace OpenTK -{ - /// Represents a 2D vector using two single-precision floating-point numbers. - /// - /// The Vector2 structure is suitable for interoperation with unmanaged code requiring two consecutive floats. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Vector2 : IEquatable - { - #region Fields - - /// - /// The X component of the Vector2. - /// - public float X; - - /// - /// The Y component of the Vector2. - /// - public float Y; - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector2(float value) - { - X = value; - Y = value; - } - - /// - /// Constructs a new Vector2. - /// - /// The x coordinate of the net Vector2. - /// The y coordinate of the net Vector2. - public Vector2(float x, float y) - { - X = x; - Y = y; - } - - /// - /// Constructs a new Vector2 from the given Vector2. - /// - /// The Vector2 to copy components from. - [Obsolete] - public Vector2(Vector2 v) - { - X = v.X; - Y = v.Y; - } - - /// - /// Constructs a new Vector2 from the given Vector3. - /// - /// The Vector3 to copy components from. Z is discarded. - [Obsolete] - public Vector2(Vector3 v) - { - X = v.X; - Y = v.Y; - } - - /// - /// Constructs a new Vector2 from the given Vector4. - /// - /// The Vector4 to copy components from. Z and W are discarded. - [Obsolete] - public Vector2(Vector4 v) - { - X = v.X; - Y = v.Y; - } - - #endregion - - #region Public Members - - /// - /// Gets or sets the value at the index of the Vector. - /// - public float this[int index] { - get{ - if(index == 0) return X; - else if(index == 1) return Y; - throw new IndexOutOfRangeException("You tried to access this vector at index: " + index); - } set{ - if(index == 0) X = value; - else if(index == 1) Y = value; - else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index); - } - } - - #region Instance - - #region public void Add() - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(Vector2 right) - { - this.X += right.X; - this.Y += right.Y; - } - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(ref Vector2 right) - { - this.X += right.X; - this.Y += right.Y; - } - - #endregion public void Add() - - #region public void Sub() - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(Vector2 right) - { - this.X -= right.X; - this.Y -= right.Y; - } - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(ref Vector2 right) - { - this.X -= right.X; - this.Y -= right.Y; - } - - #endregion public void Sub() - - #region public void Mult() - - /// Multiply this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Multiply() method instead.")] - public void Mult(float f) - { - this.X *= f; - this.Y *= f; - } - - #endregion public void Mult() - - #region public void Div() - - /// Divide this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Divide() method instead.")] - public void Div(float f) - { - float mult = 1.0f / f; - this.X *= mult; - this.Y *= mult; - } - - #endregion public void Div() - - #region public float Length - - /// - /// Gets the length (magnitude) of the vector. - /// - /// - /// - public float Length - { - get - { - return (float)System.Math.Sqrt(X * X + Y * Y); - } - } - - #endregion - - #region public float LengthFast - - /// - /// Gets an approximation of the vector length (magnitude). - /// - /// - /// This property uses an approximation of the square root function to calculate vector magnitude, with - /// an upper error bound of 0.001. - /// - /// - /// - public float LengthFast - { - get - { - return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y); - } - } - - #endregion - - #region public float LengthSquared - - /// - /// Gets the square of the vector length (magnitude). - /// - /// - /// This property avoids the costly square root operation required by the Length property. This makes it more suitable - /// for comparisons. - /// - /// - /// - public float LengthSquared - { - get - { - return X * X + Y * Y; - } - } - - #endregion - - #region public Vector2 PerpendicularRight - - /// - /// Gets the perpendicular vector on the right side of this vector. - /// - public Vector2 PerpendicularRight - { - get - { - return new Vector2(Y, -X); - } - } - - #endregion - - #region public Vector2 PerpendicularLeft - - /// - /// Gets the perpendicular vector on the left side of this vector. - /// - public Vector2 PerpendicularLeft - { - get - { - return new Vector2(-Y, X); - } - } - - #endregion - - /// - /// Returns a copy of the Vector2 scaled to unit length. - /// - /// - public Vector2 Normalized() - { - Vector2 v = this; - v.Normalize(); - return v; - } - #region public void Normalize() - - /// - /// Scales the Vector2 to unit length. - /// - public void Normalize() - { - float scale = 1.0f / this.Length; - X *= scale; - Y *= scale; - } - - #endregion - - #region public void NormalizeFast() - - /// - /// Scales the Vector2 to approximately unit length. - /// - public void NormalizeFast() - { - float scale = MathHelper.InverseSqrtFast(X * X + Y * Y); - X *= scale; - Y *= scale; - } - - #endregion - - #region public void Scale() - - /// - /// Scales the current Vector2 by the given amounts. - /// - /// The scale of the X component. - /// The scale of the Y component. - [Obsolete("Use static Multiply() method instead.")] - public void Scale(float sx, float sy) - { - this.X = X * sx; - this.Y = Y * sy; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(Vector2 scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(ref Vector2 scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - } - - #endregion public void Scale() - - #endregion - - #region Static - - #region Fields - - /// - /// Defines a unit-length Vector2 that points towards the X-axis. - /// - public static readonly Vector2 UnitX = new Vector2(1, 0); - - /// - /// Defines a unit-length Vector2 that points towards the Y-axis. - /// - public static readonly Vector2 UnitY = new Vector2(0, 1); - - /// - /// Defines a zero-length Vector2. - /// - public static readonly Vector2 Zero = new Vector2(0, 0); - - /// - /// Defines an instance with all components set to 1. - /// - public static readonly Vector2 One = new Vector2(1, 1); - - /// - /// Defines the size of the Vector2 struct in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(new Vector2()); - - #endregion - - #region Obsolete - - #region Sub - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static Vector2 Sub(Vector2 a, Vector2 b) - { - a.X -= b.X; - a.Y -= b.Y; - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static void Sub(ref Vector2 a, ref Vector2 b, out Vector2 result) - { - result.X = a.X - b.X; - result.Y = a.Y - b.Y; - } - - #endregion - - #region Mult - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static Vector2 Mult(Vector2 a, float f) - { - a.X *= f; - a.Y *= f; - return a; - } - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static void Mult(ref Vector2 a, float f, out Vector2 result) - { - result.X = a.X * f; - result.Y = a.Y * f; - } - - #endregion - - #region Div - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static Vector2 Div(Vector2 a, float f) - { - float mult = 1.0f / f; - a.X *= mult; - a.Y *= mult; - return a; - } - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static void Div(ref Vector2 a, float f, out Vector2 result) - { - float mult = 1.0f / f; - result.X = a.X * mult; - result.Y = a.Y * mult; - } - - #endregion - - #endregion - - #region Add - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static Vector2 Add(Vector2 a, Vector2 b) - { - Add(ref a, ref b, out a); - return a; - } - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static void Add(ref Vector2 a, ref Vector2 b, out Vector2 result) - { - result = new Vector2(a.X + b.X, a.Y + b.Y); - } - - #endregion - - #region Subtract - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static Vector2 Subtract(Vector2 a, Vector2 b) - { - Subtract(ref a, ref b, out a); - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static void Subtract(ref Vector2 a, ref Vector2 b, out Vector2 result) - { - result = new Vector2(a.X - b.X, a.Y - b.Y); - } - - #endregion - - #region Multiply - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector2 Multiply(Vector2 vector, float scale) - { - Multiply(ref vector, scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector2 vector, float scale, out Vector2 result) - { - result = new Vector2(vector.X * scale, vector.Y * scale); - } - - /// - /// Multiplies a vector by the components a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector2 Multiply(Vector2 vector, Vector2 scale) - { - Multiply(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector2 vector, ref Vector2 scale, out Vector2 result) - { - result = new Vector2(vector.X * scale.X, vector.Y * scale.Y); - } - - #endregion - - #region Divide - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector2 Divide(Vector2 vector, float scale) - { - Divide(ref vector, scale, out vector); - return vector; - } - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector2 vector, float scale, out Vector2 result) - { - Multiply(ref vector, 1 / scale, out result); - } - - /// - /// Divides a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector2 Divide(Vector2 vector, Vector2 scale) - { - Divide(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Divide a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector2 vector, ref Vector2 scale, out Vector2 result) - { - result = new Vector2(vector.X / scale.X, vector.Y / scale.Y); - } - - #endregion - - #region ComponentMin - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static Vector2 ComponentMin(Vector2 a, Vector2 b) - { - a.X = a.X < b.X ? a.X : b.X; - a.Y = a.Y < b.Y ? a.Y : b.Y; - return a; - } - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static void ComponentMin(ref Vector2 a, ref Vector2 b, out Vector2 result) - { - result.X = a.X < b.X ? a.X : b.X; - result.Y = a.Y < b.Y ? a.Y : b.Y; - } - - #endregion - - #region ComponentMax - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static Vector2 ComponentMax(Vector2 a, Vector2 b) - { - a.X = a.X > b.X ? a.X : b.X; - a.Y = a.Y > b.Y ? a.Y : b.Y; - return a; - } - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static void ComponentMax(ref Vector2 a, ref Vector2 b, out Vector2 result) - { - result.X = a.X > b.X ? a.X : b.X; - result.Y = a.Y > b.Y ? a.Y : b.Y; - } - - #endregion - - #region Min - - /// - /// Returns the Vector3 with the minimum magnitude - /// - /// Left operand - /// Right operand - /// The minimum Vector3 - public static Vector2 Min(Vector2 left, Vector2 right) - { - return left.LengthSquared < right.LengthSquared ? left : right; - } - - #endregion - - #region Max - - /// - /// Returns the Vector3 with the minimum magnitude - /// - /// Left operand - /// Right operand - /// The minimum Vector3 - public static Vector2 Max(Vector2 left, Vector2 right) - { - return left.LengthSquared >= right.LengthSquared ? left : right; - } - - #endregion - - #region Clamp - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static Vector2 Clamp(Vector2 vec, Vector2 min, Vector2 max) - { - vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - return vec; - } - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static void Clamp(ref Vector2 vec, ref Vector2 min, ref Vector2 max, out Vector2 result) - { - result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - } - - #endregion - - #region Normalize - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static Vector2 Normalize(Vector2 vec) - { - float scale = 1.0f / vec.Length; - vec.X *= scale; - vec.Y *= scale; - return vec; - } - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static void Normalize(ref Vector2 vec, out Vector2 result) - { - float scale = 1.0f / vec.Length; - result.X = vec.X * scale; - result.Y = vec.Y * scale; - } - - #endregion - - #region NormalizeFast - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static Vector2 NormalizeFast(Vector2 vec) - { - float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y); - vec.X *= scale; - vec.Y *= scale; - return vec; - } - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static void NormalizeFast(ref Vector2 vec, out Vector2 result) - { - float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y); - result.X = vec.X * scale; - result.Y = vec.Y * scale; - } - - #endregion - - #region Dot - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static float Dot(Vector2 left, Vector2 right) - { - return left.X * right.X + left.Y * right.Y; - } - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static void Dot(ref Vector2 left, ref Vector2 right, out float result) - { - result = left.X * right.X + left.Y * right.Y; - } - - #endregion - - #region PerpDot - - /// - /// Calculate the perpendicular dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The perpendicular dot product of the two inputs - public static float PerpDot(Vector2 left, Vector2 right) - { - return left.X * right.Y - left.Y * right.X; - } - - /// - /// Calculate the perpendicular dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The perpendicular dot product of the two inputs - public static void PerpDot(ref Vector2 left, ref Vector2 right, out float result) - { - result = left.X * right.Y - left.Y * right.X; - } - - #endregion - - #region Lerp - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static Vector2 Lerp(Vector2 a, Vector2 b, float blend) - { - a.X = blend * (b.X - a.X) + a.X; - a.Y = blend * (b.Y - a.Y) + a.Y; - return a; - } - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static void Lerp(ref Vector2 a, ref Vector2 b, float blend, out Vector2 result) - { - result.X = blend * (b.X - a.X) + a.X; - result.Y = blend * (b.Y - a.Y) + a.Y; - } - - #endregion - - #region Barycentric - - /// - /// Interpolate 3 Vectors using Barycentric coordinates - /// - /// First input Vector - /// Second input Vector - /// Third input Vector - /// First Barycentric Coordinate - /// Second Barycentric Coordinate - /// a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static Vector2 BaryCentric(Vector2 a, Vector2 b, Vector2 c, float u, float v) - { - return a + u * (b - a) + v * (c - a); - } - - /// Interpolate 3 Vectors using Barycentric coordinates - /// First input Vector. - /// Second input Vector. - /// Third input Vector. - /// First Barycentric Coordinate. - /// Second Barycentric Coordinate. - /// Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static void BaryCentric(ref Vector2 a, ref Vector2 b, ref Vector2 c, float u, float v, out Vector2 result) - { - result = a; // copy - - Vector2 temp = b; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, u, out temp); - Add(ref result, ref temp, out result); - - temp = c; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, v, out temp); - Add(ref result, ref temp, out result); - } - - #endregion - - #region Transform - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static Vector2 Transform(Vector2 vec, Quaternion quat) - { - Vector2 result; - Transform(ref vec, ref quat, out result); - return result; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static void Transform(ref Vector2 vec, ref Quaternion quat, out Vector2 result) - { - Quaternion v = new Quaternion(vec.X, vec.Y, 0, 0), i, t; - Quaternion.Invert(ref quat, out i); - Quaternion.Multiply(ref quat, ref v, out t); - Quaternion.Multiply(ref t, ref i, out v); - - result = new Vector2(v.X, v.Y); - } - - #endregion - - #endregion - - #region Swizzle - - /// - /// Gets or sets an OpenTK.Vector2 with the Y and X components of this instance. - /// - [XmlIgnore] - public Vector2 Yx { get { return new Vector2(Y, X); } set { Y = value.X; X = value.Y; } } - - #endregion - - #region Operators - - /// - /// Adds the specified instances. - /// - /// Left operand. - /// Right operand. - /// Result of addition. - public static Vector2 operator +(Vector2 left, Vector2 right) - { - left.X += right.X; - left.Y += right.Y; - return left; - } - - /// - /// Subtracts the specified instances. - /// - /// Left operand. - /// Right operand. - /// Result of subtraction. - public static Vector2 operator -(Vector2 left, Vector2 right) - { - left.X -= right.X; - left.Y -= right.Y; - return left; - } - - /// - /// Negates the specified instance. - /// - /// Operand. - /// Result of negation. - public static Vector2 operator -(Vector2 vec) - { - vec.X = -vec.X; - vec.Y = -vec.Y; - return vec; - } - - /// - /// Multiplies the specified instance by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of multiplication. - public static Vector2 operator *(Vector2 vec, float scale) - { - vec.X *= scale; - vec.Y *= scale; - return vec; - } - - /// - /// Multiplies the specified instance by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of multiplication. - public static Vector2 operator *(float scale, Vector2 vec) - { - vec.X *= scale; - vec.Y *= scale; - return vec; - } - - /// - /// Component-wise multiplication between the specified instance by a scale vector. - /// - /// Left operand. - /// Right operand. - /// Result of multiplication. - public static Vector2 operator *(Vector2 vec, Vector2 scale) - { - vec.X *= scale.X; - vec.Y *= scale.Y; - return vec; - } - - /// - /// Divides the specified instance by a scalar. - /// - /// Left operand - /// Right operand - /// Result of the division. - public static Vector2 operator /(Vector2 vec, float scale) - { - float mult = 1.0f / scale; - vec.X *= mult; - vec.Y *= mult; - return vec; - } - - /// - /// Compares the specified instances for equality. - /// - /// Left operand. - /// Right operand. - /// True if both instances are equal; false otherwise. - public static bool operator ==(Vector2 left, Vector2 right) - { - return left.Equals(right); - } - - /// - /// Compares the specified instances for inequality. - /// - /// Left operand. - /// Right operand. - /// True if both instances are not equal; false otherwise. - public static bool operator !=(Vector2 left, Vector2 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator; - /// - /// Returns a System.String that represents the current Vector2. - /// - /// - public override string ToString() - { - return String.Format("({0}{2} {1})", X, Y, listSeparator); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Vector2)) - return false; - - return this.Equals((Vector2)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current vector is equal to another vector. - /// A vector to compare with this vector. - /// true if the current vector is equal to the vector parameter; otherwise, false. - public bool Equals(Vector2 other) - { - return - X == other.X && - Y == other.Y; - } - - #endregion - } -} diff --git a/OpenTK/Math/Vector2d.cs b/OpenTK/Math/Vector2d.cs deleted file mode 100644 index 8c3846cf..00000000 --- a/OpenTK/Math/Vector2d.cs +++ /dev/null @@ -1,1058 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#endregion - -using System; -using System.Runtime.InteropServices; -using System.Xml.Serialization; - -namespace OpenTK -{ - /// Represents a 2D vector using two double-precision floating-point numbers. - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Vector2d : IEquatable - { - #region Fields - - /// The X coordinate of this instance. - public double X; - - /// The Y coordinate of this instance. - public double Y; - - /// - /// Defines a unit-length Vector2d that points towards the X-axis. - /// - public static readonly Vector2d UnitX = new Vector2d(1, 0); - - /// - /// Defines a unit-length Vector2d that points towards the Y-axis. - /// - public static readonly Vector2d UnitY = new Vector2d(0, 1); - - /// - /// Defines a zero-length Vector2d. - /// - public static readonly Vector2d Zero = new Vector2d(0, 0); - - /// - /// Defines an instance with all components set to 1. - /// - public static readonly Vector2d One = new Vector2d(1, 1); - - /// - /// Defines the size of the Vector2d struct in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(new Vector2d()); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector2d(double value) - { - X = value; - Y = value; - } - - /// Constructs left vector with the given coordinates. - /// The X coordinate. - /// The Y coordinate. - public Vector2d(double x, double y) - { - this.X = x; - this.Y = y; - } - - #endregion - - #region Public Members - - /// - /// Gets or sets the value at the index of the Vector. - /// - public double this[int index] { - get{ - if(index == 0) return X; - else if(index == 1) return Y; - throw new IndexOutOfRangeException("You tried to access this vector at index: " + index); - } set{ - if(index == 0) X = value; - else if(index == 1) Y = value; - else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index); - } - } - - #region Instance - - #region public void Add() - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(Vector2d right) - { - this.X += right.X; - this.Y += right.Y; - } - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(ref Vector2d right) - { - this.X += right.X; - this.Y += right.Y; - } - - #endregion public void Add() - - #region public void Sub() - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(Vector2d right) - { - this.X -= right.X; - this.Y -= right.Y; - } - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(ref Vector2d right) - { - this.X -= right.X; - this.Y -= right.Y; - } - - #endregion public void Sub() - - #region public void Mult() - - /// Multiply this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Multiply() method instead.")] - public void Mult(double f) - { - this.X *= f; - this.Y *= f; - } - - #endregion public void Mult() - - #region public void Div() - - /// Divide this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Divide() method instead.")] - public void Div(double f) - { - double mult = 1.0 / f; - this.X *= mult; - this.Y *= mult; - } - - #endregion public void Div() - - #region public double Length - - /// - /// Gets the length (magnitude) of the vector. - /// - /// - public double Length - { - get - { - return System.Math.Sqrt(X * X + Y * Y); - } - } - - #endregion - - #region public double LengthSquared - - /// - /// Gets the square of the vector length (magnitude). - /// - /// - /// This property avoids the costly square root operation required by the Length property. This makes it more suitable - /// for comparisons. - /// - /// - public double LengthSquared - { - get - { - return X * X + Y * Y; - } - } - - #endregion - - #region public Vector2d PerpendicularRight - - /// - /// Gets the perpendicular vector on the right side of this vector. - /// - public Vector2d PerpendicularRight - { - get - { - return new Vector2d(Y, -X); - } - } - - #endregion - - #region public Vector2d PerpendicularLeft - - /// - /// Gets the perpendicular vector on the left side of this vector. - /// - public Vector2d PerpendicularLeft - { - get - { - return new Vector2d(-Y, X); - } - } - - #endregion - - /// - /// Returns a copy of the Vector2d scaled to unit length. - /// - /// - public Vector2d Normalized() - { - Vector2d v = this; - v.Normalize(); - return v; - } - - #region public void Normalize() - - /// - /// Scales the Vector2 to unit length. - /// - public void Normalize() - { - double scale = 1.0 / Length; - X *= scale; - Y *= scale; - } - - #endregion - - #region public void Scale() - - /// - /// Scales the current Vector2 by the given amounts. - /// - /// The scale of the X component. - /// The scale of the Y component. - [Obsolete("Use static Multiply() method instead.")] - public void Scale(double sx, double sy) - { - X *= sx; - Y *= sy; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(Vector2d scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(ref Vector2d scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - } - - #endregion public void Scale() - - #endregion - - #region Static - - #region Obsolete - - #region Sub - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static Vector2d Sub(Vector2d a, Vector2d b) - { - a.X -= b.X; - a.Y -= b.Y; - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static void Sub(ref Vector2d a, ref Vector2d b, out Vector2d result) - { - result.X = a.X - b.X; - result.Y = a.Y - b.Y; - } - - #endregion - - #region Mult - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static Vector2d Mult(Vector2d a, double d) - { - a.X *= d; - a.Y *= d; - return a; - } - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static void Mult(ref Vector2d a, double d, out Vector2d result) - { - result.X = a.X * d; - result.Y = a.Y * d; - } - - #endregion - - #region Div - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static Vector2d Div(Vector2d a, double d) - { - double mult = 1.0 / d; - a.X *= mult; - a.Y *= mult; - return a; - } - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static void Div(ref Vector2d a, double d, out Vector2d result) - { - double mult = 1.0 / d; - result.X = a.X * mult; - result.Y = a.Y * mult; - } - - #endregion - - #endregion - - #region Add - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static Vector2d Add(Vector2d a, Vector2d b) - { - Add(ref a, ref b, out a); - return a; - } - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static void Add(ref Vector2d a, ref Vector2d b, out Vector2d result) - { - result = new Vector2d(a.X + b.X, a.Y + b.Y); - } - - #endregion - - #region Subtract - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static Vector2d Subtract(Vector2d a, Vector2d b) - { - Subtract(ref a, ref b, out a); - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static void Subtract(ref Vector2d a, ref Vector2d b, out Vector2d result) - { - result = new Vector2d(a.X - b.X, a.Y - b.Y); - } - - #endregion - - #region Multiply - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector2d Multiply(Vector2d vector, double scale) - { - Multiply(ref vector, scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector2d vector, double scale, out Vector2d result) - { - result = new Vector2d(vector.X * scale, vector.Y * scale); - } - - /// - /// Multiplies a vector by the components a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector2d Multiply(Vector2d vector, Vector2d scale) - { - Multiply(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector2d vector, ref Vector2d scale, out Vector2d result) - { - result = new Vector2d(vector.X * scale.X, vector.Y * scale.Y); - } - - #endregion - - #region Divide - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector2d Divide(Vector2d vector, double scale) - { - Divide(ref vector, scale, out vector); - return vector; - } - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector2d vector, double scale, out Vector2d result) - { - Multiply(ref vector, 1 / scale, out result); - } - - /// - /// Divides a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector2d Divide(Vector2d vector, Vector2d scale) - { - Divide(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Divide a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector2d vector, ref Vector2d scale, out Vector2d result) - { - result = new Vector2d(vector.X / scale.X, vector.Y / scale.Y); - } - - #endregion - - #region Min - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static Vector2d Min(Vector2d a, Vector2d b) - { - a.X = a.X < b.X ? a.X : b.X; - a.Y = a.Y < b.Y ? a.Y : b.Y; - return a; - } - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static void Min(ref Vector2d a, ref Vector2d b, out Vector2d result) - { - result.X = a.X < b.X ? a.X : b.X; - result.Y = a.Y < b.Y ? a.Y : b.Y; - } - - #endregion - - #region Max - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static Vector2d Max(Vector2d a, Vector2d b) - { - a.X = a.X > b.X ? a.X : b.X; - a.Y = a.Y > b.Y ? a.Y : b.Y; - return a; - } - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static void Max(ref Vector2d a, ref Vector2d b, out Vector2d result) - { - result.X = a.X > b.X ? a.X : b.X; - result.Y = a.Y > b.Y ? a.Y : b.Y; - } - - #endregion - - #region Clamp - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static Vector2d Clamp(Vector2d vec, Vector2d min, Vector2d max) - { - vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - return vec; - } - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static void Clamp(ref Vector2d vec, ref Vector2d min, ref Vector2d max, out Vector2d result) - { - result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - } - - #endregion - - #region Normalize - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static Vector2d Normalize(Vector2d vec) - { - double scale = 1.0 / vec.Length; - vec.X *= scale; - vec.Y *= scale; - return vec; - } - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static void Normalize(ref Vector2d vec, out Vector2d result) - { - double scale = 1.0 / vec.Length; - result.X = vec.X * scale; - result.Y = vec.Y * scale; - } - - #endregion - - #region NormalizeFast - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static Vector2d NormalizeFast(Vector2d vec) - { - double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y); - vec.X *= scale; - vec.Y *= scale; - return vec; - } - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static void NormalizeFast(ref Vector2d vec, out Vector2d result) - { - double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y); - result.X = vec.X * scale; - result.Y = vec.Y * scale; - } - - #endregion - - #region Dot - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static double Dot(Vector2d left, Vector2d right) - { - return left.X * right.X + left.Y * right.Y; - } - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static void Dot(ref Vector2d left, ref Vector2d right, out double result) - { - result = left.X * right.X + left.Y * right.Y; - } - - #endregion - - #region Lerp - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static Vector2d Lerp(Vector2d a, Vector2d b, double blend) - { - a.X = blend * (b.X - a.X) + a.X; - a.Y = blend * (b.Y - a.Y) + a.Y; - return a; - } - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static void Lerp(ref Vector2d a, ref Vector2d b, double blend, out Vector2d result) - { - result.X = blend * (b.X - a.X) + a.X; - result.Y = blend * (b.Y - a.Y) + a.Y; - } - - #endregion - - #region Barycentric - - /// - /// Interpolate 3 Vectors using Barycentric coordinates - /// - /// First input Vector - /// Second input Vector - /// Third input Vector - /// First Barycentric Coordinate - /// Second Barycentric Coordinate - /// a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static Vector2d BaryCentric(Vector2d a, Vector2d b, Vector2d c, double u, double v) - { - return a + u * (b - a) + v * (c - a); - } - - /// Interpolate 3 Vectors using Barycentric coordinates - /// First input Vector. - /// Second input Vector. - /// Third input Vector. - /// First Barycentric Coordinate. - /// Second Barycentric Coordinate. - /// Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static void BaryCentric(ref Vector2d a, ref Vector2d b, ref Vector2d c, double u, double v, out Vector2d result) - { - result = a; // copy - - Vector2d temp = b; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, u, out temp); - Add(ref result, ref temp, out result); - - temp = c; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, v, out temp); - Add(ref result, ref temp, out result); - } - - #endregion - - #region Transform - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static Vector2d Transform(Vector2d vec, Quaterniond quat) - { - Vector2d result; - Transform(ref vec, ref quat, out result); - return result; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static void Transform(ref Vector2d vec, ref Quaterniond quat, out Vector2d result) - { - Quaterniond v = new Quaterniond(vec.X, vec.Y, 0, 0), i, t; - Quaterniond.Invert(ref quat, out i); - Quaterniond.Multiply(ref quat, ref v, out t); - Quaterniond.Multiply(ref t, ref i, out v); - - result = new Vector2d(v.X, v.Y); - } - - #endregion - - #endregion - - #region Swizzle - - /// - /// Gets or sets an OpenTK.Vector2d with the Y and X components of this instance. - /// - [XmlIgnore] - public Vector2d Yx { get { return new Vector2d(Y, X); } set { Y = value.X; X = value.Y; } } - - #endregion - - #region Operators - - /// - /// Adds two instances. - /// - /// The left instance. - /// The right instance. - /// The result of the operation. - public static Vector2d operator +(Vector2d left, Vector2d right) - { - left.X += right.X; - left.Y += right.Y; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The left instance. - /// The right instance. - /// The result of the operation. - public static Vector2d operator -(Vector2d left, Vector2d right) - { - left.X -= right.X; - left.Y -= right.Y; - return left; - } - - /// - /// Negates an instance. - /// - /// The instance. - /// The result of the operation. - public static Vector2d operator -(Vector2d vec) - { - vec.X = -vec.X; - vec.Y = -vec.Y; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the operation. - public static Vector2d operator *(Vector2d vec, double f) - { - vec.X *= f; - vec.Y *= f; - return vec; - } - - /// - /// Multiply an instance by a scalar. - /// - /// The scalar. - /// The instance. - /// The result of the operation. - public static Vector2d operator *(double f, Vector2d vec) - { - vec.X *= f; - vec.Y *= f; - return vec; - } - - /// - /// Component-wise multiplication between the specified instance by a scale vector. - /// - /// Left operand. - /// Right operand. - /// Result of multiplication. - public static Vector2d operator *(Vector2d vec, Vector2d scale) - { - vec.X *= scale.X; - vec.Y *= scale.Y; - return vec; - } - - /// - /// Divides an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the operation. - public static Vector2d operator /(Vector2d vec, double f) - { - double mult = 1.0 / f; - vec.X *= mult; - vec.Y *= mult; - return vec; - } - - /// - /// Compares two instances for equality. - /// - /// The left instance. - /// The right instance. - /// True, if both instances are equal; false otherwise. - public static bool operator ==(Vector2d left, Vector2d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for ienquality. - /// - /// The left instance. - /// The right instance. - /// True, if the instances are not equal; false otherwise. - public static bool operator !=(Vector2d left, Vector2d right) - { - return !left.Equals(right); - } - - /// Converts OpenTK.Vector2 to OpenTK.Vector2d. - /// The Vector2 to convert. - /// The resulting Vector2d. - public static explicit operator Vector2d(Vector2 v2) - { - return new Vector2d(v2.X, v2.Y); - } - - /// Converts OpenTK.Vector2d to OpenTK.Vector2. - /// The Vector2d to convert. - /// The resulting Vector2. - public static explicit operator Vector2(Vector2d v2d) - { - return new Vector2((float)v2d.X, (float)v2d.Y); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator; - /// - /// Returns a System.String that represents the current instance. - /// - /// - public override string ToString() - { - return String.Format("({0}{2} {1})", X, Y, listSeparator); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Vector2d)) - return false; - - return this.Equals((Vector2d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current vector is equal to another vector. - /// A vector to compare with this vector. - /// true if the current vector is equal to the vector parameter; otherwise, false. - public bool Equals(Vector2d other) - { - return - X == other.X && - Y == other.Y; - } - - #endregion - } -} \ No newline at end of file diff --git a/OpenTK/Math/Vector2h.cs b/OpenTK/Math/Vector2h.cs deleted file mode 100644 index 85ec2805..00000000 --- a/OpenTK/Math/Vector2h.cs +++ /dev/null @@ -1,370 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Xml.Serialization; - -namespace OpenTK -{ - - /// 2-component Vector of the Half type. Occupies 4 Byte total. - [Serializable, StructLayout(LayoutKind.Sequential)] - public struct Vector2h : ISerializable, IEquatable - { - #region Fields - - /// The X component of the Half2. - public Half X; - - /// The Y component of the Half2. - public Half Y; - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector2h(Half value) - { - X = value; - Y = value; - } - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector2h(Single value) - { - X = new Half(value); - Y = new Half(value); - } - - /// - /// The new Half2 instance will avoid conversion and copy directly from the Half parameters. - /// - /// An Half instance of a 16-bit half-precision floating-point number. - /// An Half instance of a 16-bit half-precision floating-point number. - public Vector2h(Half x, Half y) - { - X = x; - Y = y; - } - - /// - /// The new Half2 instance will convert the 2 parameters into 16-bit half-precision floating-point. - /// - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - public Vector2h(Single x, Single y) - { - X = new Half(x); - Y = new Half(y); - } - - /// - /// The new Half2 instance will convert the 2 parameters into 16-bit half-precision floating-point. - /// - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - /// Enable checks that will throw if the conversion result is not meaningful. - public Vector2h(Single x, Single y, bool throwOnError) - { - X = new Half(x, throwOnError); - Y = new Half(y, throwOnError); - } - - /// - /// The new Half2 instance will convert the Vector2 into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector2 - [CLSCompliant(false)] - public Vector2h(Vector2 v) - { - X = new Half(v.X); - Y = new Half(v.Y); - } - - /// - /// The new Half2 instance will convert the Vector2 into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector2 - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector2h(Vector2 v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - } - - /// - /// The new Half2 instance will convert the Vector2 into 16-bit half-precision floating-point. - /// This is the fastest constructor. - /// - /// OpenTK.Vector2 - public Vector2h(ref Vector2 v) - { - X = new Half(v.X); - Y = new Half(v.Y); - } - - /// - /// The new Half2 instance will convert the Vector2 into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector2 - /// Enable checks that will throw if the conversion result is not meaningful. - public Vector2h(ref Vector2 v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - } - - /// - /// The new Half2 instance will convert the Vector2d into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector2d - [CLSCompliant(false)] - public Vector2h(Vector2d v) - { - X = new Half(v.X); - Y = new Half(v.Y); - } - - /// - /// The new Half2 instance will convert the Vector2d into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector2d - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector2h(Vector2d v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - } - - /// - /// The new Half2 instance will convert the Vector2d into 16-bit half-precision floating-point. - /// This is the faster constructor. - /// - /// OpenTK.Vector2d - [CLSCompliant(false)] - public Vector2h(ref Vector2d v) - { - X = new Half(v.X); - Y = new Half(v.Y); - } - - /// - /// The new Half2 instance will convert the Vector2d into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector2d - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector2h(ref Vector2d v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - } - - #endregion Constructors - - #region Swizzle - - /// - /// Gets or sets an OpenTK.Vector2h with the Y and X components of this instance. - /// - [XmlIgnore] - public Vector2h Yx { get { return new Vector2h(Y, X); } set { Y = value.X; X = value.Y; } } - - #endregion - - #region Half -> Single - - /// - /// Returns this Half2 instance's contents as Vector2. - /// - /// OpenTK.Vector2 - public Vector2 ToVector2() - { - return new Vector2(X, Y); - } - - /// - /// Returns this Half2 instance's contents as Vector2d. - /// - public Vector2d ToVector2d() - { - return new Vector2d(X, Y); - } - - #endregion Half -> Single - - #region Conversions - - /// Converts OpenTK.Vector2 to OpenTK.Half2. - /// The Vector2 to convert. - /// The resulting Half vector. - public static explicit operator Vector2h(Vector2 v) - { - return new Vector2h(v); - } - - /// Converts OpenTK.Vector2d to OpenTK.Half2. - /// The Vector2d to convert. - /// The resulting Half vector. - public static explicit operator Vector2h(Vector2d v) - { - return new Vector2h(v); - } - - /// Converts OpenTK.Half2 to OpenTK.Vector2. - /// The Half2 to convert. - /// The resulting Vector2. - public static explicit operator Vector2(Vector2h h) - { - return new Vector2(h.X, h.Y); - } - - /// Converts OpenTK.Half2 to OpenTK.Vector2d. - /// The Half2 to convert. - /// The resulting Vector2d. - public static explicit operator Vector2d(Vector2h h) - { - return new Vector2d(h.X, h.Y); - } - - #endregion Conversions - - #region Constants - - /// The size in bytes for an instance of the Half2 struct is 4. - public static readonly int SizeInBytes = 4; - - #endregion Constants - - #region ISerializable - - /// Constructor used by ISerializable to deserialize the object. - /// - /// - public Vector2h(SerializationInfo info, StreamingContext context) - { - this.X = (Half)info.GetValue("X", typeof(Half)); - this.Y = (Half)info.GetValue("Y", typeof(Half)); - } - - /// Used by ISerialize to serialize the object. - /// - /// - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("X", this.X); - info.AddValue("Y", this.Y); - } - - #endregion ISerializable - - #region Binary dump - - /// Updates the X and Y components of this instance by reading from a Stream. - /// A BinaryReader instance associated with an open Stream. - public void FromBinaryStream(BinaryReader bin) - { - X.FromBinaryStream(bin); - Y.FromBinaryStream(bin); - } - - /// Writes the X and Y components of this instance into a Stream. - /// A BinaryWriter instance associated with an open Stream. - public void ToBinaryStream(BinaryWriter bin) - { - X.ToBinaryStream(bin); - Y.ToBinaryStream(bin); - } - - #endregion Binary dump - - #region IEquatable Members - - /// Returns a value indicating whether this instance is equal to a specified OpenTK.Half2 vector. - /// OpenTK.Half2 to compare to this instance.. - /// True, if other is equal to this instance; false otherwise. - public bool Equals(Vector2h other) - { - return (this.X.Equals(other.X) && this.Y.Equals(other.Y)); - } - - #endregion - - #region ToString() - - private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator; - /// Returns a string that contains this Half2's numbers in human-legible form. - public override string ToString() - { - return String.Format("({0}{2} {1})", X, Y, listSeparator); - } - - #endregion ToString() - - #region BitConverter - - /// Returns the Half2 as an array of bytes. - /// The Half2 to convert. - /// The input as byte array. - public static byte[] GetBytes(Vector2h h) - { - byte[] result = new byte[SizeInBytes]; - - byte[] temp = Half.GetBytes(h.X); - result[0] = temp[0]; - result[1] = temp[1]; - temp = Half.GetBytes(h.Y); - result[2] = temp[0]; - result[3] = temp[1]; - - return result; - } - - /// Converts an array of bytes into Half2. - /// A Half2 in it's byte[] representation. - /// The starting position within value. - /// A new Half2 instance. - public static Vector2h FromBytes(byte[] value, int startIndex) - { - Vector2h h2 = new Vector2h(); - h2.X = Half.FromBytes(value, startIndex); - h2.Y = Half.FromBytes(value, startIndex + 2); - return h2; - } - - #endregion BitConverter - } -} \ No newline at end of file diff --git a/OpenTK/Math/Vector3.cs b/OpenTK/Math/Vector3.cs deleted file mode 100644 index 8a096653..00000000 --- a/OpenTK/Math/Vector3.cs +++ /dev/null @@ -1,1494 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; -using System.Xml.Serialization; -namespace OpenTK -{ - /// - /// Represents a 3D vector using three single-precision floating-point numbers. - /// - /// - /// The Vector3 structure is suitable for interoperation with unmanaged code requiring three consecutive floats. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Vector3 : IEquatable - { - #region Fields - - /// - /// The X component of the Vector3. - /// - public float X; - - /// - /// The Y component of the Vector3. - /// - public float Y; - - /// - /// The Z component of the Vector3. - /// - public float Z; - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector3(float value) - { - X = value; - Y = value; - Z = value; - } - - /// - /// Constructs a new Vector3. - /// - /// The x component of the Vector3. - /// The y component of the Vector3. - /// The z component of the Vector3. - public Vector3(float x, float y, float z) - { - X = x; - Y = y; - Z = z; - } - - /// - /// Constructs a new Vector3 from the given Vector2. - /// - /// The Vector2 to copy components from. - public Vector3(Vector2 v) - { - X = v.X; - Y = v.Y; - Z = 0.0f; - } - - /// - /// Constructs a new Vector3 from the given Vector3. - /// - /// The Vector3 to copy components from. - public Vector3(Vector3 v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - } - - /// - /// Constructs a new Vector3 from the given Vector4. - /// - /// The Vector4 to copy components from. - public Vector3(Vector4 v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - } - - #endregion - - #region Public Members - - - /// - /// Gets or sets the value at the index of the Vector. - /// - public float this[int index] { - get{ - if(index == 0) return X; - else if(index == 1) return Y; - else if(index == 2) return Z; - throw new IndexOutOfRangeException("You tried to access this vector at index: " + index); - } set{ - if(index == 0) X = value; - else if(index == 1) Y = value; - else if(index == 2) Z = value; - else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index); - } - } - - #region Instance - - #region public void Add() - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(Vector3 right) - { - this.X += right.X; - this.Y += right.Y; - this.Z += right.Z; - } - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(ref Vector3 right) - { - this.X += right.X; - this.Y += right.Y; - this.Z += right.Z; - } - - #endregion public void Add() - - #region public void Sub() - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(Vector3 right) - { - this.X -= right.X; - this.Y -= right.Y; - this.Z -= right.Z; - } - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(ref Vector3 right) - { - this.X -= right.X; - this.Y -= right.Y; - this.Z -= right.Z; - } - - #endregion public void Sub() - - #region public void Mult() - - /// Multiply this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Multiply() method instead.")] - public void Mult(float f) - { - this.X *= f; - this.Y *= f; - this.Z *= f; - } - - #endregion public void Mult() - - #region public void Div() - - /// Divide this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Divide() method instead.")] - public void Div(float f) - { - float mult = 1.0f / f; - this.X *= mult; - this.Y *= mult; - this.Z *= mult; - } - - #endregion public void Div() - - #region public float Length - - /// - /// Gets the length (magnitude) of the vector. - /// - /// - /// - public float Length - { - get - { - return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z); - } - } - - #endregion - - #region public float LengthFast - - /// - /// Gets an approximation of the vector length (magnitude). - /// - /// - /// This property uses an approximation of the square root function to calculate vector magnitude, with - /// an upper error bound of 0.001. - /// - /// - /// - public float LengthFast - { - get - { - return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z); - } - } - - #endregion - - #region public float LengthSquared - - /// - /// Gets the square of the vector length (magnitude). - /// - /// - /// This property avoids the costly square root operation required by the Length property. This makes it more suitable - /// for comparisons. - /// - /// - /// - public float LengthSquared - { - get - { - return X * X + Y * Y + Z * Z; - } - } - - #endregion - - /// - /// Returns a copy of the Vector3 scaled to unit length. - /// - public Vector3 Normalized() - { - Vector3 v = this; - v.Normalize(); - return v; - } - - #region public void Normalize() - - /// - /// Scales the Vector3 to unit length. - /// - public void Normalize() - { - float scale = 1.0f / this.Length; - X *= scale; - Y *= scale; - Z *= scale; - } - - #endregion - - #region public void NormalizeFast() - - /// - /// Scales the Vector3 to approximately unit length. - /// - public void NormalizeFast() - { - float scale = MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z); - X *= scale; - Y *= scale; - Z *= scale; - } - - #endregion - - #region public void Scale() - - /// - /// Scales the current Vector3 by the given amounts. - /// - /// The scale of the X component. - /// The scale of the Y component. - /// The scale of the Z component. - [Obsolete("Use static Multiply() method instead.")] - public void Scale(float sx, float sy, float sz) - { - this.X = X * sx; - this.Y = Y * sy; - this.Z = Z * sz; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(Vector3 scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - this.Z *= scale.Z; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(ref Vector3 scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - this.Z *= scale.Z; - } - - #endregion public void Scale() - - #endregion - - #region Static - - #region Fields - - /// - /// Defines a unit-length Vector3 that points towards the X-axis. - /// - public static readonly Vector3 UnitX = new Vector3(1, 0, 0); - - /// - /// Defines a unit-length Vector3 that points towards the Y-axis. - /// - public static readonly Vector3 UnitY = new Vector3(0, 1, 0); - - /// - /// /// Defines a unit-length Vector3 that points towards the Z-axis. - /// - public static readonly Vector3 UnitZ = new Vector3(0, 0, 1); - - /// - /// Defines a zero-length Vector3. - /// - public static readonly Vector3 Zero = new Vector3(0, 0, 0); - - /// - /// Defines an instance with all components set to 1. - /// - public static readonly Vector3 One = new Vector3(1, 1, 1); - - /// - /// Defines the size of the Vector3 struct in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(new Vector3()); - - #endregion - - #region Obsolete - - #region Sub - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static Vector3 Sub(Vector3 a, Vector3 b) - { - a.X -= b.X; - a.Y -= b.Y; - a.Z -= b.Z; - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static void Sub(ref Vector3 a, ref Vector3 b, out Vector3 result) - { - result.X = a.X - b.X; - result.Y = a.Y - b.Y; - result.Z = a.Z - b.Z; - } - - #endregion - - #region Mult - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static Vector3 Mult(Vector3 a, float f) - { - a.X *= f; - a.Y *= f; - a.Z *= f; - return a; - } - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static void Mult(ref Vector3 a, float f, out Vector3 result) - { - result.X = a.X * f; - result.Y = a.Y * f; - result.Z = a.Z * f; - } - - #endregion - - #region Div - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static Vector3 Div(Vector3 a, float f) - { - float mult = 1.0f / f; - a.X *= mult; - a.Y *= mult; - a.Z *= mult; - return a; - } - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static void Div(ref Vector3 a, float f, out Vector3 result) - { - float mult = 1.0f / f; - result.X = a.X * mult; - result.Y = a.Y * mult; - result.Z = a.Z * mult; - } - - #endregion - - #endregion - - #region Add - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static Vector3 Add(Vector3 a, Vector3 b) - { - Add(ref a, ref b, out a); - return a; - } - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static void Add(ref Vector3 a, ref Vector3 b, out Vector3 result) - { - result = new Vector3(a.X + b.X, a.Y + b.Y, a.Z + b.Z); - } - - #endregion - - #region Subtract - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static Vector3 Subtract(Vector3 a, Vector3 b) - { - Subtract(ref a, ref b, out a); - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static void Subtract(ref Vector3 a, ref Vector3 b, out Vector3 result) - { - result = new Vector3(a.X - b.X, a.Y - b.Y, a.Z - b.Z); - } - - #endregion - - #region Multiply - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector3 Multiply(Vector3 vector, float scale) - { - Multiply(ref vector, scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector3 vector, float scale, out Vector3 result) - { - result = new Vector3(vector.X * scale, vector.Y * scale, vector.Z * scale); - } - - /// - /// Multiplies a vector by the components a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector3 Multiply(Vector3 vector, Vector3 scale) - { - Multiply(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector3 vector, ref Vector3 scale, out Vector3 result) - { - result = new Vector3(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z); - } - - #endregion - - #region Divide - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector3 Divide(Vector3 vector, float scale) - { - Divide(ref vector, scale, out vector); - return vector; - } - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector3 vector, float scale, out Vector3 result) - { - Multiply(ref vector, 1 / scale, out result); - } - - /// - /// Divides a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector3 Divide(Vector3 vector, Vector3 scale) - { - Divide(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Divide a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector3 vector, ref Vector3 scale, out Vector3 result) - { - result = new Vector3(vector.X / scale.X, vector.Y / scale.Y, vector.Z / scale.Z); - } - - #endregion - - #region ComponentMin - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static Vector3 ComponentMin(Vector3 a, Vector3 b) - { - a.X = a.X < b.X ? a.X : b.X; - a.Y = a.Y < b.Y ? a.Y : b.Y; - a.Z = a.Z < b.Z ? a.Z : b.Z; - return a; - } - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static void ComponentMin(ref Vector3 a, ref Vector3 b, out Vector3 result) - { - result.X = a.X < b.X ? a.X : b.X; - result.Y = a.Y < b.Y ? a.Y : b.Y; - result.Z = a.Z < b.Z ? a.Z : b.Z; - } - - #endregion - - #region ComponentMax - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static Vector3 ComponentMax(Vector3 a, Vector3 b) - { - a.X = a.X > b.X ? a.X : b.X; - a.Y = a.Y > b.Y ? a.Y : b.Y; - a.Z = a.Z > b.Z ? a.Z : b.Z; - return a; - } - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static void ComponentMax(ref Vector3 a, ref Vector3 b, out Vector3 result) - { - result.X = a.X > b.X ? a.X : b.X; - result.Y = a.Y > b.Y ? a.Y : b.Y; - result.Z = a.Z > b.Z ? a.Z : b.Z; - } - - #endregion - - #region Min - - /// - /// Returns the Vector3 with the minimum magnitude - /// - /// Left operand - /// Right operand - /// The minimum Vector3 - public static Vector3 Min(Vector3 left, Vector3 right) - { - return left.LengthSquared < right.LengthSquared ? left : right; - } - - #endregion - - #region Max - - /// - /// Returns the Vector3 with the minimum magnitude - /// - /// Left operand - /// Right operand - /// The minimum Vector3 - public static Vector3 Max(Vector3 left, Vector3 right) - { - return left.LengthSquared >= right.LengthSquared ? left : right; - } - - #endregion - - #region Clamp - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static Vector3 Clamp(Vector3 vec, Vector3 min, Vector3 max) - { - vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - vec.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z; - return vec; - } - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static void Clamp(ref Vector3 vec, ref Vector3 min, ref Vector3 max, out Vector3 result) - { - result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - result.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z; - } - - #endregion - - #region Normalize - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static Vector3 Normalize(Vector3 vec) - { - float scale = 1.0f / vec.Length; - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static void Normalize(ref Vector3 vec, out Vector3 result) - { - float scale = 1.0f / vec.Length; - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - } - - #endregion - - #region NormalizeFast - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static Vector3 NormalizeFast(Vector3 vec) - { - float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z); - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static void NormalizeFast(ref Vector3 vec, out Vector3 result) - { - float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z); - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - } - - #endregion - - #region Dot - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static float Dot(Vector3 left, Vector3 right) - { - return left.X * right.X + left.Y * right.Y + left.Z * right.Z; - } - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static void Dot(ref Vector3 left, ref Vector3 right, out float result) - { - result = left.X * right.X + left.Y * right.Y + left.Z * right.Z; - } - - #endregion - - #region Cross - - /// - /// Caclulate the cross (vector) product of two vectors - /// - /// First operand - /// Second operand - /// The cross product of the two inputs - public static Vector3 Cross(Vector3 left, Vector3 right) - { - Vector3 result; - Cross(ref left, ref right, out result); - return result; - } - - /// - /// Caclulate the cross (vector) product of two vectors - /// - /// First operand - /// Second operand - /// The cross product of the two inputs - /// The cross product of the two inputs - public static void Cross(ref Vector3 left, ref Vector3 right, out Vector3 result) - { - result = new Vector3(left.Y * right.Z - left.Z * right.Y, - left.Z * right.X - left.X * right.Z, - left.X * right.Y - left.Y * right.X); - } - - #endregion - - #region Lerp - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static Vector3 Lerp(Vector3 a, Vector3 b, float blend) - { - a.X = blend * (b.X - a.X) + a.X; - a.Y = blend * (b.Y - a.Y) + a.Y; - a.Z = blend * (b.Z - a.Z) + a.Z; - return a; - } - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static void Lerp(ref Vector3 a, ref Vector3 b, float blend, out Vector3 result) - { - result.X = blend * (b.X - a.X) + a.X; - result.Y = blend * (b.Y - a.Y) + a.Y; - result.Z = blend * (b.Z - a.Z) + a.Z; - } - - #endregion - - #region Barycentric - - /// - /// Interpolate 3 Vectors using Barycentric coordinates - /// - /// First input Vector - /// Second input Vector - /// Third input Vector - /// First Barycentric Coordinate - /// Second Barycentric Coordinate - /// a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static Vector3 BaryCentric(Vector3 a, Vector3 b, Vector3 c, float u, float v) - { - return a + u * (b - a) + v * (c - a); - } - - /// Interpolate 3 Vectors using Barycentric coordinates - /// First input Vector. - /// Second input Vector. - /// Third input Vector. - /// First Barycentric Coordinate. - /// Second Barycentric Coordinate. - /// Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static void BaryCentric(ref Vector3 a, ref Vector3 b, ref Vector3 c, float u, float v, out Vector3 result) - { - result = a; // copy - - Vector3 temp = b; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, u, out temp); - Add(ref result, ref temp, out result); - - temp = c; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, v, out temp); - Add(ref result, ref temp, out result); - } - - #endregion - - #region Transform - - /// Transform a direction vector by the given Matrix - /// Assumes the matrix has a bottom row of (0,0,0,1), that is the translation part is ignored. - /// - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static Vector3 TransformVector(Vector3 vec, Matrix4 mat) - { - Vector3 v; - v.X = Vector3.Dot(vec, new Vector3(mat.Column0)); - v.Y = Vector3.Dot(vec, new Vector3(mat.Column1)); - v.Z = Vector3.Dot(vec, new Vector3(mat.Column2)); - return v; - } - - /// Transform a direction vector by the given Matrix - /// Assumes the matrix has a bottom row of (0,0,0,1), that is the translation part is ignored. - /// - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static void TransformVector(ref Vector3 vec, ref Matrix4 mat, out Vector3 result) - { - result.X = vec.X * mat.Row0.X + - vec.Y * mat.Row1.X + - vec.Z * mat.Row2.X; - - result.Y = vec.X * mat.Row0.Y + - vec.Y * mat.Row1.Y + - vec.Z * mat.Row2.Y; - - result.Z = vec.X * mat.Row0.Z + - vec.Y * mat.Row1.Z + - vec.Z * mat.Row2.Z; - } - - /// Transform a Normal by the given Matrix - /// - /// This calculates the inverse of the given matrix, use TransformNormalInverse if you - /// already have the inverse to avoid this extra calculation - /// - /// The normal to transform - /// The desired transformation - /// The transformed normal - public static Vector3 TransformNormal(Vector3 norm, Matrix4 mat) - { - mat.Invert(); - return TransformNormalInverse(norm, mat); - } - - /// Transform a Normal by the given Matrix - /// - /// This calculates the inverse of the given matrix, use TransformNormalInverse if you - /// already have the inverse to avoid this extra calculation - /// - /// The normal to transform - /// The desired transformation - /// The transformed normal - public static void TransformNormal(ref Vector3 norm, ref Matrix4 mat, out Vector3 result) - { - Matrix4 Inverse = Matrix4.Invert(mat); - Vector3.TransformNormalInverse(ref norm, ref Inverse, out result); - } - - /// Transform a Normal by the (transpose of the) given Matrix - /// - /// This version doesn't calculate the inverse matrix. - /// Use this version if you already have the inverse of the desired transform to hand - /// - /// The normal to transform - /// The inverse of the desired transformation - /// The transformed normal - public static Vector3 TransformNormalInverse(Vector3 norm, Matrix4 invMat) - { - Vector3 n; - n.X = Vector3.Dot(norm, new Vector3(invMat.Row0)); - n.Y = Vector3.Dot(norm, new Vector3(invMat.Row1)); - n.Z = Vector3.Dot(norm, new Vector3(invMat.Row2)); - return n; - } - - /// Transform a Normal by the (transpose of the) given Matrix - /// - /// This version doesn't calculate the inverse matrix. - /// Use this version if you already have the inverse of the desired transform to hand - /// - /// The normal to transform - /// The inverse of the desired transformation - /// The transformed normal - public static void TransformNormalInverse(ref Vector3 norm, ref Matrix4 invMat, out Vector3 result) - { - result.X = norm.X * invMat.Row0.X + - norm.Y * invMat.Row0.Y + - norm.Z * invMat.Row0.Z; - - result.Y = norm.X * invMat.Row1.X + - norm.Y * invMat.Row1.Y + - norm.Z * invMat.Row1.Z; - - result.Z = norm.X * invMat.Row2.X + - norm.Y * invMat.Row2.Y + - norm.Z * invMat.Row2.Z; - } - - /// Transform a Position by the given Matrix - /// The position to transform - /// The desired transformation - /// The transformed position - public static Vector3 TransformPosition(Vector3 pos, Matrix4 mat) - { - Vector3 p; - p.X = Vector3.Dot(pos, new Vector3(mat.Column0)) + mat.Row3.X; - p.Y = Vector3.Dot(pos, new Vector3(mat.Column1)) + mat.Row3.Y; - p.Z = Vector3.Dot(pos, new Vector3(mat.Column2)) + mat.Row3.Z; - return p; - } - - /// Transform a Position by the given Matrix - /// The position to transform - /// The desired transformation - /// The transformed position - public static void TransformPosition(ref Vector3 pos, ref Matrix4 mat, out Vector3 result) - { - result.X = pos.X * mat.Row0.X + - pos.Y * mat.Row1.X + - pos.Z * mat.Row2.X + - mat.Row3.X; - - result.Y = pos.X * mat.Row0.Y + - pos.Y * mat.Row1.Y + - pos.Z * mat.Row2.Y + - mat.Row3.Y; - - result.Z = pos.X * mat.Row0.Z + - pos.Y * mat.Row1.Z + - pos.Z * mat.Row2.Z + - mat.Row3.Z; - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static Vector3 Transform(Vector3 vec, Matrix4 mat) - { - Vector3 result; - Transform(ref vec, ref mat, out result); - return result; - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static void Transform(ref Vector3 vec, ref Matrix4 mat, out Vector3 result) - { - Vector4 v4 = new Vector4(vec.X, vec.Y, vec.Z, 1.0f); - Vector4.Transform(ref v4, ref mat, out v4); - result = v4.Xyz; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static Vector3 Transform(Vector3 vec, Quaternion quat) - { - Vector3 result; - Transform(ref vec, ref quat, out result); - return result; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static void Transform(ref Vector3 vec, ref Quaternion quat, out Vector3 result) - { - // Since vec.W == 0, we can optimize quat * vec * quat^-1 as follows: - // vec + 2.0 * cross(quat.xyz, cross(quat.xyz, vec) + quat.w * vec) - Vector3 xyz = quat.Xyz, temp, temp2; - Vector3.Cross(ref xyz, ref vec, out temp); - Vector3.Multiply(ref vec, quat.W, out temp2); - Vector3.Add(ref temp, ref temp2, out temp); - Vector3.Cross(ref xyz, ref temp, out temp); - Vector3.Multiply(ref temp, 2, out temp); - Vector3.Add(ref vec, ref temp, out result); - } - - /// Transform a Vector3 by the given Matrix, and project the resulting Vector4 back to a Vector3 - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static Vector3 TransformPerspective(Vector3 vec, Matrix4 mat) - { - Vector3 result; - TransformPerspective(ref vec, ref mat, out result); - return result; - } - - /// Transform a Vector3 by the given Matrix, and project the resulting Vector4 back to a Vector3 - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static void TransformPerspective(ref Vector3 vec, ref Matrix4 mat, out Vector3 result) - { - Vector4 v = new Vector4(vec, 1); - Vector4.Transform(ref v, ref mat, out v); - result.X = v.X / v.W; - result.Y = v.Y / v.W; - result.Z = v.Z / v.W; - } - - #endregion - - #region CalculateAngle - - /// - /// Calculates the angle (in radians) between two vectors. - /// - /// The first vector. - /// The second vector. - /// Angle (in radians) between the vectors. - /// Note that the returned angle is never bigger than the constant Pi. - public static float CalculateAngle(Vector3 first, Vector3 second) - { - return (float)System.Math.Acos((Vector3.Dot(first, second)) / (first.Length * second.Length)); - } - - /// Calculates the angle (in radians) between two vectors. - /// The first vector. - /// The second vector. - /// Angle (in radians) between the vectors. - /// Note that the returned angle is never bigger than the constant Pi. - public static void CalculateAngle(ref Vector3 first, ref Vector3 second, out float result) - { - float temp; - Vector3.Dot(ref first, ref second, out temp); - result = (float)System.Math.Acos(temp / (first.Length * second.Length)); - } - - #endregion - - #endregion - - #region Swizzle - - #region 2-component - - /// - /// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance. - /// - [XmlIgnore] - public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the X and Z components of this instance. - /// - [XmlIgnore] - public Vector2 Xz { get { return new Vector2(X, Z); } set { X = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the Y and X components of this instance. - /// - [XmlIgnore] - public Vector2 Yx { get { return new Vector2(Y, X); } set { Y = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the Y and Z components of this instance. - /// - [XmlIgnore] - public Vector2 Yz { get { return new Vector2(Y, Z); } set { Y = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the Z and X components of this instance. - /// - [XmlIgnore] - public Vector2 Zx { get { return new Vector2(Z, X); } set { Z = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the Z and Y components of this instance. - /// - [XmlIgnore] - public Vector2 Zy { get { return new Vector2(Z, Y); } set { Z = value.X; Y = value.Y; } } - - #endregion - - #region 3-component - - /// - /// Gets or sets an OpenTK.Vector3 with the X, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector3 Xzy { get { return new Vector3(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Y, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector3 Yxz { get { return new Vector3(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Y, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector3 Yzx { get { return new Vector3(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Z, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector3 Zxy { get { return new Vector3(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Z, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector3 Zyx { get { return new Vector3(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } } - - #endregion - - #endregion - - #region Operators - - /// - /// Adds two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Vector3 operator +(Vector3 left, Vector3 right) - { - left.X += right.X; - left.Y += right.Y; - left.Z += right.Z; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Vector3 operator -(Vector3 left, Vector3 right) - { - left.X -= right.X; - left.Y -= right.Y; - left.Z -= right.Z; - return left; - } - - /// - /// Negates an instance. - /// - /// The instance. - /// The result of the calculation. - public static Vector3 operator -(Vector3 vec) - { - vec.X = -vec.X; - vec.Y = -vec.Y; - vec.Z = -vec.Z; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - public static Vector3 operator *(Vector3 vec, float scale) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The scalar. - /// The instance. - /// The result of the calculation. - public static Vector3 operator *(float scale, Vector3 vec) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Component-wise multiplication between the specified instance by a scale vector. - /// - /// Left operand. - /// Right operand. - /// Result of multiplication. - public static Vector3 operator *(Vector3 vec, Vector3 scale) - { - vec.X *= scale.X; - vec.Y *= scale.Y; - vec.Z *= scale.Z; - return vec; - } - - /// - /// Divides an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - public static Vector3 operator /(Vector3 vec, float scale) - { - float mult = 1.0f / scale; - vec.X *= mult; - vec.Y *= mult; - vec.Z *= mult; - return vec; - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Vector3 left, Vector3 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equa lright; false otherwise. - public static bool operator !=(Vector3 left, Vector3 right) - { - return !left.Equals(right); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator; - /// - /// Returns a System.String that represents the current Vector3. - /// - /// - public override string ToString() - { - return String.Format("({0}{3} {1}{3} {2})", X, Y, Z, listSeparator); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Vector3)) - return false; - - return this.Equals((Vector3)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current vector is equal to another vector. - /// A vector to compare with this vector. - /// true if the current vector is equal to the vector parameter; otherwise, false. - public bool Equals(Vector3 other) - { - return - X == other.X && - Y == other.Y && - Z == other.Z; - } - - #endregion - } -} diff --git a/OpenTK/Math/Vector3d.cs b/OpenTK/Math/Vector3d.cs deleted file mode 100644 index 0b281625..00000000 --- a/OpenTK/Math/Vector3d.cs +++ /dev/null @@ -1,1508 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -*/ -#endregion - -using System; -using System.Runtime.InteropServices; -using System.Xml.Serialization; - -namespace OpenTK -{ - /// - /// Represents a 3D vector using three double-precision floating-point numbers. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Vector3d : IEquatable - { - #region Fields - - /// - /// The X component of the Vector3. - /// - public double X; - - /// - /// The Y component of the Vector3. - /// - public double Y; - - /// - /// The Z component of the Vector3. - /// - public double Z; - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector3d(double value) - { - X = value; - Y = value; - Z = value; - } - - /// - /// Constructs a new Vector3. - /// - /// The x component of the Vector3. - /// The y component of the Vector3. - /// The z component of the Vector3. - public Vector3d(double x, double y, double z) - { - X = x; - Y = y; - Z = z; - } - - /// - /// Constructs a new instance from the given Vector2d. - /// - /// The Vector2d to copy components from. - public Vector3d(Vector2d v) - { - X = v.X; - Y = v.Y; - Z = 0.0f; - } - - /// - /// Constructs a new instance from the given Vector3d. - /// - /// The Vector3d to copy components from. - public Vector3d(Vector3d v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - } - - /// - /// Constructs a new instance from the given Vector4d. - /// - /// The Vector4d to copy components from. - public Vector3d(Vector4d v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - } - - - #endregion - - #region Public Members - - /// - /// Gets or sets the value at the index of the Vector. - /// - public double this[int index] { - get{ - if(index == 0) return X; - else if(index == 1) return Y; - else if(index == 2) return Z; - throw new IndexOutOfRangeException("You tried to access this vector at index: " + index); - } set{ - if(index == 0) X = value; - else if(index == 1) Y = value; - else if(index == 2) Z = value; - else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index); - } - } - - #region Instance - - #region public void Add() - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(Vector3d right) - { - this.X += right.X; - this.Y += right.Y; - this.Z += right.Z; - } - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(ref Vector3d right) - { - this.X += right.X; - this.Y += right.Y; - this.Z += right.Z; - } - - #endregion public void Add() - - #region public void Sub() - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(Vector3d right) - { - this.X -= right.X; - this.Y -= right.Y; - this.Z -= right.Z; - } - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(ref Vector3d right) - { - this.X -= right.X; - this.Y -= right.Y; - this.Z -= right.Z; - } - - #endregion public void Sub() - - #region public void Mult() - - /// Multiply this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Multiply() method instead.")] - public void Mult(double f) - { - this.X *= f; - this.Y *= f; - this.Z *= f; - } - - #endregion public void Mult() - - #region public void Div() - - /// Divide this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Divide() method instead.")] - public void Div(double f) - { - double mult = 1.0 / f; - this.X *= mult; - this.Y *= mult; - this.Z *= mult; - } - - #endregion public void Div() - - #region public double Length - - /// - /// Gets the length (magnitude) of the vector. - /// - /// - /// - public double Length - { - get - { - return System.Math.Sqrt(X * X + Y * Y + Z * Z); - } - } - - #endregion - - #region public double LengthFast - - /// - /// Gets an approximation of the vector length (magnitude). - /// - /// - /// This property uses an approximation of the square root function to calculate vector magnitude, with - /// an upper error bound of 0.001. - /// - /// - /// - public double LengthFast - { - get - { - return 1.0 / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z); - } - } - - #endregion - - #region public double LengthSquared - - /// - /// Gets the square of the vector length (magnitude). - /// - /// - /// This property avoids the costly square root operation required by the Length property. This makes it more suitable - /// for comparisons. - /// - /// - /// - public double LengthSquared - { - get - { - return X * X + Y * Y + Z * Z; - } - } - - #endregion - - /// - /// Returns a copy of the Vector3d scaled to unit length. - /// - /// - public Vector3d Normalized() - { - Vector3d v = this; - v.Normalize(); - return v; - } - - #region public void Normalize() - - /// - /// Scales the Vector3d to unit length. - /// - public void Normalize() - { - double scale = 1.0 / this.Length; - X *= scale; - Y *= scale; - Z *= scale; - } - - #endregion - - #region public void NormalizeFast() - - /// - /// Scales the Vector3d to approximately unit length. - /// - public void NormalizeFast() - { - double scale = MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z); - X *= scale; - Y *= scale; - Z *= scale; - } - - #endregion - - #region public void Scale() - - /// - /// Scales the current Vector3d by the given amounts. - /// - /// The scale of the X component. - /// The scale of the Y component. - /// The scale of the Z component. - [Obsolete("Use static Multiply() method instead.")] - public void Scale(double sx, double sy, double sz) - { - this.X = X * sx; - this.Y = Y * sy; - this.Z = Z * sz; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [Obsolete("Use static Multiply() method instead.")] - [CLSCompliant(false)] - public void Scale(Vector3d scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - this.Z *= scale.Z; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [Obsolete("Use static Multiply() method instead.")] - [CLSCompliant(false)] - public void Scale(ref Vector3d scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - this.Z *= scale.Z; - } - - #endregion public void Scale() - - #endregion - - #region Static - - #region Fields - - /// - /// Defines a unit-length Vector3d that points towards the X-axis. - /// - public static readonly Vector3d UnitX = new Vector3d(1, 0, 0); - - /// - /// Defines a unit-length Vector3d that points towards the Y-axis. - /// - public static readonly Vector3d UnitY = new Vector3d(0, 1, 0); - - /// - /// /// Defines a unit-length Vector3d that points towards the Z-axis. - /// - public static readonly Vector3d UnitZ = new Vector3d(0, 0, 1); - - /// - /// Defines a zero-length Vector3. - /// - public static readonly Vector3d Zero = new Vector3d(0, 0, 0); - - /// - /// Defines an instance with all components set to 1. - /// - public static readonly Vector3d One = new Vector3d(1, 1, 1); - - /// - /// Defines the size of the Vector3d struct in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(new Vector3d()); - - #endregion - - #region Obsolete - - #region Sub - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static Vector3d Sub(Vector3d a, Vector3d b) - { - a.X -= b.X; - a.Y -= b.Y; - a.Z -= b.Z; - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static void Sub(ref Vector3d a, ref Vector3d b, out Vector3d result) - { - result.X = a.X - b.X; - result.Y = a.Y - b.Y; - result.Z = a.Z - b.Z; - } - - #endregion - - #region Mult - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static Vector3d Mult(Vector3d a, double f) - { - a.X *= f; - a.Y *= f; - a.Z *= f; - return a; - } - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static void Mult(ref Vector3d a, double f, out Vector3d result) - { - result.X = a.X * f; - result.Y = a.Y * f; - result.Z = a.Z * f; - } - - #endregion - - #region Div - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static Vector3d Div(Vector3d a, double f) - { - double mult = 1.0 / f; - a.X *= mult; - a.Y *= mult; - a.Z *= mult; - return a; - } - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static void Div(ref Vector3d a, double f, out Vector3d result) - { - double mult = 1.0 / f; - result.X = a.X * mult; - result.Y = a.Y * mult; - result.Z = a.Z * mult; - } - - #endregion - - #endregion - - #region Add - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static Vector3d Add(Vector3d a, Vector3d b) - { - Add(ref a, ref b, out a); - return a; - } - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static void Add(ref Vector3d a, ref Vector3d b, out Vector3d result) - { - result = new Vector3d(a.X + b.X, a.Y + b.Y, a.Z + b.Z); - } - - #endregion - - #region Subtract - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static Vector3d Subtract(Vector3d a, Vector3d b) - { - Subtract(ref a, ref b, out a); - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static void Subtract(ref Vector3d a, ref Vector3d b, out Vector3d result) - { - result = new Vector3d(a.X - b.X, a.Y - b.Y, a.Z - b.Z); - } - - #endregion - - #region Multiply - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector3d Multiply(Vector3d vector, double scale) - { - Multiply(ref vector, scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector3d vector, double scale, out Vector3d result) - { - result = new Vector3d(vector.X * scale, vector.Y * scale, vector.Z * scale); - } - - /// - /// Multiplies a vector by the components a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector3d Multiply(Vector3d vector, Vector3d scale) - { - Multiply(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector3d vector, ref Vector3d scale, out Vector3d result) - { - result = new Vector3d(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z); - } - - #endregion - - #region Divide - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector3d Divide(Vector3d vector, double scale) - { - Divide(ref vector, scale, out vector); - return vector; - } - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector3d vector, double scale, out Vector3d result) - { - Multiply(ref vector, 1 / scale, out result); - } - - /// - /// Divides a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector3d Divide(Vector3d vector, Vector3d scale) - { - Divide(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Divide a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector3d vector, ref Vector3d scale, out Vector3d result) - { - result = new Vector3d(vector.X / scale.X, vector.Y / scale.Y, vector.Z / scale.Z); - } - - #endregion - - #region ComponentMin - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static Vector3d ComponentMin(Vector3d a, Vector3d b) - { - a.X = a.X < b.X ? a.X : b.X; - a.Y = a.Y < b.Y ? a.Y : b.Y; - a.Z = a.Z < b.Z ? a.Z : b.Z; - return a; - } - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static void ComponentMin(ref Vector3d a, ref Vector3d b, out Vector3d result) - { - result.X = a.X < b.X ? a.X : b.X; - result.Y = a.Y < b.Y ? a.Y : b.Y; - result.Z = a.Z < b.Z ? a.Z : b.Z; - } - - #endregion - - #region ComponentMax - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static Vector3d ComponentMax(Vector3d a, Vector3d b) - { - a.X = a.X > b.X ? a.X : b.X; - a.Y = a.Y > b.Y ? a.Y : b.Y; - a.Z = a.Z > b.Z ? a.Z : b.Z; - return a; - } - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static void ComponentMax(ref Vector3d a, ref Vector3d b, out Vector3d result) - { - result.X = a.X > b.X ? a.X : b.X; - result.Y = a.Y > b.Y ? a.Y : b.Y; - result.Z = a.Z > b.Z ? a.Z : b.Z; - } - - #endregion - - #region Min - - /// - /// Returns the Vector3d with the minimum magnitude - /// - /// Left operand - /// Right operand - /// The minimum Vector3 - public static Vector3d Min(Vector3d left, Vector3d right) - { - return left.LengthSquared < right.LengthSquared ? left : right; - } - - #endregion - - #region Max - - /// - /// Returns the Vector3d with the minimum magnitude - /// - /// Left operand - /// Right operand - /// The minimum Vector3 - public static Vector3d Max(Vector3d left, Vector3d right) - { - return left.LengthSquared >= right.LengthSquared ? left : right; - } - - #endregion - - #region Clamp - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static Vector3d Clamp(Vector3d vec, Vector3d min, Vector3d max) - { - vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - vec.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z; - return vec; - } - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static void Clamp(ref Vector3d vec, ref Vector3d min, ref Vector3d max, out Vector3d result) - { - result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - result.Z = vec.Z < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z; - } - - #endregion - - #region Normalize - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static Vector3d Normalize(Vector3d vec) - { - double scale = 1.0 / vec.Length; - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static void Normalize(ref Vector3d vec, out Vector3d result) - { - double scale = 1.0 / vec.Length; - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - } - - #endregion - - #region NormalizeFast - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static Vector3d NormalizeFast(Vector3d vec) - { - double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z); - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static void NormalizeFast(ref Vector3d vec, out Vector3d result) - { - double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z); - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - } - - #endregion - - #region Dot - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static double Dot(Vector3d left, Vector3d right) - { - return left.X * right.X + left.Y * right.Y + left.Z * right.Z; - } - - /// - /// Calculate the dot (scalar) product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static void Dot(ref Vector3d left, ref Vector3d right, out double result) - { - result = left.X * right.X + left.Y * right.Y + left.Z * right.Z; - } - - #endregion - - #region Cross - - /// - /// Caclulate the cross (vector) product of two vectors - /// - /// First operand - /// Second operand - /// The cross product of the two inputs - public static Vector3d Cross(Vector3d left, Vector3d right) - { - Vector3d result; - Cross(ref left, ref right, out result); - return result; - } - - /// - /// Caclulate the cross (vector) product of two vectors - /// - /// First operand - /// Second operand - /// The cross product of the two inputs - /// The cross product of the two inputs - public static void Cross(ref Vector3d left, ref Vector3d right, out Vector3d result) - { - result = new Vector3d(left.Y * right.Z - left.Z * right.Y, - left.Z * right.X - left.X * right.Z, - left.X * right.Y - left.Y * right.X); - } - - #endregion - - #region Lerp - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static Vector3d Lerp(Vector3d a, Vector3d b, double blend) - { - a.X = blend * (b.X - a.X) + a.X; - a.Y = blend * (b.Y - a.Y) + a.Y; - a.Z = blend * (b.Z - a.Z) + a.Z; - return a; - } - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static void Lerp(ref Vector3d a, ref Vector3d b, double blend, out Vector3d result) - { - result.X = blend * (b.X - a.X) + a.X; - result.Y = blend * (b.Y - a.Y) + a.Y; - result.Z = blend * (b.Z - a.Z) + a.Z; - } - - #endregion - - #region Barycentric - - /// - /// Interpolate 3 Vectors using Barycentric coordinates - /// - /// First input Vector - /// Second input Vector - /// Third input Vector - /// First Barycentric Coordinate - /// Second Barycentric Coordinate - /// a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static Vector3d BaryCentric(Vector3d a, Vector3d b, Vector3d c, double u, double v) - { - return a + u * (b - a) + v * (c - a); - } - - /// Interpolate 3 Vectors using Barycentric coordinates - /// First input Vector. - /// Second input Vector. - /// Third input Vector. - /// First Barycentric Coordinate. - /// Second Barycentric Coordinate. - /// Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static void BaryCentric(ref Vector3d a, ref Vector3d b, ref Vector3d c, double u, double v, out Vector3d result) - { - result = a; // copy - - Vector3d temp = b; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, u, out temp); - Add(ref result, ref temp, out result); - - temp = c; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, v, out temp); - Add(ref result, ref temp, out result); - } - - #endregion - - #region Transform - - /// Transform a direction vector by the given Matrix - /// Assumes the matrix has a bottom row of (0,0,0,1), that is the translation part is ignored. - /// - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static Vector3d TransformVector(Vector3d vec, Matrix4d mat) - { - return new Vector3d( - Vector3d.Dot(vec, new Vector3d(mat.Column0)), - Vector3d.Dot(vec, new Vector3d(mat.Column1)), - Vector3d.Dot(vec, new Vector3d(mat.Column2))); - } - - /// Transform a direction vector by the given Matrix - /// Assumes the matrix has a bottom row of (0,0,0,1), that is the translation part is ignored. - /// - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static void TransformVector(ref Vector3d vec, ref Matrix4d mat, out Vector3d result) - { - result.X = vec.X * mat.Row0.X + - vec.Y * mat.Row1.X + - vec.Z * mat.Row2.X; - - result.Y = vec.X * mat.Row0.Y + - vec.Y * mat.Row1.Y + - vec.Z * mat.Row2.Y; - - result.Z = vec.X * mat.Row0.Z + - vec.Y * mat.Row1.Z + - vec.Z * mat.Row2.Z; - } - - /// Transform a Normal by the given Matrix - /// - /// This calculates the inverse of the given matrix, use TransformNormalInverse if you - /// already have the inverse to avoid this extra calculation - /// - /// The normal to transform - /// The desired transformation - /// The transformed normal - public static Vector3d TransformNormal(Vector3d norm, Matrix4d mat) - { - mat.Invert(); - return TransformNormalInverse(norm, mat); - } - - /// Transform a Normal by the given Matrix - /// - /// This calculates the inverse of the given matrix, use TransformNormalInverse if you - /// already have the inverse to avoid this extra calculation - /// - /// The normal to transform - /// The desired transformation - /// The transformed normal - public static void TransformNormal(ref Vector3d norm, ref Matrix4d mat, out Vector3d result) - { - Matrix4d Inverse = Matrix4d.Invert(mat); - Vector3d.TransformNormalInverse(ref norm, ref Inverse, out result); - } - - /// Transform a Normal by the (transpose of the) given Matrix - /// - /// This version doesn't calculate the inverse matrix. - /// Use this version if you already have the inverse of the desired transform to hand - /// - /// The normal to transform - /// The inverse of the desired transformation - /// The transformed normal - public static Vector3d TransformNormalInverse(Vector3d norm, Matrix4d invMat) - { - return new Vector3d( - Vector3d.Dot(norm, new Vector3d(invMat.Row0)), - Vector3d.Dot(norm, new Vector3d(invMat.Row1)), - Vector3d.Dot(norm, new Vector3d(invMat.Row2))); - } - - /// Transform a Normal by the (transpose of the) given Matrix - /// - /// This version doesn't calculate the inverse matrix. - /// Use this version if you already have the inverse of the desired transform to hand - /// - /// The normal to transform - /// The inverse of the desired transformation - /// The transformed normal - public static void TransformNormalInverse(ref Vector3d norm, ref Matrix4d invMat, out Vector3d result) - { - result.X = norm.X * invMat.Row0.X + - norm.Y * invMat.Row0.Y + - norm.Z * invMat.Row0.Z; - - result.Y = norm.X * invMat.Row1.X + - norm.Y * invMat.Row1.Y + - norm.Z * invMat.Row1.Z; - - result.Z = norm.X * invMat.Row2.X + - norm.Y * invMat.Row2.Y + - norm.Z * invMat.Row2.Z; - } - - /// Transform a Position by the given Matrix - /// The position to transform - /// The desired transformation - /// The transformed position - public static Vector3d TransformPosition(Vector3d pos, Matrix4d mat) - { - return new Vector3d( - Vector3d.Dot(pos, new Vector3d(mat.Column0)) + mat.Row3.X, - Vector3d.Dot(pos, new Vector3d(mat.Column1)) + mat.Row3.Y, - Vector3d.Dot(pos, new Vector3d(mat.Column2)) + mat.Row3.Z); - } - - /// Transform a Position by the given Matrix - /// The position to transform - /// The desired transformation - /// The transformed position - public static void TransformPosition(ref Vector3d pos, ref Matrix4d mat, out Vector3d result) - { - result.X = pos.X * mat.Row0.X + - pos.Y * mat.Row1.X + - pos.Z * mat.Row2.X + - mat.Row3.X; - - result.Y = pos.X * mat.Row0.Y + - pos.Y * mat.Row1.Y + - pos.Z * mat.Row2.Y + - mat.Row3.Y; - - result.Z = pos.X * mat.Row0.Z + - pos.Y * mat.Row1.Z + - pos.Z * mat.Row2.Z + - mat.Row3.Z; - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static Vector3d Transform(Vector3d vec, Matrix4d mat) - { - Vector3d result; - Transform(ref vec, ref mat, out result); - return result; - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static void Transform(ref Vector3d vec, ref Matrix4d mat, out Vector3d result) - { - Vector4d v4 = new Vector4d(vec.X, vec.Y, vec.Z, 1.0); - Vector4d.Transform(ref v4, ref mat, out v4); - result = v4.Xyz; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static Vector3d Transform(Vector3d vec, Quaterniond quat) - { - Vector3d result; - Transform(ref vec, ref quat, out result); - return result; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static void Transform(ref Vector3d vec, ref Quaterniond quat, out Vector3d result) - { - // Since vec.W == 0, we can optimize quat * vec * quat^-1 as follows: - // vec + 2.0 * cross(quat.xyz, cross(quat.xyz, vec) + quat.w * vec) - Vector3d xyz = quat.Xyz, temp, temp2; - Vector3d.Cross(ref xyz, ref vec, out temp); - Vector3d.Multiply(ref vec, quat.W, out temp2); - Vector3d.Add(ref temp, ref temp2, out temp); - Vector3d.Cross(ref xyz, ref temp, out temp); - Vector3d.Multiply(ref temp, 2, out temp); - Vector3d.Add(ref vec, ref temp, out result); - } - - /// - /// Transform a Vector3d by the given Matrix, and project the resulting Vector4 back to a Vector3 - /// - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static Vector3d TransformPerspective(Vector3d vec, Matrix4d mat) - { - Vector3d result; - TransformPerspective(ref vec, ref mat, out result); - return result; - } - - /// Transform a Vector3d by the given Matrix, and project the resulting Vector4d back to a Vector3d - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static void TransformPerspective(ref Vector3d vec, ref Matrix4d mat, out Vector3d result) - { - Vector4d v = new Vector4d(vec, 1); - Vector4d.Transform(ref v, ref mat, out v); - result.X = v.X / v.W; - result.Y = v.Y / v.W; - result.Z = v.Z / v.W; - } - - #endregion - - #region CalculateAngle - - /// - /// Calculates the angle (in radians) between two vectors. - /// - /// The first vector. - /// The second vector. - /// Angle (in radians) between the vectors. - /// Note that the returned angle is never bigger than the constant Pi. - public static double CalculateAngle(Vector3d first, Vector3d second) - { - return System.Math.Acos((Vector3d.Dot(first, second)) / (first.Length * second.Length)); - } - - /// Calculates the angle (in radians) between two vectors. - /// The first vector. - /// The second vector. - /// Angle (in radians) between the vectors. - /// Note that the returned angle is never bigger than the constant Pi. - public static void CalculateAngle(ref Vector3d first, ref Vector3d second, out double result) - { - double temp; - Vector3d.Dot(ref first, ref second, out temp); - result = System.Math.Acos(temp / (first.Length * second.Length)); - } - - #endregion - - #endregion - - #region Swizzle - - #region 2-component - - /// - /// Gets or sets an OpenTK.Vector2d with the X and Y components of this instance. - /// - [XmlIgnore] - public Vector2d Xy { get { return new Vector2d(X, Y); } set { X = value.X; Y = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the X and Z components of this instance. - /// - [XmlIgnore] - public Vector2d Xz { get { return new Vector2d(X, Z); } set { X = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the Y and X components of this instance. - /// - [XmlIgnore] - public Vector2d Yx { get { return new Vector2d(Y, X); } set { Y = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the Y and Z components of this instance. - /// - [XmlIgnore] - public Vector2d Yz { get { return new Vector2d(Y, Z); } set { Y = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the Z and X components of this instance. - /// - [XmlIgnore] - public Vector2d Zx { get { return new Vector2d(Z, X); } set { Z = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the Z and Y components of this instance. - /// - [XmlIgnore] - public Vector2d Zy { get { return new Vector2d(Z, Y); } set { Z = value.X; Y = value.Y; } } - - #endregion - - #region 3-component - - /// - /// Gets or sets an OpenTK.Vector3d with the X, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector3d Xzy { get { return new Vector3d(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Y, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector3d Yxz { get { return new Vector3d(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Y, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector3d Yzx { get { return new Vector3d(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Z, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector3d Zxy { get { return new Vector3d(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Z, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector3d Zyx { get { return new Vector3d(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } } - - #endregion - - #endregion - - #region Operators - - /// - /// Adds two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Vector3d operator +(Vector3d left, Vector3d right) - { - left.X += right.X; - left.Y += right.Y; - left.Z += right.Z; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Vector3d operator -(Vector3d left, Vector3d right) - { - left.X -= right.X; - left.Y -= right.Y; - left.Z -= right.Z; - return left; - } - - /// - /// Negates an instance. - /// - /// The instance. - /// The result of the calculation. - public static Vector3d operator -(Vector3d vec) - { - vec.X = -vec.X; - vec.Y = -vec.Y; - vec.Z = -vec.Z; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - public static Vector3d operator *(Vector3d vec, double scale) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The scalar. - /// The instance. - /// The result of the calculation. - public static Vector3d operator *(double scale, Vector3d vec) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - return vec; - } - - /// - /// Component-wise multiplication between the specified instance by a scale vector. - /// - /// Left operand. - /// Right operand. - /// Result of multiplication. - public static Vector3d operator *(Vector3d vec, Vector3d scale) - { - vec.X *= scale.X; - vec.Y *= scale.Y; - vec.Z *= scale.Z; - return vec; - } - - /// - /// Divides an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - public static Vector3d operator /(Vector3d vec, double scale) - { - double mult = 1 / scale; - vec.X *= mult; - vec.Y *= mult; - vec.Z *= mult; - return vec; - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Vector3d left, Vector3d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equa lright; false otherwise. - public static bool operator !=(Vector3d left, Vector3d right) - { - return !left.Equals(right); - } - - /// Converts OpenTK.Vector3 to OpenTK.Vector3d. - /// The Vector3 to convert. - /// The resulting Vector3d. - public static explicit operator Vector3d(Vector3 v3) - { - return new Vector3d(v3.X, v3.Y, v3.Z); - } - - /// Converts OpenTK.Vector3d to OpenTK.Vector3. - /// The Vector3d to convert. - /// The resulting Vector3. - public static explicit operator Vector3(Vector3d v3d) - { - return new Vector3((float)v3d.X, (float)v3d.Y, (float)v3d.Z); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator; - /// - /// Returns a System.String that represents the current Vector3. - /// - /// - public override string ToString() - { - return String.Format("({0}{3} {1}{3} {2})", X, Y, Z, listSeparator); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Vector3d)) - return false; - - return this.Equals((Vector3d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current vector is equal to another vector. - /// A vector to compare with this vector. - /// true if the current vector is equal to the vector parameter; otherwise, false. - public bool Equals(Vector3d other) - { - return - X == other.X && - Y == other.Y && - Z == other.Z; - } - - #endregion - } -} \ No newline at end of file diff --git a/OpenTK/Math/Vector3h.cs b/OpenTK/Math/Vector3h.cs deleted file mode 100644 index 52945c6d..00000000 --- a/OpenTK/Math/Vector3h.cs +++ /dev/null @@ -1,475 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Xml.Serialization; - -namespace OpenTK -{ - /// - /// 3-component Vector of the Half type. Occupies 6 Byte total. - /// - [Serializable, StructLayout(LayoutKind.Sequential)] - public struct Vector3h : ISerializable, IEquatable - { - #region Public Fields - - /// The X component of the Half3. - public Half X; - - /// The Y component of the Half3. - public Half Y; - - /// The Z component of the Half3. - public Half Z; - - #endregion Public Fields - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector3h(Half value) - { - X = value; - Y = value; - Z = value; - } - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector3h(Single value) - { - X = new Half(value); - Y = new Half(value); - Z = new Half(value); - } - - /// - /// The new Half3 instance will avoid conversion and copy directly from the Half parameters. - /// - /// An Half instance of a 16-bit half-precision floating-point number. - /// An Half instance of a 16-bit half-precision floating-point number. - /// An Half instance of a 16-bit half-precision floating-point number. - public Vector3h(Half x, Half y, Half z) - { - this.X = x; - this.Y = y; - this.Z = z; - } - - /// - /// The new Half3 instance will convert the 3 parameters into 16-bit half-precision floating-point. - /// - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - public Vector3h(Single x, Single y, Single z) - { - X = new Half(x); - Y = new Half(y); - Z = new Half(z); - } - - /// - /// The new Half3 instance will convert the 3 parameters into 16-bit half-precision floating-point. - /// - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - /// Enable checks that will throw if the conversion result is not meaningful. - public Vector3h(Single x, Single y, Single z, bool throwOnError) - { - X = new Half(x, throwOnError); - Y = new Half(y, throwOnError); - Z = new Half(z, throwOnError); - } - - /// - /// The new Half3 instance will convert the Vector3 into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector3 - [CLSCompliant(false)] - public Vector3h(Vector3 v) - { - X = new Half(v.X); - Y = new Half(v.Y); - Z = new Half(v.Z); - } - - /// - /// The new Half3 instance will convert the Vector3 into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector3 - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector3h(Vector3 v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - Z = new Half(v.Z, throwOnError); - } - - /// - /// The new Half3 instance will convert the Vector3 into 16-bit half-precision floating-point. - /// This is the fastest constructor. - /// - /// OpenTK.Vector3 - public Vector3h(ref Vector3 v) - { - X = new Half(v.X); - Y = new Half(v.Y); - Z = new Half(v.Z); - } - - /// - /// The new Half3 instance will convert the Vector3 into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector3 - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector3h(ref Vector3 v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - Z = new Half(v.Z, throwOnError); - } - - /// - /// The new Half3 instance will convert the Vector3d into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector3d - [CLSCompliant(false)] - public Vector3h(Vector3d v) - { - X = new Half(v.X); - Y = new Half(v.Y); - Z = new Half(v.Z); - } - - /// - /// The new Half3 instance will convert the Vector3d into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector3d - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector3h(Vector3d v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - Z = new Half(v.Z, throwOnError); - } - - /// - /// The new Half3 instance will convert the Vector3d into 16-bit half-precision floating-point. - /// This is the faster constructor. - /// - /// OpenTK.Vector3d - [CLSCompliant(false)] - public Vector3h(ref Vector3d v) - { - X = new Half(v.X); - Y = new Half(v.Y); - Z = new Half(v.Z); - } - - /// - /// The new Half3 instance will convert the Vector3d into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector3d - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector3h(ref Vector3d v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - Z = new Half(v.Z, throwOnError); - } - - #endregion Constructors - - #region Swizzle - - #region 2-component - - /// - /// Gets or sets an OpenTK.Vector2h with the X and Y components of this instance. - /// - [XmlIgnore] - public Vector2h Xy { get { return new Vector2h(X, Y); } set { X = value.X; Y = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the X and Z components of this instance. - /// - [XmlIgnore] - public Vector2h Xz { get { return new Vector2h(X, Z); } set { X = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the Y and X components of this instance. - /// - [XmlIgnore] - public Vector2h Yx { get { return new Vector2h(Y, X); } set { Y = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the Y and Z components of this instance. - /// - [XmlIgnore] - public Vector2h Yz { get { return new Vector2h(Y, Z); } set { Y = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the Z and X components of this instance. - /// - [XmlIgnore] - public Vector2h Zx { get { return new Vector2h(Z, X); } set { Z = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the Z and Y components of this instance. - /// - [XmlIgnore] - public Vector2h Zy { get { return new Vector2h(Z, Y); } set { Z = value.X; Y = value.Y; } } - - #endregion - - #region 3-component - - /// - /// Gets or sets an OpenTK.Vector3h with the X, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector3h Xzy { get { return new Vector3h(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Y, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector3h Yxz { get { return new Vector3h(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Y, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector3h Yzx { get { return new Vector3h(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Z, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector3h Zxy { get { return new Vector3h(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Z, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector3h Zyx { get { return new Vector3h(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } } - - #endregion - - #endregion - - #region Half -> Single - - /// - /// Returns this Half3 instance's contents as Vector3. - /// - /// OpenTK.Vector3 - public Vector3 ToVector3() - { - return new Vector3(X, Y, Z); - } - - /// - /// Returns this Half3 instance's contents as Vector3d. - /// - public Vector3d ToVector3d() - { - return new Vector3d(X, Y, Z); - } - - #endregion Half -> Single - - #region Conversions - - /// Converts OpenTK.Vector3 to OpenTK.Half3. - /// The Vector3 to convert. - /// The resulting Half vector. - public static explicit operator Vector3h(Vector3 v3f) - { - return new Vector3h(v3f); - } - - /// Converts OpenTK.Vector3d to OpenTK.Half3. - /// The Vector3d to convert. - /// The resulting Half vector. - public static explicit operator Vector3h(Vector3d v3d) - { - return new Vector3h(v3d); - } - - /// Converts OpenTK.Half3 to OpenTK.Vector3. - /// The Half3 to convert. - /// The resulting Vector3. - public static explicit operator Vector3(Vector3h h3) - { - Vector3 result = new Vector3(); - result.X = h3.X.ToSingle(); - result.Y = h3.Y.ToSingle(); - result.Z = h3.Z.ToSingle(); - return result; - } - - /// Converts OpenTK.Half3 to OpenTK.Vector3d. - /// The Half3 to convert. - /// The resulting Vector3d. - public static explicit operator Vector3d(Vector3h h3) - { - Vector3d result = new Vector3d(); - result.X = h3.X.ToSingle(); - result.Y = h3.Y.ToSingle(); - result.Z = h3.Z.ToSingle(); - return result; - } - - #endregion Conversions - - #region Constants - - /// The size in bytes for an instance of the Half3 struct is 6. - public static readonly int SizeInBytes = 6; - - #endregion Constants - - #region ISerializable - - /// Constructor used by ISerializable to deserialize the object. - /// - /// - public Vector3h(SerializationInfo info, StreamingContext context) - { - this.X = (Half)info.GetValue("X", typeof(Half)); - this.Y = (Half)info.GetValue("Y", typeof(Half)); - this.Z = (Half)info.GetValue("Z", typeof(Half)); - } - - /// Used by ISerialize to serialize the object. - /// - /// - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("X", this.X); - info.AddValue("Y", this.Y); - info.AddValue("Z", this.Z); - } - - #endregion ISerializable - - #region Binary dump - - /// Updates the X,Y and Z components of this instance by reading from a Stream. - /// A BinaryReader instance associated with an open Stream. - public void FromBinaryStream(BinaryReader bin) - { - X.FromBinaryStream(bin); - Y.FromBinaryStream(bin); - Z.FromBinaryStream(bin); - } - - /// Writes the X,Y and Z components of this instance into a Stream. - /// A BinaryWriter instance associated with an open Stream. - public void ToBinaryStream(BinaryWriter bin) - { - X.ToBinaryStream(bin); - Y.ToBinaryStream(bin); - Z.ToBinaryStream(bin); - } - - #endregion Binary dump - - #region IEquatable Members - - /// Returns a value indicating whether this instance is equal to a specified OpenTK.Half3 vector. - /// OpenTK.Half3 to compare to this instance.. - /// True, if other is equal to this instance; false otherwise. - public bool Equals(Vector3h other) - { - return (this.X.Equals(other.X) && this.Y.Equals(other.Y) && this.Z.Equals(other.Z)); - } - - #endregion - - #region ToString() - - private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator; - /// Returns a string that contains this Half3's numbers in human-legible form. - public override string ToString() - { - return String.Format("({0}{3} {1}{3} {2})", X.ToString(), Y.ToString(), Z.ToString(), listSeparator); - } - - #endregion ToString() - - #region BitConverter - - /// Returns the Half3 as an array of bytes. - /// The Half3 to convert. - /// The input as byte array. - public static byte[] GetBytes(Vector3h h) - { - byte[] result = new byte[SizeInBytes]; - - byte[] temp = Half.GetBytes(h.X); - result[0] = temp[0]; - result[1] = temp[1]; - temp = Half.GetBytes(h.Y); - result[2] = temp[0]; - result[3] = temp[1]; - temp = Half.GetBytes(h.Z); - result[4] = temp[0]; - result[5] = temp[1]; - - return result; - } - - /// Converts an array of bytes into Half3. - /// A Half3 in it's byte[] representation. - /// The starting position within value. - /// A new Half3 instance. - public static Vector3h FromBytes(byte[] value, int startIndex) - { - Vector3h h3 = new Vector3h(); - h3.X = Half.FromBytes(value, startIndex); - h3.Y = Half.FromBytes(value, startIndex + 2); - h3.Z = Half.FromBytes(value, startIndex + 4); - return h3; - } - - #endregion BitConverter - } -} diff --git a/OpenTK/Math/Vector4.cs b/OpenTK/Math/Vector4.cs deleted file mode 100644 index 98f374fc..00000000 --- a/OpenTK/Math/Vector4.cs +++ /dev/null @@ -1,1639 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; -using System.Xml.Serialization; -namespace OpenTK -{ - /// Represents a 4D vector using four single-precision floating-point numbers. - /// - /// The Vector4 structure is suitable for interoperation with unmanaged code requiring four consecutive floats. - /// - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Vector4 : IEquatable - { - #region Fields - - /// - /// The X component of the Vector4. - /// - public float X; - - /// - /// The Y component of the Vector4. - /// - public float Y; - - /// - /// The Z component of the Vector4. - /// - public float Z; - - /// - /// The W component of the Vector4. - /// - public float W; - - /// - /// Defines a unit-length Vector4 that points towards the X-axis. - /// - public static readonly Vector4 UnitX = new Vector4(1, 0, 0, 0); - - /// - /// Defines a unit-length Vector4 that points towards the Y-axis. - /// - public static readonly Vector4 UnitY = new Vector4(0, 1, 0, 0); - - /// - /// Defines a unit-length Vector4 that points towards the Z-axis. - /// - public static readonly Vector4 UnitZ = new Vector4(0, 0, 1, 0); - - /// - /// Defines a unit-length Vector4 that points towards the W-axis. - /// - public static readonly Vector4 UnitW = new Vector4(0, 0, 0, 1); - - /// - /// Defines a zero-length Vector4. - /// - public static readonly Vector4 Zero = new Vector4(0, 0, 0, 0); - - /// - /// Defines an instance with all components set to 1. - /// - public static readonly Vector4 One = new Vector4(1, 1, 1, 1); - - /// - /// Defines the size of the Vector4 struct in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4()); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector4(float value) - { - X = value; - Y = value; - Z = value; - W = value; - } - - /// - /// Constructs a new Vector4. - /// - /// The x component of the Vector4. - /// The y component of the Vector4. - /// The z component of the Vector4. - /// The w component of the Vector4. - public Vector4(float x, float y, float z, float w) - { - X = x; - Y = y; - Z = z; - W = w; - } - - /// - /// Constructs a new Vector4 from the given Vector2. - /// - /// The Vector2 to copy components from. - public Vector4(Vector2 v) - { - X = v.X; - Y = v.Y; - Z = 0.0f; - W = 0.0f; - } - - /// - /// Constructs a new Vector4 from the given Vector3. - /// The w component is initialized to 0. - /// - /// The Vector3 to copy components from. - /// - public Vector4(Vector3 v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - W = 0.0f; - } - - /// - /// Constructs a new Vector4 from the specified Vector3 and w component. - /// - /// The Vector3 to copy components from. - /// The w component of the new Vector4. - public Vector4(Vector3 v, float w) - { - X = v.X; - Y = v.Y; - Z = v.Z; - W = w; - } - - /// - /// Constructs a new Vector4 from the given Vector4. - /// - /// The Vector4 to copy components from. - public Vector4(Vector4 v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - W = v.W; - } - - #endregion - - #region Public Members - - /// - /// Gets or sets the value at the index of the Vector. - /// - public float this[int index] { - get{ - if(index == 0) return X; - else if(index == 1) return Y; - else if(index == 2) return Z; - else if(index == 3) return W; - throw new IndexOutOfRangeException("You tried to access this vector at index: " + index); - } set{ - if(index == 0) X = value; - else if(index == 1) Y = value; - else if(index == 2) Z = value; - else if(index == 3) W = value; - else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index); - } - } - - #region Instance - - #region public void Add() - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(Vector4 right) - { - this.X += right.X; - this.Y += right.Y; - this.Z += right.Z; - this.W += right.W; - } - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(ref Vector4 right) - { - this.X += right.X; - this.Y += right.Y; - this.Z += right.Z; - this.W += right.W; - } - - #endregion public void Add() - - #region public void Sub() - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(Vector4 right) - { - this.X -= right.X; - this.Y -= right.Y; - this.Z -= right.Z; - this.W -= right.W; - } - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(ref Vector4 right) - { - this.X -= right.X; - this.Y -= right.Y; - this.Z -= right.Z; - this.W -= right.W; - } - - #endregion public void Sub() - - #region public void Mult() - - /// Multiply this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Multiply() method instead.")] - public void Mult(float f) - { - this.X *= f; - this.Y *= f; - this.Z *= f; - this.W *= f; - } - - #endregion public void Mult() - - #region public void Div() - - /// Divide this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Divide() method instead.")] - public void Div(float f) - { - float mult = 1.0f / f; - this.X *= mult; - this.Y *= mult; - this.Z *= mult; - this.W *= mult; - } - - #endregion public void Div() - - #region public float Length - - /// - /// Gets the length (magnitude) of the vector. - /// - /// - /// - public float Length - { - get - { - return (float)System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W); - } - } - - #endregion - - #region public float LengthFast - - /// - /// Gets an approximation of the vector length (magnitude). - /// - /// - /// This property uses an approximation of the square root function to calculate vector magnitude, with - /// an upper error bound of 0.001. - /// - /// - /// - public float LengthFast - { - get - { - return 1.0f / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W); - } - } - - #endregion - - #region public float LengthSquared - - /// - /// Gets the square of the vector length (magnitude). - /// - /// - /// This property avoids the costly square root operation required by the Length property. This makes it more suitable - /// for comparisons. - /// - /// - /// - public float LengthSquared - { - get - { - return X * X + Y * Y + Z * Z + W * W; - } - } - - #endregion - - /// - /// Returns a copy of the Vector4 scaled to unit length. - /// - public Vector4 Normalized() - { - Vector4 v = this; - v.Normalize(); - return v; - } - - #region public void Normalize() - - /// - /// Scales the Vector4 to unit length. - /// - public void Normalize() - { - float scale = 1.0f / this.Length; - X *= scale; - Y *= scale; - Z *= scale; - W *= scale; - } - - #endregion - - #region public void NormalizeFast() - - /// - /// Scales the Vector4 to approximately unit length. - /// - public void NormalizeFast() - { - float scale = MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W); - X *= scale; - Y *= scale; - Z *= scale; - W *= scale; - } - - #endregion - - #region public void Scale() - - /// - /// Scales the current Vector4 by the given amounts. - /// - /// The scale of the X component. - /// The scale of the Y component. - /// The scale of the Z component. - /// The scale of the Z component. - [Obsolete("Use static Multiply() method instead.")] - public void Scale(float sx, float sy, float sz, float sw) - { - this.X = X * sx; - this.Y = Y * sy; - this.Z = Z * sz; - this.W = W * sw; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(Vector4 scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - this.Z *= scale.Z; - this.W *= scale.W; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(ref Vector4 scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - this.Z *= scale.Z; - this.W *= scale.W; - } - - #endregion public void Scale() - - #endregion - - #region Static - - #region Obsolete - - #region Sub - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static Vector4 Sub(Vector4 a, Vector4 b) - { - a.X -= b.X; - a.Y -= b.Y; - a.Z -= b.Z; - a.W -= b.W; - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static void Sub(ref Vector4 a, ref Vector4 b, out Vector4 result) - { - result.X = a.X - b.X; - result.Y = a.Y - b.Y; - result.Z = a.Z - b.Z; - result.W = a.W - b.W; - } - - #endregion - - #region Mult - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - public static Vector4 Mult(Vector4 a, float f) - { - a.X *= f; - a.Y *= f; - a.Z *= f; - a.W *= f; - return a; - } - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - public static void Mult(ref Vector4 a, float f, out Vector4 result) - { - result.X = a.X * f; - result.Y = a.Y * f; - result.Z = a.Z * f; - result.W = a.W * f; - } - - #endregion - - #region Div - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - public static Vector4 Div(Vector4 a, float f) - { - float mult = 1.0f / f; - a.X *= mult; - a.Y *= mult; - a.Z *= mult; - a.W *= mult; - return a; - } - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - public static void Div(ref Vector4 a, float f, out Vector4 result) - { - float mult = 1.0f / f; - result.X = a.X * mult; - result.Y = a.Y * mult; - result.Z = a.Z * mult; - result.W = a.W * mult; - } - - #endregion - - #endregion - - #region Add - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static Vector4 Add(Vector4 a, Vector4 b) - { - Add(ref a, ref b, out a); - return a; - } - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static void Add(ref Vector4 a, ref Vector4 b, out Vector4 result) - { - result = new Vector4(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W); - } - - #endregion - - #region Subtract - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static Vector4 Subtract(Vector4 a, Vector4 b) - { - Subtract(ref a, ref b, out a); - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static void Subtract(ref Vector4 a, ref Vector4 b, out Vector4 result) - { - result = new Vector4(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W); - } - - #endregion - - #region Multiply - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector4 Multiply(Vector4 vector, float scale) - { - Multiply(ref vector, scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector4 vector, float scale, out Vector4 result) - { - result = new Vector4(vector.X * scale, vector.Y * scale, vector.Z * scale, vector.W * scale); - } - - /// - /// Multiplies a vector by the components a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector4 Multiply(Vector4 vector, Vector4 scale) - { - Multiply(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector4 vector, ref Vector4 scale, out Vector4 result) - { - result = new Vector4(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z, vector.W * scale.W); - } - - #endregion - - #region Divide - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector4 Divide(Vector4 vector, float scale) - { - Divide(ref vector, scale, out vector); - return vector; - } - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector4 vector, float scale, out Vector4 result) - { - Multiply(ref vector, 1 / scale, out result); - } - - /// - /// Divides a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector4 Divide(Vector4 vector, Vector4 scale) - { - Divide(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Divide a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector4 vector, ref Vector4 scale, out Vector4 result) - { - result = new Vector4(vector.X / scale.X, vector.Y / scale.Y, vector.Z / scale.Z, vector.W / scale.W); - } - - #endregion - - #region Min - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static Vector4 Min(Vector4 a, Vector4 b) - { - a.X = a.X < b.X ? a.X : b.X; - a.Y = a.Y < b.Y ? a.Y : b.Y; - a.Z = a.Z < b.Z ? a.Z : b.Z; - a.W = a.W < b.W ? a.W : b.W; - return a; - } - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static void Min(ref Vector4 a, ref Vector4 b, out Vector4 result) - { - result.X = a.X < b.X ? a.X : b.X; - result.Y = a.Y < b.Y ? a.Y : b.Y; - result.Z = a.Z < b.Z ? a.Z : b.Z; - result.W = a.W < b.W ? a.W : b.W; - } - - #endregion - - #region Max - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static Vector4 Max(Vector4 a, Vector4 b) - { - a.X = a.X > b.X ? a.X : b.X; - a.Y = a.Y > b.Y ? a.Y : b.Y; - a.Z = a.Z > b.Z ? a.Z : b.Z; - a.W = a.W > b.W ? a.W : b.W; - return a; - } - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static void Max(ref Vector4 a, ref Vector4 b, out Vector4 result) - { - result.X = a.X > b.X ? a.X : b.X; - result.Y = a.Y > b.Y ? a.Y : b.Y; - result.Z = a.Z > b.Z ? a.Z : b.Z; - result.W = a.W > b.W ? a.W : b.W; - } - - #endregion - - #region Clamp - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static Vector4 Clamp(Vector4 vec, Vector4 min, Vector4 max) - { - vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - vec.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z; - vec.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W; - return vec; - } - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static void Clamp(ref Vector4 vec, ref Vector4 min, ref Vector4 max, out Vector4 result) - { - result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - result.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z; - result.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W; - } - - #endregion - - #region Normalize - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static Vector4 Normalize(Vector4 vec) - { - float scale = 1.0f / vec.Length; - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static void Normalize(ref Vector4 vec, out Vector4 result) - { - float scale = 1.0f / vec.Length; - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - result.W = vec.W * scale; - } - - #endregion - - #region NormalizeFast - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static Vector4 NormalizeFast(Vector4 vec) - { - float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W); - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static void NormalizeFast(ref Vector4 vec, out Vector4 result) - { - float scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W); - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - result.W = vec.W * scale; - } - - #endregion - - #region Dot - - /// - /// Calculate the dot product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static float Dot(Vector4 left, Vector4 right) - { - return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W; - } - - /// - /// Calculate the dot product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static void Dot(ref Vector4 left, ref Vector4 right, out float result) - { - result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W; - } - - #endregion - - #region Lerp - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static Vector4 Lerp(Vector4 a, Vector4 b, float blend) - { - a.X = blend * (b.X - a.X) + a.X; - a.Y = blend * (b.Y - a.Y) + a.Y; - a.Z = blend * (b.Z - a.Z) + a.Z; - a.W = blend * (b.W - a.W) + a.W; - return a; - } - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static void Lerp(ref Vector4 a, ref Vector4 b, float blend, out Vector4 result) - { - result.X = blend * (b.X - a.X) + a.X; - result.Y = blend * (b.Y - a.Y) + a.Y; - result.Z = blend * (b.Z - a.Z) + a.Z; - result.W = blend * (b.W - a.W) + a.W; - } - - #endregion - - #region Barycentric - - /// - /// Interpolate 3 Vectors using Barycentric coordinates - /// - /// First input Vector - /// Second input Vector - /// Third input Vector - /// First Barycentric Coordinate - /// Second Barycentric Coordinate - /// a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static Vector4 BaryCentric(Vector4 a, Vector4 b, Vector4 c, float u, float v) - { - return a + u * (b - a) + v * (c - a); - } - - /// Interpolate 3 Vectors using Barycentric coordinates - /// First input Vector. - /// Second input Vector. - /// Third input Vector. - /// First Barycentric Coordinate. - /// Second Barycentric Coordinate. - /// Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static void BaryCentric(ref Vector4 a, ref Vector4 b, ref Vector4 c, float u, float v, out Vector4 result) - { - result = a; // copy - - Vector4 temp = b; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, u, out temp); - Add(ref result, ref temp, out result); - - temp = c; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, v, out temp); - Add(ref result, ref temp, out result); - } - - #endregion - - #region Transform - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static Vector4 Transform(Vector4 vec, Matrix4 mat) - { - Vector4 result; - Transform(ref vec, ref mat, out result); - return result; - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static void Transform(ref Vector4 vec, ref Matrix4 mat, out Vector4 result) - { - result = new Vector4( - vec.X * mat.Row0.X + vec.Y * mat.Row1.X + vec.Z * mat.Row2.X + vec.W * mat.Row3.X, - vec.X * mat.Row0.Y + vec.Y * mat.Row1.Y + vec.Z * mat.Row2.Y + vec.W * mat.Row3.Y, - vec.X * mat.Row0.Z + vec.Y * mat.Row1.Z + vec.Z * mat.Row2.Z + vec.W * mat.Row3.Z, - vec.X * mat.Row0.W + vec.Y * mat.Row1.W + vec.Z * mat.Row2.W + vec.W * mat.Row3.W); - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static Vector4 Transform(Vector4 vec, Quaternion quat) - { - Vector4 result; - Transform(ref vec, ref quat, out result); - return result; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static void Transform(ref Vector4 vec, ref Quaternion quat, out Vector4 result) - { - Quaternion v = new Quaternion(vec.X, vec.Y, vec.Z, vec.W), i, t; - Quaternion.Invert(ref quat, out i); - Quaternion.Multiply(ref quat, ref v, out t); - Quaternion.Multiply(ref t, ref i, out v); - - result = new Vector4(v.X, v.Y, v.Z, v.W); - } - - #endregion - - #endregion - - #region Swizzle - - #region 2-component - - /// - /// Gets or sets an OpenTK.Vector2 with the X and Y components of this instance. - /// - [XmlIgnore] - public Vector2 Xy { get { return new Vector2(X, Y); } set { X = value.X; Y = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the X and Z components of this instance. - /// - [XmlIgnore] - public Vector2 Xz { get { return new Vector2(X, Z); } set { X = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the X and W components of this instance. - /// - [XmlIgnore] - public Vector2 Xw { get { return new Vector2(X, W); } set { X = value.X; W = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the Y and X components of this instance. - /// - [XmlIgnore] - public Vector2 Yx { get { return new Vector2(Y, X); } set { Y = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the Y and Z components of this instance. - /// - [XmlIgnore] - public Vector2 Yz { get { return new Vector2(Y, Z); } set { Y = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the Y and W components of this instance. - /// - [XmlIgnore] - public Vector2 Yw { get { return new Vector2(Y, W); } set { Y = value.X; W = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the Z and X components of this instance. - /// - [XmlIgnore] - public Vector2 Zx { get { return new Vector2(Z, X); } set { Z = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the Z and Y components of this instance. - /// - [XmlIgnore] - public Vector2 Zy { get { return new Vector2(Z, Y); } set { Z = value.X; Y = value.Y; } } - - /// - /// Gets an OpenTK.Vector2 with the Z and W components of this instance. - /// - [XmlIgnore] - public Vector2 Zw { get { return new Vector2(Z, W); } set { Z = value.X; W = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the W and X components of this instance. - /// - [XmlIgnore] - public Vector2 Wx { get { return new Vector2(W, X); } set { W = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the W and Y components of this instance. - /// - [XmlIgnore] - public Vector2 Wy { get { return new Vector2(W, Y); } set { W = value.X; Y = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2 with the W and Z components of this instance. - /// - [XmlIgnore] - public Vector2 Wz { get { return new Vector2(W, Z); } set { W = value.X; Z = value.Y; } } - - #endregion - - #region 3-component - - /// - /// Gets or sets an OpenTK.Vector3 with the X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector3 Xyz { get { return new Vector3(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector3 Xyw { get { return new Vector3(X, Y, W); } set { X = value.X; Y = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the X, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector3 Xzy { get { return new Vector3(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the X, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector3 Xzw { get { return new Vector3(X, Z, W); } set { X = value.X; Z = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the X, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector3 Xwy { get { return new Vector3(X, W, Y); } set { X = value.X; W = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the X, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector3 Xwz { get { return new Vector3(X, W, Z); } set { X = value.X; W = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Y, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector3 Yxz { get { return new Vector3(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Y, X, and W components of this instance. - /// - [XmlIgnore] - public Vector3 Yxw { get { return new Vector3(Y, X, W); } set { Y = value.X; X = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Y, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector3 Yzx { get { return new Vector3(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Y, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector3 Yzw { get { return new Vector3(Y, Z, W); } set { Y = value.X; Z = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Y, W, and X components of this instance. - /// - [XmlIgnore] - public Vector3 Ywx { get { return new Vector3(Y, W, X); } set { Y = value.X; W = value.Y; X = value.Z; } } - - /// - /// Gets an OpenTK.Vector3 with the Y, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector3 Ywz { get { return new Vector3(Y, W, Z); } set { Y = value.X; W = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Z, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector3 Zxy { get { return new Vector3(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Z, X, and W components of this instance. - /// - [XmlIgnore] - public Vector3 Zxw { get { return new Vector3(Z, X, W); } set { Z = value.X; X = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Z, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector3 Zyx { get { return new Vector3(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Z, Y, and W components of this instance. - /// - [XmlIgnore] - public Vector3 Zyw { get { return new Vector3(Z, Y, W); } set { Z = value.X; Y = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Z, W, and X components of this instance. - /// - [XmlIgnore] - public Vector3 Zwx { get { return new Vector3(Z, W, X); } set { Z = value.X; W = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the Z, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector3 Zwy { get { return new Vector3(Z, W, Y); } set { Z = value.X; W = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the W, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector3 Wxy { get { return new Vector3(W, X, Y); } set { W = value.X; X = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the W, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector3 Wxz { get { return new Vector3(W, X, Z); } set { W = value.X; X = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the W, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector3 Wyx { get { return new Vector3(W, Y, X); } set { W = value.X; Y = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the W, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector3 Wyz { get { return new Vector3(W, Y, Z); } set { W = value.X; Y = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the W, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector3 Wzx { get { return new Vector3(W, Z, X); } set { W = value.X; Z = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3 with the W, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector3 Wzy { get { return new Vector3(W, Z, Y); } set { W = value.X; Z = value.Y; Y = value.Z; } } - - #endregion - - #region 4-component - - /// - /// Gets or sets an OpenTK.Vector4 with the X, Y, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector4 Xywz { get { return new Vector4(X, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the X, Z, Y, and W components of this instance. - /// - [XmlIgnore] - public Vector4 Xzyw { get { return new Vector4(X, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the X, Z, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector4 Xzwy { get { return new Vector4(X, Z, W, Y); } set { X = value.X; Z = value.Y; W = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the X, W, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector4 Xwyz { get { return new Vector4(X, W, Y, Z); } set { X = value.X; W = value.Y; Y = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the X, W, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector4 Xwzy { get { return new Vector4(X, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Y, X, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector4 Yxzw { get { return new Vector4(Y, X, Z, W); } set { Y = value.X; X = value.Y; Z = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Y, X, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector4 Yxwz { get { return new Vector4(Y, X, W, Z); } set { Y = value.X; X = value.Y; W = value.Z; Z = value.W; } } - - /// - /// Gets an OpenTK.Vector4 with the Y, Y, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector4 Yyzw { get { return new Vector4(Y, Y, Z, W); } set { X = value.X; Y = value.Y; Z = value.Z; W = value.W; } } - - /// - /// Gets an OpenTK.Vector4 with the Y, Y, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector4 Yywz { get { return new Vector4(Y, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Y, Z, X, and W components of this instance. - /// - [XmlIgnore] - public Vector4 Yzxw { get { return new Vector4(Y, Z, X, W); } set { Y = value.X; Z = value.Y; X = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Y, Z, W, and X components of this instance. - /// - [XmlIgnore] - public Vector4 Yzwx { get { return new Vector4(Y, Z, W, X); } set { Y = value.X; Z = value.Y; W = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Y, W, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector4 Ywxz { get { return new Vector4(Y, W, X, Z); } set { Y = value.X; W = value.Y; X = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Y, W, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector4 Ywzx { get { return new Vector4(Y, W, Z, X); } set { Y = value.X; W = value.Y; Z = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Z, X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector4 Zxyw { get { return new Vector4(Z, X, Y, W); } set { Z = value.X; X = value.Y; Y = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Z, X, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector4 Zxwy { get { return new Vector4(Z, X, W, Y); } set { Z = value.X; X = value.Y; W = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Z, Y, X, and W components of this instance. - /// - [XmlIgnore] - public Vector4 Zyxw { get { return new Vector4(Z, Y, X, W); } set { Z = value.X; Y = value.Y; X = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Z, Y, W, and X components of this instance. - /// - [XmlIgnore] - public Vector4 Zywx { get { return new Vector4(Z, Y, W, X); } set { Z = value.X; Y = value.Y; W = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Z, W, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector4 Zwxy { get { return new Vector4(Z, W, X, Y); } set { Z = value.X; W = value.Y; X = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the Z, W, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector4 Zwyx { get { return new Vector4(Z, W, Y, X); } set { Z = value.X; W = value.Y; Y = value.Z; X = value.W; } } - - /// - /// Gets an OpenTK.Vector4 with the Z, W, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector4 Zwzy { get { return new Vector4(Z, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the W, X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector4 Wxyz { get { return new Vector4(W, X, Y, Z); } set { W = value.X; X = value.Y; Y = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the W, X, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector4 Wxzy { get { return new Vector4(W, X, Z, Y); } set { W = value.X; X = value.Y; Z = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the W, Y, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector4 Wyxz { get { return new Vector4(W, Y, X, Z); } set { W = value.X; Y = value.Y; X = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the W, Y, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector4 Wyzx { get { return new Vector4(W, Y, Z, X); } set { W = value.X; Y = value.Y; Z = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the W, Z, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector4 Wzxy { get { return new Vector4(W, Z, X, Y); } set { W = value.X; Z = value.Y; X = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4 with the W, Z, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector4 Wzyx { get { return new Vector4(W, Z, Y, X); } set { W = value.X; Z = value.Y; Y = value.Z; X = value.W; } } - - /// - /// Gets an OpenTK.Vector4 with the W, Z, Y, and W components of this instance. - /// - [XmlIgnore] - public Vector4 Wzyw { get { return new Vector4(W, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } } - - #endregion - - #endregion - - #region Operators - - /// - /// Adds two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Vector4 operator +(Vector4 left, Vector4 right) - { - left.X += right.X; - left.Y += right.Y; - left.Z += right.Z; - left.W += right.W; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Vector4 operator -(Vector4 left, Vector4 right) - { - left.X -= right.X; - left.Y -= right.Y; - left.Z -= right.Z; - left.W -= right.W; - return left; - } - - /// - /// Negates an instance. - /// - /// The instance. - /// The result of the calculation. - public static Vector4 operator -(Vector4 vec) - { - vec.X = -vec.X; - vec.Y = -vec.Y; - vec.Z = -vec.Z; - vec.W = -vec.W; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - public static Vector4 operator *(Vector4 vec, float scale) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The scalar. - /// The instance. - /// The result of the calculation. - public static Vector4 operator *(float scale, Vector4 vec) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Component-wise multiplication between the specified instance by a scale vector. - /// - /// Left operand. - /// Right operand. - /// Result of multiplication. - public static Vector4 operator *(Vector4 vec, Vector4 scale) - { - vec.X *= scale.X; - vec.Y *= scale.Y; - vec.Z *= scale.Z; - vec.W *= scale.W; - return vec; - } - - /// - /// Divides an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - public static Vector4 operator /(Vector4 vec, float scale) - { - float mult = 1.0f / scale; - vec.X *= mult; - vec.Y *= mult; - vec.Z *= mult; - vec.W *= mult; - return vec; - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Vector4 left, Vector4 right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equa lright; false otherwise. - public static bool operator !=(Vector4 left, Vector4 right) - { - return !left.Equals(right); - } - - /// - /// Returns a pointer to the first element of the specified instance. - /// - /// The instance. - /// A pointer to the first element of v. - [CLSCompliant(false)] - unsafe public static explicit operator float*(Vector4 v) - { - return &v.X; - } - - /// - /// Returns a pointer to the first element of the specified instance. - /// - /// The instance. - /// A pointer to the first element of v. - public static explicit operator IntPtr(Vector4 v) - { - unsafe - { - return (IntPtr)(&v.X); - } - } - - #endregion - - #region Overrides - - #region public override string ToString() - - private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator; - /// - /// Returns a System.String that represents the current Vector4. - /// - /// - public override string ToString() - { - return String.Format("({0}{4} {1}{4} {2}{4} {3})", X, Y, Z, W, listSeparator); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Vector4)) - return false; - - return this.Equals((Vector4)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current vector is equal to another vector. - /// A vector to compare with this vector. - /// true if the current vector is equal to the vector parameter; otherwise, false. - public bool Equals(Vector4 other) - { - return - X == other.X && - Y == other.Y && - Z == other.Z && - W == other.W; - } - - #endregion - } -} diff --git a/OpenTK/Math/Vector4d.cs b/OpenTK/Math/Vector4d.cs deleted file mode 100644 index b158005e..00000000 --- a/OpenTK/Math/Vector4d.cs +++ /dev/null @@ -1,1658 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.Runtime.InteropServices; -using System.Xml.Serialization; - -namespace OpenTK -{ - /// Represents a 4D vector using four double-precision floating-point numbers. - [Serializable] - [StructLayout(LayoutKind.Sequential)] - public struct Vector4d : IEquatable - { - #region Fields - - /// - /// The X component of the Vector4d. - /// - public double X; - - /// - /// The Y component of the Vector4d. - /// - public double Y; - - /// - /// The Z component of the Vector4d. - /// - public double Z; - - /// - /// The W component of the Vector4d. - /// - public double W; - - /// - /// Defines a unit-length Vector4d that points towards the X-axis. - /// - public static readonly Vector4d UnitX = new Vector4d(1, 0, 0, 0); - - /// - /// Defines a unit-length Vector4d that points towards the Y-axis. - /// - public static readonly Vector4d UnitY = new Vector4d(0, 1, 0, 0); - - /// - /// Defines a unit-length Vector4d that points towards the Z-axis. - /// - public static readonly Vector4d UnitZ = new Vector4d(0, 0, 1, 0); - - /// - /// Defines a unit-length Vector4d that points towards the W-axis. - /// - public static readonly Vector4d UnitW = new Vector4d(0, 0, 0, 1); - - /// - /// Defines a zero-length Vector4d. - /// - public static readonly Vector4d Zero = new Vector4d(0, 0, 0, 0); - - /// - /// Defines an instance with all components set to 1. - /// - public static readonly Vector4d One = new Vector4d(1, 1, 1, 1); - - /// - /// Defines the size of the Vector4d struct in bytes. - /// - public static readonly int SizeInBytes = Marshal.SizeOf(new Vector4d()); - - #endregion - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector4d(double value) - { - X = value; - Y = value; - Z = value; - W = value; - } - - /// - /// Constructs a new Vector4d. - /// - /// The x component of the Vector4d. - /// The y component of the Vector4d. - /// The z component of the Vector4d. - /// The w component of the Vector4d. - public Vector4d(double x, double y, double z, double w) - { - X = x; - Y = y; - Z = z; - W = w; - } - - /// - /// Constructs a new Vector4d from the given Vector2d. - /// - /// The Vector2d to copy components from. - public Vector4d(Vector2d v) - { - X = v.X; - Y = v.Y; - Z = 0.0f; - W = 0.0f; - } - - /// - /// Constructs a new Vector4d from the given Vector3d. - /// The w component is initialized to 0. - /// - /// The Vector3d to copy components from. - /// - public Vector4d(Vector3d v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - W = 0.0f; - } - - /// - /// Constructs a new Vector4d from the specified Vector3d and w component. - /// - /// The Vector3d to copy components from. - /// The w component of the new Vector4. - public Vector4d(Vector3d v, double w) - { - X = v.X; - Y = v.Y; - Z = v.Z; - W = w; - } - - /// - /// Constructs a new Vector4d from the given Vector4d. - /// - /// The Vector4d to copy components from. - public Vector4d(Vector4d v) - { - X = v.X; - Y = v.Y; - Z = v.Z; - W = v.W; - } - - #endregion - - #region Public Members - - /// - /// Gets or sets the value at the index of the Vector. - /// - public double this[int index] { - get{ - if(index == 0) return X; - else if(index == 1) return Y; - else if(index == 2) return Z; - else if(index == 3) return W; - throw new IndexOutOfRangeException("You tried to access this vector at index: " + index); - } set{ - if(index == 0) X = value; - else if(index == 1) Y = value; - else if(index == 2) Z = value; - else if(index == 3) W = value; - else throw new IndexOutOfRangeException("You tried to set this vector at index: " + index); - } - } - - #region Instance - - #region public void Add() - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(Vector4d right) - { - this.X += right.X; - this.Y += right.Y; - this.Z += right.Z; - this.W += right.W; - } - - /// Add the Vector passed as parameter to this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Add() method instead.")] - public void Add(ref Vector4d right) - { - this.X += right.X; - this.Y += right.Y; - this.Z += right.Z; - this.W += right.W; - } - - #endregion public void Add() - - #region public void Sub() - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(Vector4d right) - { - this.X -= right.X; - this.Y -= right.Y; - this.Z -= right.Z; - this.W -= right.W; - } - - /// Subtract the Vector passed as parameter from this instance. - /// Right operand. This parameter is only read from. - [CLSCompliant(false)] - [Obsolete("Use static Subtract() method instead.")] - public void Sub(ref Vector4d right) - { - this.X -= right.X; - this.Y -= right.Y; - this.Z -= right.Z; - this.W -= right.W; - } - - #endregion public void Sub() - - #region public void Mult() - - /// Multiply this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Multiply() method instead.")] - public void Mult(double f) - { - this.X *= f; - this.Y *= f; - this.Z *= f; - this.W *= f; - } - - #endregion public void Mult() - - #region public void Div() - - /// Divide this instance by a scalar. - /// Scalar operand. - [Obsolete("Use static Divide() method instead.")] - public void Div(double f) - { - double mult = 1.0 / f; - this.X *= mult; - this.Y *= mult; - this.Z *= mult; - this.W *= mult; - } - - #endregion public void Div() - - #region public double Length - - /// - /// Gets the length (magnitude) of the vector. - /// - /// - /// - public double Length - { - get - { - return System.Math.Sqrt(X * X + Y * Y + Z * Z + W * W); - } - } - - #endregion - - #region public double LengthFast - - /// - /// Gets an approximation of the vector length (magnitude). - /// - /// - /// This property uses an approximation of the square root function to calculate vector magnitude, with - /// an upper error bound of 0.001. - /// - /// - /// - public double LengthFast - { - get - { - return 1.0 / MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W); - } - } - - #endregion - - #region public double LengthSquared - - /// - /// Gets the square of the vector length (magnitude). - /// - /// - /// This property avoids the costly square root operation required by the Length property. This makes it more suitable - /// for comparisons. - /// - /// - public double LengthSquared - { - get - { - return X * X + Y * Y + Z * Z + W * W; - } - } - - #endregion - - /// - /// Returns a copy of the Vector4d scaled to unit length. - /// - public Vector4d Normalized() - { - Vector4d v = this; - v.Normalize(); - return v; - } - - #region public void Normalize() - - /// - /// Scales the Vector4d to unit length. - /// - public void Normalize() - { - double scale = 1.0 / this.Length; - X *= scale; - Y *= scale; - Z *= scale; - W *= scale; - } - - #endregion - - #region public void NormalizeFast() - - /// - /// Scales the Vector4d to approximately unit length. - /// - public void NormalizeFast() - { - double scale = MathHelper.InverseSqrtFast(X * X + Y * Y + Z * Z + W * W); - X *= scale; - Y *= scale; - Z *= scale; - W *= scale; - } - - #endregion - - #region public void Scale() - - /// - /// Scales the current Vector4d by the given amounts. - /// - /// The scale of the X component. - /// The scale of the Y component. - /// The scale of the Z component. - /// The scale of the Z component. - [Obsolete("Use static Multiply() method instead.")] - public void Scale(double sx, double sy, double sz, double sw) - { - this.X = X * sx; - this.Y = Y * sy; - this.Z = Z * sz; - this.W = W * sw; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(Vector4d scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - this.Z *= scale.Z; - this.W *= scale.W; - } - - /// Scales this instance by the given parameter. - /// The scaling of the individual components. - [CLSCompliant(false)] - [Obsolete("Use static Multiply() method instead.")] - public void Scale(ref Vector4d scale) - { - this.X *= scale.X; - this.Y *= scale.Y; - this.Z *= scale.Z; - this.W *= scale.W; - } - - #endregion public void Scale() - - #endregion - - #region Static - - #region Obsolete - - #region Sub - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static Vector4d Sub(Vector4d a, Vector4d b) - { - a.X -= b.X; - a.Y -= b.Y; - a.Z -= b.Z; - a.W -= b.W; - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - [Obsolete("Use static Subtract() method instead.")] - public static void Sub(ref Vector4d a, ref Vector4d b, out Vector4d result) - { - result.X = a.X - b.X; - result.Y = a.Y - b.Y; - result.Z = a.Z - b.Z; - result.W = a.W - b.W; - } - - #endregion - - #region Mult - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static Vector4d Mult(Vector4d a, double f) - { - a.X *= f; - a.Y *= f; - a.Z *= f; - a.W *= f; - return a; - } - - /// - /// Multiply a vector and a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the multiplication - [Obsolete("Use static Multiply() method instead.")] - public static void Mult(ref Vector4d a, double f, out Vector4d result) - { - result.X = a.X * f; - result.Y = a.Y * f; - result.Z = a.Z * f; - result.W = a.W * f; - } - - #endregion - - #region Div - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static Vector4d Div(Vector4d a, double f) - { - double mult = 1.0 / f; - a.X *= mult; - a.Y *= mult; - a.Z *= mult; - a.W *= mult; - return a; - } - - /// - /// Divide a vector by a scalar - /// - /// Vector operand - /// Scalar operand - /// Result of the division - [Obsolete("Use static Divide() method instead.")] - public static void Div(ref Vector4d a, double f, out Vector4d result) - { - double mult = 1.0 / f; - result.X = a.X * mult; - result.Y = a.Y * mult; - result.Z = a.Z * mult; - result.W = a.W * mult; - } - - #endregion - - #endregion - - #region Add - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static Vector4d Add(Vector4d a, Vector4d b) - { - Add(ref a, ref b, out a); - return a; - } - - /// - /// Adds two vectors. - /// - /// Left operand. - /// Right operand. - /// Result of operation. - public static void Add(ref Vector4d a, ref Vector4d b, out Vector4d result) - { - result = new Vector4d(a.X + b.X, a.Y + b.Y, a.Z + b.Z, a.W + b.W); - } - - #endregion - - #region Subtract - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static Vector4d Subtract(Vector4d a, Vector4d b) - { - Subtract(ref a, ref b, out a); - return a; - } - - /// - /// Subtract one Vector from another - /// - /// First operand - /// Second operand - /// Result of subtraction - public static void Subtract(ref Vector4d a, ref Vector4d b, out Vector4d result) - { - result = new Vector4d(a.X - b.X, a.Y - b.Y, a.Z - b.Z, a.W - b.W); - } - - #endregion - - #region Multiply - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector4d Multiply(Vector4d vector, double scale) - { - Multiply(ref vector, scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector4d vector, double scale, out Vector4d result) - { - result = new Vector4d(vector.X * scale, vector.Y * scale, vector.Z * scale, vector.W * scale); - } - - /// - /// Multiplies a vector by the components a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector4d Multiply(Vector4d vector, Vector4d scale) - { - Multiply(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Multiplies a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Multiply(ref Vector4d vector, ref Vector4d scale, out Vector4d result) - { - result = new Vector4d(vector.X * scale.X, vector.Y * scale.Y, vector.Z * scale.Z, vector.W * scale.W); - } - - #endregion - - #region Divide - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector4d Divide(Vector4d vector, double scale) - { - Divide(ref vector, scale, out vector); - return vector; - } - - /// - /// Divides a vector by a scalar. - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector4d vector, double scale, out Vector4d result) - { - Multiply(ref vector, 1 / scale, out result); - } - - /// - /// Divides a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static Vector4d Divide(Vector4d vector, Vector4d scale) - { - Divide(ref vector, ref scale, out vector); - return vector; - } - - /// - /// Divide a vector by the components of a vector (scale). - /// - /// Left operand. - /// Right operand. - /// Result of the operation. - public static void Divide(ref Vector4d vector, ref Vector4d scale, out Vector4d result) - { - result = new Vector4d(vector.X / scale.X, vector.Y / scale.Y, vector.Z / scale.Z, vector.W / scale.W); - } - - #endregion - - #region Min - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static Vector4d Min(Vector4d a, Vector4d b) - { - a.X = a.X < b.X ? a.X : b.X; - a.Y = a.Y < b.Y ? a.Y : b.Y; - a.Z = a.Z < b.Z ? a.Z : b.Z; - a.W = a.W < b.W ? a.W : b.W; - return a; - } - - /// - /// Calculate the component-wise minimum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise minimum - public static void Min(ref Vector4d a, ref Vector4d b, out Vector4d result) - { - result.X = a.X < b.X ? a.X : b.X; - result.Y = a.Y < b.Y ? a.Y : b.Y; - result.Z = a.Z < b.Z ? a.Z : b.Z; - result.W = a.W < b.W ? a.W : b.W; - } - - #endregion - - #region Max - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static Vector4d Max(Vector4d a, Vector4d b) - { - a.X = a.X > b.X ? a.X : b.X; - a.Y = a.Y > b.Y ? a.Y : b.Y; - a.Z = a.Z > b.Z ? a.Z : b.Z; - a.W = a.W > b.W ? a.W : b.W; - return a; - } - - /// - /// Calculate the component-wise maximum of two vectors - /// - /// First operand - /// Second operand - /// The component-wise maximum - public static void Max(ref Vector4d a, ref Vector4d b, out Vector4d result) - { - result.X = a.X > b.X ? a.X : b.X; - result.Y = a.Y > b.Y ? a.Y : b.Y; - result.Z = a.Z > b.Z ? a.Z : b.Z; - result.W = a.W > b.W ? a.W : b.W; - } - - #endregion - - #region Clamp - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static Vector4d Clamp(Vector4d vec, Vector4d min, Vector4d max) - { - vec.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - vec.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - vec.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z; - vec.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W; - return vec; - } - - /// - /// Clamp a vector to the given minimum and maximum vectors - /// - /// Input vector - /// Minimum vector - /// Maximum vector - /// The clamped vector - public static void Clamp(ref Vector4d vec, ref Vector4d min, ref Vector4d max, out Vector4d result) - { - result.X = vec.X < min.X ? min.X : vec.X > max.X ? max.X : vec.X; - result.Y = vec.Y < min.Y ? min.Y : vec.Y > max.Y ? max.Y : vec.Y; - result.Z = vec.X < min.Z ? min.Z : vec.Z > max.Z ? max.Z : vec.Z; - result.W = vec.Y < min.W ? min.W : vec.W > max.W ? max.W : vec.W; - } - - #endregion - - #region Normalize - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static Vector4d Normalize(Vector4d vec) - { - double scale = 1.0 / vec.Length; - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Scale a vector to unit length - /// - /// The input vector - /// The normalized vector - public static void Normalize(ref Vector4d vec, out Vector4d result) - { - double scale = 1.0 / vec.Length; - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - result.W = vec.W * scale; - } - - #endregion - - #region NormalizeFast - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static Vector4d NormalizeFast(Vector4d vec) - { - double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W); - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Scale a vector to approximately unit length - /// - /// The input vector - /// The normalized vector - public static void NormalizeFast(ref Vector4d vec, out Vector4d result) - { - double scale = MathHelper.InverseSqrtFast(vec.X * vec.X + vec.Y * vec.Y + vec.Z * vec.Z + vec.W * vec.W); - result.X = vec.X * scale; - result.Y = vec.Y * scale; - result.Z = vec.Z * scale; - result.W = vec.W * scale; - } - - #endregion - - #region Dot - - /// - /// Calculate the dot product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static double Dot(Vector4d left, Vector4d right) - { - return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W; - } - - /// - /// Calculate the dot product of two vectors - /// - /// First operand - /// Second operand - /// The dot product of the two inputs - public static void Dot(ref Vector4d left, ref Vector4d right, out double result) - { - result = left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W; - } - - #endregion - - #region Lerp - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static Vector4d Lerp(Vector4d a, Vector4d b, double blend) - { - a.X = blend * (b.X - a.X) + a.X; - a.Y = blend * (b.Y - a.Y) + a.Y; - a.Z = blend * (b.Z - a.Z) + a.Z; - a.W = blend * (b.W - a.W) + a.W; - return a; - } - - /// - /// Returns a new Vector that is the linear blend of the 2 given Vectors - /// - /// First input vector - /// Second input vector - /// The blend factor. a when blend=0, b when blend=1. - /// a when blend=0, b when blend=1, and a linear combination otherwise - public static void Lerp(ref Vector4d a, ref Vector4d b, double blend, out Vector4d result) - { - result.X = blend * (b.X - a.X) + a.X; - result.Y = blend * (b.Y - a.Y) + a.Y; - result.Z = blend * (b.Z - a.Z) + a.Z; - result.W = blend * (b.W - a.W) + a.W; - } - - #endregion - - #region Barycentric - - /// - /// Interpolate 3 Vectors using Barycentric coordinates - /// - /// First input Vector - /// Second input Vector - /// Third input Vector - /// First Barycentric Coordinate - /// Second Barycentric Coordinate - /// a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static Vector4d BaryCentric(Vector4d a, Vector4d b, Vector4d c, double u, double v) - { - return a + u * (b - a) + v * (c - a); - } - - /// Interpolate 3 Vectors using Barycentric coordinates - /// First input Vector. - /// Second input Vector. - /// Third input Vector. - /// First Barycentric Coordinate. - /// Second Barycentric Coordinate. - /// Output Vector. a when u=v=0, b when u=1,v=0, c when u=0,v=1, and a linear combination of a,b,c otherwise - public static void BaryCentric(ref Vector4d a, ref Vector4d b, ref Vector4d c, double u, double v, out Vector4d result) - { - result = a; // copy - - Vector4d temp = b; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, u, out temp); - Add(ref result, ref temp, out result); - - temp = c; // copy - Subtract(ref temp, ref a, out temp); - Multiply(ref temp, v, out temp); - Add(ref result, ref temp, out result); - } - - #endregion - - #region Transform - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static Vector4d Transform(Vector4d vec, Matrix4d mat) - { - Vector4d result; - Transform(ref vec, ref mat, out result); - return result; - } - - /// Transform a Vector by the given Matrix - /// The vector to transform - /// The desired transformation - /// The transformed vector - public static void Transform(ref Vector4d vec, ref Matrix4d mat, out Vector4d result) - { - result = new Vector4d( - vec.X * mat.Row0.X + vec.Y * mat.Row1.X + vec.Z * mat.Row2.X + vec.W * mat.Row3.X, - vec.X * mat.Row0.Y + vec.Y * mat.Row1.Y + vec.Z * mat.Row2.Y + vec.W * mat.Row3.Y, - vec.X * mat.Row0.Z + vec.Y * mat.Row1.Z + vec.Z * mat.Row2.Z + vec.W * mat.Row3.Z, - vec.X * mat.Row0.W + vec.Y * mat.Row1.W + vec.Z * mat.Row2.W + vec.W * mat.Row3.W); - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static Vector4d Transform(Vector4d vec, Quaterniond quat) - { - Vector4d result; - Transform(ref vec, ref quat, out result); - return result; - } - - /// - /// Transforms a vector by a quaternion rotation. - /// - /// The vector to transform. - /// The quaternion to rotate the vector by. - /// The result of the operation. - public static void Transform(ref Vector4d vec, ref Quaterniond quat, out Vector4d result) - { - Quaterniond v = new Quaterniond(vec.X, vec.Y, vec.Z, vec.W), i, t; - Quaterniond.Invert(ref quat, out i); - Quaterniond.Multiply(ref quat, ref v, out t); - Quaterniond.Multiply(ref t, ref i, out v); - - result = new Vector4d(v.X, v.Y, v.Z, v.W); - } - - #endregion - - #endregion - - #region Swizzle - - #region 2-component - - /// - /// Gets or sets an OpenTK.Vector2d with the X and Y components of this instance. - /// - [XmlIgnore] - public Vector2d Xy { get { return new Vector2d(X, Y); } set { X = value.X; Y = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the X and Z components of this instance. - /// - [XmlIgnore] - public Vector2d Xz { get { return new Vector2d(X, Z); } set { X = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the X and W components of this instance. - /// - [XmlIgnore] - public Vector2d Xw { get { return new Vector2d(X, W); } set { X = value.X; W = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the Y and X components of this instance. - /// - [XmlIgnore] - public Vector2d Yx { get { return new Vector2d(Y, X); } set { Y = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the Y and Z components of this instance. - /// - [XmlIgnore] - public Vector2d Yz { get { return new Vector2d(Y, Z); } set { Y = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the Y and W components of this instance. - /// - [XmlIgnore] - public Vector2d Yw { get { return new Vector2d(Y, W); } set { Y = value.X; W = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the Z and X components of this instance. - /// - [XmlIgnore] - public Vector2d Zx { get { return new Vector2d(Z, X); } set { Z = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the Z and Y components of this instance. - /// - [XmlIgnore] - public Vector2d Zy { get { return new Vector2d(Z, Y); } set { Z = value.X; Y = value.Y; } } - - /// - /// Gets an OpenTK.Vector2d with the Z and W components of this instance. - /// - [XmlIgnore] - public Vector2d Zw { get { return new Vector2d(Z, W); } set { Z = value.X; W = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the W and X components of this instance. - /// - [XmlIgnore] - public Vector2d Wx { get { return new Vector2d(W, X); } set { W = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the W and Y components of this instance. - /// - [XmlIgnore] - public Vector2d Wy { get { return new Vector2d(W, Y); } set { W = value.X; Y = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2d with the W and Z components of this instance. - /// - [XmlIgnore] - public Vector2d Wz { get { return new Vector2d(W, Z); } set { W = value.X; Z = value.Y; } } - - #endregion - - #region 3-component - - /// - /// Gets or sets an OpenTK.Vector3d with the X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector3d Xyz { get { return new Vector3d(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector3d Xyw { get { return new Vector3d(X, Y, W); } set { X = value.X; Y = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the X, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector3d Xzy { get { return new Vector3d(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the X, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector3d Xzw { get { return new Vector3d(X, Z, W); } set { X = value.X; Z = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the X, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector3d Xwy { get { return new Vector3d(X, W, Y); } set { X = value.X; W = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the X, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector3d Xwz { get { return new Vector3d(X, W, Z); } set { X = value.X; W = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Y, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector3d Yxz { get { return new Vector3d(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Y, X, and W components of this instance. - /// - [XmlIgnore] - public Vector3d Yxw { get { return new Vector3d(Y, X, W); } set { Y = value.X; X = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Y, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector3d Yzx { get { return new Vector3d(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Y, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector3d Yzw { get { return new Vector3d(Y, Z, W); } set { Y = value.X; Z = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Y, W, and X components of this instance. - /// - [XmlIgnore] - public Vector3d Ywx { get { return new Vector3d(Y, W, X); } set { Y = value.X; W = value.Y; X = value.Z; } } - - /// - /// Gets an OpenTK.Vector3d with the Y, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector3d Ywz { get { return new Vector3d(Y, W, Z); } set { Y = value.X; W = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Z, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector3d Zxy { get { return new Vector3d(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Z, X, and W components of this instance. - /// - [XmlIgnore] - public Vector3d Zxw { get { return new Vector3d(Z, X, W); } set { Z = value.X; X = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Z, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector3d Zyx { get { return new Vector3d(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Z, Y, and W components of this instance. - /// - [XmlIgnore] - public Vector3d Zyw { get { return new Vector3d(Z, Y, W); } set { Z = value.X; Y = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Z, W, and X components of this instance. - /// - [XmlIgnore] - public Vector3d Zwx { get { return new Vector3d(Z, W, X); } set { Z = value.X; W = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the Z, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector3d Zwy { get { return new Vector3d(Z, W, Y); } set { Z = value.X; W = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the W, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector3d Wxy { get { return new Vector3d(W, X, Y); } set { W = value.X; X = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the W, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector3d Wxz { get { return new Vector3d(W, X, Z); } set { W = value.X; X = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the W, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector3d Wyx { get { return new Vector3d(W, Y, X); } set { W = value.X; Y = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the W, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector3d Wyz { get { return new Vector3d(W, Y, Z); } set { W = value.X; Y = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the W, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector3d Wzx { get { return new Vector3d(W, Z, X); } set { W = value.X; Z = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3d with the W, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector3d Wzy { get { return new Vector3d(W, Z, Y); } set { W = value.X; Z = value.Y; Y = value.Z; } } - - #endregion - - #region 4-component - - /// - /// Gets or sets an OpenTK.Vector4d with the X, Y, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector4d Xywz { get { return new Vector4d(X, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the X, Z, Y, and W components of this instance. - /// - [XmlIgnore] - public Vector4d Xzyw { get { return new Vector4d(X, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the X, Z, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector4d Xzwy { get { return new Vector4d(X, Z, W, Y); } set { X = value.X; Z = value.Y; W = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the X, W, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector4d Xwyz { get { return new Vector4d(X, W, Y, Z); } set { X = value.X; W = value.Y; Y = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the X, W, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector4d Xwzy { get { return new Vector4d(X, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Y, X, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector4d Yxzw { get { return new Vector4d(Y, X, Z, W); } set { Y = value.X; X = value.Y; Z = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Y, X, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector4d Yxwz { get { return new Vector4d(Y, X, W, Z); } set { Y = value.X; X = value.Y; W = value.Z; Z = value.W; } } - - /// - /// Gets an OpenTK.Vector4d with the Y, Y, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector4d Yyzw { get { return new Vector4d(Y, Y, Z, W); } set { X = value.X; Y = value.Y; Z = value.Z; W = value.W; } } - - /// - /// Gets an OpenTK.Vector4d with the Y, Y, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector4d Yywz { get { return new Vector4d(Y, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Y, Z, X, and W components of this instance. - /// - [XmlIgnore] - public Vector4d Yzxw { get { return new Vector4d(Y, Z, X, W); } set { Y = value.X; Z = value.Y; X = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Y, Z, W, and X components of this instance. - /// - [XmlIgnore] - public Vector4d Yzwx { get { return new Vector4d(Y, Z, W, X); } set { Y = value.X; Z = value.Y; W = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Y, W, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector4d Ywxz { get { return new Vector4d(Y, W, X, Z); } set { Y = value.X; W = value.Y; X = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Y, W, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector4d Ywzx { get { return new Vector4d(Y, W, Z, X); } set { Y = value.X; W = value.Y; Z = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Z, X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector4d Zxyw { get { return new Vector4d(Z, X, Y, W); } set { Z = value.X; X = value.Y; Y = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Z, X, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector4d Zxwy { get { return new Vector4d(Z, X, W, Y); } set { Z = value.X; X = value.Y; W = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Z, Y, X, and W components of this instance. - /// - [XmlIgnore] - public Vector4d Zyxw { get { return new Vector4d(Z, Y, X, W); } set { Z = value.X; Y = value.Y; X = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Z, Y, W, and X components of this instance. - /// - [XmlIgnore] - public Vector4d Zywx { get { return new Vector4d(Z, Y, W, X); } set { Z = value.X; Y = value.Y; W = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Z, W, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector4d Zwxy { get { return new Vector4d(Z, W, X, Y); } set { Z = value.X; W = value.Y; X = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the Z, W, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector4d Zwyx { get { return new Vector4d(Z, W, Y, X); } set { Z = value.X; W = value.Y; Y = value.Z; X = value.W; } } - - /// - /// Gets an OpenTK.Vector4d with the Z, W, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector4d Zwzy { get { return new Vector4d(Z, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the W, X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector4d Wxyz { get { return new Vector4d(W, X, Y, Z); } set { W = value.X; X = value.Y; Y = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the W, X, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector4d Wxzy { get { return new Vector4d(W, X, Z, Y); } set { W = value.X; X = value.Y; Z = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the W, Y, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector4d Wyxz { get { return new Vector4d(W, Y, X, Z); } set { W = value.X; Y = value.Y; X = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the W, Y, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector4d Wyzx { get { return new Vector4d(W, Y, Z, X); } set { W = value.X; Y = value.Y; Z = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the W, Z, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector4d Wzxy { get { return new Vector4d(W, Z, X, Y); } set { W = value.X; Z = value.Y; X = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4d with the W, Z, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector4d Wzyx { get { return new Vector4d(W, Z, Y, X); } set { W = value.X; Z = value.Y; Y = value.Z; X = value.W; } } - - /// - /// Gets an OpenTK.Vector4d with the W, Z, Y, and W components of this instance. - /// - [XmlIgnore] - public Vector4d Wzyw { get { return new Vector4d(W, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } } - - #endregion - - #endregion - - #region Operators - - /// - /// Adds two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Vector4d operator +(Vector4d left, Vector4d right) - { - left.X += right.X; - left.Y += right.Y; - left.Z += right.Z; - left.W += right.W; - return left; - } - - /// - /// Subtracts two instances. - /// - /// The first instance. - /// The second instance. - /// The result of the calculation. - public static Vector4d operator -(Vector4d left, Vector4d right) - { - left.X -= right.X; - left.Y -= right.Y; - left.Z -= right.Z; - left.W -= right.W; - return left; - } - - /// - /// Negates an instance. - /// - /// The instance. - /// The result of the calculation. - public static Vector4d operator -(Vector4d vec) - { - vec.X = -vec.X; - vec.Y = -vec.Y; - vec.Z = -vec.Z; - vec.W = -vec.W; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - public static Vector4d operator *(Vector4d vec, double scale) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Multiplies an instance by a scalar. - /// - /// The scalar. - /// The instance. - /// The result of the calculation. - public static Vector4d operator *(double scale, Vector4d vec) - { - vec.X *= scale; - vec.Y *= scale; - vec.Z *= scale; - vec.W *= scale; - return vec; - } - - /// - /// Component-wise multiplication between the specified instance by a scale vector. - /// - /// Left operand. - /// Right operand. - /// Result of multiplication. - public static Vector4d operator *(Vector4d vec, Vector4d scale) - { - vec.X *= scale.X; - vec.Y *= scale.Y; - vec.Z *= scale.Z; - vec.W *= scale.W; - return vec; - } - - /// - /// Divides an instance by a scalar. - /// - /// The instance. - /// The scalar. - /// The result of the calculation. - public static Vector4d operator /(Vector4d vec, double scale) - { - double mult = 1 / scale; - vec.X *= mult; - vec.Y *= mult; - vec.Z *= mult; - vec.W *= mult; - return vec; - } - - /// - /// Compares two instances for equality. - /// - /// The first instance. - /// The second instance. - /// True, if left equals right; false otherwise. - public static bool operator ==(Vector4d left, Vector4d right) - { - return left.Equals(right); - } - - /// - /// Compares two instances for inequality. - /// - /// The first instance. - /// The second instance. - /// True, if left does not equa lright; false otherwise. - public static bool operator !=(Vector4d left, Vector4d right) - { - return !left.Equals(right); - } - - /// - /// Returns a pointer to the first element of the specified instance. - /// - /// The instance. - /// A pointer to the first element of v. - [CLSCompliant(false)] - unsafe public static explicit operator double*(Vector4d v) - { - return &v.X; - } - - /// - /// Returns a pointer to the first element of the specified instance. - /// - /// The instance. - /// A pointer to the first element of v. - public static explicit operator IntPtr(Vector4d v) - { - unsafe - { - return (IntPtr)(&v.X); - } - } - - /// Converts OpenTK.Vector4 to OpenTK.Vector4d. - /// The Vector4 to convert. - /// The resulting Vector4d. - public static explicit operator Vector4d(Vector4 v4) - { - return new Vector4d(v4.X, v4.Y, v4.Z, v4.W); - } - - /// Converts OpenTK.Vector4d to OpenTK.Vector4. - /// The Vector4d to convert. - /// The resulting Vector4. - public static explicit operator Vector4(Vector4d v4d) - { - return new Vector4((float)v4d.X, (float)v4d.Y, (float)v4d.Z, (float)v4d.W); - } - - #endregion - - #region Overrides - - #region public override string ToString() - - private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator; - /// - /// Returns a System.String that represents the current Vector4d. - /// - /// - public override string ToString() - { - return String.Format("({0}{4} {1}{4} {2}{4} {3})", X, Y, Z, W, listSeparator); - } - - #endregion - - #region public override int GetHashCode() - - /// - /// Returns the hashcode for this instance. - /// - /// A System.Int32 containing the unique hashcode for this instance. - public override int GetHashCode() - { - return X.GetHashCode() ^ Y.GetHashCode() ^ Z.GetHashCode() ^ W.GetHashCode(); - } - - #endregion - - #region public override bool Equals(object obj) - - /// - /// Indicates whether this instance and a specified object are equal. - /// - /// The object to compare to. - /// True if the instances are equal; false otherwise. - public override bool Equals(object obj) - { - if (!(obj is Vector4d)) - return false; - - return this.Equals((Vector4d)obj); - } - - #endregion - - #endregion - - #endregion - - #region IEquatable Members - - /// Indicates whether the current vector is equal to another vector. - /// A vector to compare with this vector. - /// true if the current vector is equal to the vector parameter; otherwise, false. - public bool Equals(Vector4d other) - { - return - X == other.X && - Y == other.Y && - Z == other.Z && - W == other.W; - } - - #endregion - } -} \ No newline at end of file diff --git a/OpenTK/Math/Vector4h.cs b/OpenTK/Math/Vector4h.cs deleted file mode 100644 index d9499f73..00000000 --- a/OpenTK/Math/Vector4h.cs +++ /dev/null @@ -1,819 +0,0 @@ -#region --- License --- -/* -Copyright (c) 2006 - 2008 The Open Toolkit library. - -Permission is hereby granted, free of charge, to any person obtaining a copy of -this software and associated documentation files (the "Software"), to deal in -the Software without restriction, including without limitation the rights to -use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -of the Software, and to permit persons to whom the Software is furnished to do -so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -#endregion - -using System; -using System.IO; -using System.Runtime.InteropServices; -using System.Runtime.Serialization; -using System.Xml.Serialization; - -namespace OpenTK -{ - /// - /// 4-component Vector of the Half type. Occupies 8 Byte total. - /// - [Serializable, StructLayout(LayoutKind.Sequential)] - public struct Vector4h : ISerializable, IEquatable - { - #region Public Fields - - /// The X component of the Half4. - public Half X; - - /// The Y component of the Half4. - public Half Y; - - /// The Z component of the Half4. - public Half Z; - - /// The W component of the Half4. - public Half W; - - #endregion Public Fields - - #region Constructors - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector4h(Half value) - { - X = value; - Y = value; - Z = value; - W = value; - } - - /// - /// Constructs a new instance. - /// - /// The value that will initialize this instance. - public Vector4h(Single value) - { - X = new Half(value); - Y = new Half(value); - Z = new Half(value); - W = new Half(value); - } - - /// - /// The new Half4 instance will avoid conversion and copy directly from the Half parameters. - /// - /// An Half instance of a 16-bit half-precision floating-point number. - /// An Half instance of a 16-bit half-precision floating-point number. - /// An Half instance of a 16-bit half-precision floating-point number. - /// An Half instance of a 16-bit half-precision floating-point number. - public Vector4h(Half x, Half y, Half z, Half w) - { - this.X = x; - this.Y = y; - this.Z = z; - this.W = w; - } - - /// - /// The new Half4 instance will convert the 4 parameters into 16-bit half-precision floating-point. - /// - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - public Vector4h(Single x, Single y, Single z, Single w) - { - X = new Half(x); - Y = new Half(y); - Z = new Half(z); - W = new Half(w); - } - - /// - /// The new Half4 instance will convert the 4 parameters into 16-bit half-precision floating-point. - /// - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - /// 32-bit single-precision floating-point number. - /// Enable checks that will throw if the conversion result is not meaningful. - public Vector4h(Single x, Single y, Single z, Single w, bool throwOnError) - { - X = new Half(x, throwOnError); - Y = new Half(y, throwOnError); - Z = new Half(z, throwOnError); - W = new Half(w, throwOnError); - } - - /// - /// The new Half4 instance will convert the Vector4 into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector4 - [CLSCompliant(false)] - public Vector4h(Vector4 v) - { - X = new Half(v.X); - Y = new Half(v.Y); - Z = new Half(v.Z); - W = new Half(v.W); - } - - /// - /// The new Half4 instance will convert the Vector4 into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector4 - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector4h(Vector4 v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - Z = new Half(v.Z, throwOnError); - W = new Half(v.W, throwOnError); - } - - /// - /// The new Half4 instance will convert the Vector4 into 16-bit half-precision floating-point. - /// This is the fastest constructor. - /// - /// OpenTK.Vector4 - public Vector4h(ref Vector4 v) - { - X = new Half(v.X); - Y = new Half(v.Y); - Z = new Half(v.Z); - W = new Half(v.W); - } - - /// - /// The new Half4 instance will convert the Vector4 into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector4 - /// Enable checks that will throw if the conversion result is not meaningful. - public Vector4h(ref Vector4 v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - Z = new Half(v.Z, throwOnError); - W = new Half(v.W, throwOnError); - } - - /// - /// The new Half4 instance will convert the Vector4d into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector4d - [CLSCompliant(false)] - public Vector4h(Vector4d v) - { - X = new Half(v.X); - Y = new Half(v.Y); - Z = new Half(v.Z); - W = new Half(v.W); - } - - /// - /// The new Half4 instance will convert the Vector4d into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector4d - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector4h(Vector4d v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - Z = new Half(v.Z, throwOnError); - W = new Half(v.W, throwOnError); - } - - /// - /// The new Half4 instance will convert the Vector4d into 16-bit half-precision floating-point. - /// This is the faster constructor. - /// - /// OpenTK.Vector4d - [CLSCompliant(false)] - public Vector4h(ref Vector4d v) - { - X = new Half(v.X); - Y = new Half(v.Y); - Z = new Half(v.Z); - W = new Half(v.W); - } - - /// - /// The new Half4 instance will convert the Vector4d into 16-bit half-precision floating-point. - /// - /// OpenTK.Vector4d - /// Enable checks that will throw if the conversion result is not meaningful. - [CLSCompliant(false)] - public Vector4h(ref Vector4d v, bool throwOnError) - { - X = new Half(v.X, throwOnError); - Y = new Half(v.Y, throwOnError); - Z = new Half(v.Z, throwOnError); - W = new Half(v.W, throwOnError); - } - - #endregion Constructors - - #region Swizzle - - #region 2-component - - /// - /// Gets or sets an OpenTK.Vector2h with the X and Y components of this instance. - /// - [XmlIgnore] - public Vector2h Xy { get { return new Vector2h(X, Y); } set { X = value.X; Y = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the X and Z components of this instance. - /// - [XmlIgnore] - public Vector2h Xz { get { return new Vector2h(X, Z); } set { X = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the X and W components of this instance. - /// - [XmlIgnore] - public Vector2h Xw { get { return new Vector2h(X, W); } set { X = value.X; W = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the Y and X components of this instance. - /// - [XmlIgnore] - public Vector2h Yx { get { return new Vector2h(Y, X); } set { Y = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the Y and Z components of this instance. - /// - [XmlIgnore] - public Vector2h Yz { get { return new Vector2h(Y, Z); } set { Y = value.X; Z = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the Y and W components of this instance. - /// - [XmlIgnore] - public Vector2h Yw { get { return new Vector2h(Y, W); } set { Y = value.X; W = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the Z and X components of this instance. - /// - [XmlIgnore] - public Vector2h Zx { get { return new Vector2h(Z, X); } set { Z = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the Z and Y components of this instance. - /// - [XmlIgnore] - public Vector2h Zy { get { return new Vector2h(Z, Y); } set { Z = value.X; Y = value.Y; } } - - /// - /// Gets an OpenTK.Vector2h with the Z and W components of this instance. - /// - [XmlIgnore] - public Vector2h Zw { get { return new Vector2h(Z, W); } set { Z = value.X; W = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the W and X components of this instance. - /// - [XmlIgnore] - public Vector2h Wx { get { return new Vector2h(W, X); } set { W = value.X; X = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the W and Y components of this instance. - /// - [XmlIgnore] - public Vector2h Wy { get { return new Vector2h(W, Y); } set { W = value.X; Y = value.Y; } } - - /// - /// Gets or sets an OpenTK.Vector2h with the W and Z components of this instance. - /// - [XmlIgnore] - public Vector2h Wz { get { return new Vector2h(W, Z); } set { W = value.X; Z = value.Y; } } - - #endregion - - #region 3-component - - /// - /// Gets or sets an OpenTK.Vector3h with the X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector3h Xyz { get { return new Vector3h(X, Y, Z); } set { X = value.X; Y = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector3h Xyw { get { return new Vector3h(X, Y, W); } set { X = value.X; Y = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the X, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector3h Xzy { get { return new Vector3h(X, Z, Y); } set { X = value.X; Z = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the X, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector3h Xzw { get { return new Vector3h(X, Z, W); } set { X = value.X; Z = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the X, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector3h Xwy { get { return new Vector3h(X, W, Y); } set { X = value.X; W = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the X, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector3h Xwz { get { return new Vector3h(X, W, Z); } set { X = value.X; W = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Y, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector3h Yxz { get { return new Vector3h(Y, X, Z); } set { Y = value.X; X = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Y, X, and W components of this instance. - /// - [XmlIgnore] - public Vector3h Yxw { get { return new Vector3h(Y, X, W); } set { Y = value.X; X = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Y, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector3h Yzx { get { return new Vector3h(Y, Z, X); } set { Y = value.X; Z = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Y, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector3h Yzw { get { return new Vector3h(Y, Z, W); } set { Y = value.X; Z = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Y, W, and X components of this instance. - /// - [XmlIgnore] - public Vector3h Ywx { get { return new Vector3h(Y, W, X); } set { Y = value.X; W = value.Y; X = value.Z; } } - - /// - /// Gets an OpenTK.Vector3h with the Y, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector3h Ywz { get { return new Vector3h(Y, W, Z); } set { Y = value.X; W = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Z, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector3h Zxy { get { return new Vector3h(Z, X, Y); } set { Z = value.X; X = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Z, X, and W components of this instance. - /// - [XmlIgnore] - public Vector3h Zxw { get { return new Vector3h(Z, X, W); } set { Z = value.X; X = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Z, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector3h Zyx { get { return new Vector3h(Z, Y, X); } set { Z = value.X; Y = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Z, Y, and W components of this instance. - /// - [XmlIgnore] - public Vector3h Zyw { get { return new Vector3h(Z, Y, W); } set { Z = value.X; Y = value.Y; W = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Z, W, and X components of this instance. - /// - [XmlIgnore] - public Vector3h Zwx { get { return new Vector3h(Z, W, X); } set { Z = value.X; W = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the Z, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector3h Zwy { get { return new Vector3h(Z, W, Y); } set { Z = value.X; W = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the W, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector3h Wxy { get { return new Vector3h(W, X, Y); } set { W = value.X; X = value.Y; Y = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the W, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector3h Wxz { get { return new Vector3h(W, X, Z); } set { W = value.X; X = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the W, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector3h Wyx { get { return new Vector3h(W, Y, X); } set { W = value.X; Y = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the W, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector3h Wyz { get { return new Vector3h(W, Y, Z); } set { W = value.X; Y = value.Y; Z = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the W, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector3h Wzx { get { return new Vector3h(W, Z, X); } set { W = value.X; Z = value.Y; X = value.Z; } } - - /// - /// Gets or sets an OpenTK.Vector3h with the W, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector3h Wzy { get { return new Vector3h(W, Z, Y); } set { W = value.X; Z = value.Y; Y = value.Z; } } - - #endregion - - #region 4-component - - /// - /// Gets or sets an OpenTK.Vector4h with the X, Y, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector4h Xywz { get { return new Vector4h(X, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the X, Z, Y, and W components of this instance. - /// - [XmlIgnore] - public Vector4h Xzyw { get { return new Vector4h(X, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the X, Z, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector4h Xzwy { get { return new Vector4h(X, Z, W, Y); } set { X = value.X; Z = value.Y; W = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the X, W, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector4h Xwyz { get { return new Vector4h(X, W, Y, Z); } set { X = value.X; W = value.Y; Y = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the X, W, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector4h Xwzy { get { return new Vector4h(X, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Y, X, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector4h Yxzw { get { return new Vector4h(Y, X, Z, W); } set { Y = value.X; X = value.Y; Z = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Y, X, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector4h Yxwz { get { return new Vector4h(Y, X, W, Z); } set { Y = value.X; X = value.Y; W = value.Z; Z = value.W; } } - - /// - /// Gets an OpenTK.Vector4h with the Y, Y, Z, and W components of this instance. - /// - [XmlIgnore] - public Vector4h Yyzw { get { return new Vector4h(Y, Y, Z, W); } set { X = value.X; Y = value.Y; Z = value.Z; W = value.W; } } - - /// - /// Gets an OpenTK.Vector4h with the Y, Y, W, and Z components of this instance. - /// - [XmlIgnore] - public Vector4h Yywz { get { return new Vector4h(Y, Y, W, Z); } set { X = value.X; Y = value.Y; W = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Y, Z, X, and W components of this instance. - /// - [XmlIgnore] - public Vector4h Yzxw { get { return new Vector4h(Y, Z, X, W); } set { Y = value.X; Z = value.Y; X = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Y, Z, W, and X components of this instance. - /// - [XmlIgnore] - public Vector4h Yzwx { get { return new Vector4h(Y, Z, W, X); } set { Y = value.X; Z = value.Y; W = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Y, W, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector4h Ywxz { get { return new Vector4h(Y, W, X, Z); } set { Y = value.X; W = value.Y; X = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Y, W, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector4h Ywzx { get { return new Vector4h(Y, W, Z, X); } set { Y = value.X; W = value.Y; Z = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Z, X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector4h Zxyw { get { return new Vector4h(Z, X, Y, W); } set { Z = value.X; X = value.Y; Y = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Z, X, W, and Y components of this instance. - /// - [XmlIgnore] - public Vector4h Zxwy { get { return new Vector4h(Z, X, W, Y); } set { Z = value.X; X = value.Y; W = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Z, Y, X, and W components of this instance. - /// - [XmlIgnore] - public Vector4h Zyxw { get { return new Vector4h(Z, Y, X, W); } set { Z = value.X; Y = value.Y; X = value.Z; W = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Z, Y, W, and X components of this instance. - /// - [XmlIgnore] - public Vector4h Zywx { get { return new Vector4h(Z, Y, W, X); } set { Z = value.X; Y = value.Y; W = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Z, W, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector4h Zwxy { get { return new Vector4h(Z, W, X, Y); } set { Z = value.X; W = value.Y; X = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the Z, W, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector4h Zwyx { get { return new Vector4h(Z, W, Y, X); } set { Z = value.X; W = value.Y; Y = value.Z; X = value.W; } } - - /// - /// Gets an OpenTK.Vector4h with the Z, W, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector4h Zwzy { get { return new Vector4h(Z, W, Z, Y); } set { X = value.X; W = value.Y; Z = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the W, X, Y, and Z components of this instance. - /// - [XmlIgnore] - public Vector4h Wxyz { get { return new Vector4h(W, X, Y, Z); } set { W = value.X; X = value.Y; Y = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the W, X, Z, and Y components of this instance. - /// - [XmlIgnore] - public Vector4h Wxzy { get { return new Vector4h(W, X, Z, Y); } set { W = value.X; X = value.Y; Z = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the W, Y, X, and Z components of this instance. - /// - [XmlIgnore] - public Vector4h Wyxz { get { return new Vector4h(W, Y, X, Z); } set { W = value.X; Y = value.Y; X = value.Z; Z = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the W, Y, Z, and X components of this instance. - /// - [XmlIgnore] - public Vector4h Wyzx { get { return new Vector4h(W, Y, Z, X); } set { W = value.X; Y = value.Y; Z = value.Z; X = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the W, Z, X, and Y components of this instance. - /// - [XmlIgnore] - public Vector4h Wzxy { get { return new Vector4h(W, Z, X, Y); } set { W = value.X; Z = value.Y; X = value.Z; Y = value.W; } } - - /// - /// Gets or sets an OpenTK.Vector4h with the W, Z, Y, and X components of this instance. - /// - [XmlIgnore] - public Vector4h Wzyx { get { return new Vector4h(W, Z, Y, X); } set { W = value.X; Z = value.Y; Y = value.Z; X = value.W; } } - - /// - /// Gets an OpenTK.Vector4h with the W, Z, Y, and W components of this instance. - /// - [XmlIgnore] - public Vector4h Wzyw { get { return new Vector4h(W, Z, Y, W); } set { X = value.X; Z = value.Y; Y = value.Z; W = value.W; } } - - #endregion - - #endregion - - #region Half -> Single - - /// - /// Returns this Half4 instance's contents as Vector4. - /// - /// OpenTK.Vector4 - public Vector4 ToVector4() - { - return new Vector4(X, Y, Z, W); - } - - /// - /// Returns this Half4 instance's contents as Vector4d. - /// - public Vector4d ToVector4d() - { - return new Vector4d(X, Y, Z, W); - } - - #endregion Half -> Single - - #region Conversions - - /// Converts OpenTK.Vector4 to OpenTK.Half4. - /// The Vector4 to convert. - /// The resulting Half vector. - public static explicit operator Vector4h(Vector4 v4f) - { - return new Vector4h(v4f); - } - - /// Converts OpenTK.Vector4d to OpenTK.Half4. - /// The Vector4d to convert. - /// The resulting Half vector. - public static explicit operator Vector4h(Vector4d v4d) - { - return new Vector4h(v4d); - } - - /// Converts OpenTK.Half4 to OpenTK.Vector4. - /// The Half4 to convert. - /// The resulting Vector4. - public static explicit operator Vector4(Vector4h h4) - { - Vector4 result = new Vector4(); - result.X = h4.X.ToSingle(); - result.Y = h4.Y.ToSingle(); - result.Z = h4.Z.ToSingle(); - result.W = h4.W.ToSingle(); - return result; - } - - /// Converts OpenTK.Half4 to OpenTK.Vector4d. - /// The Half4 to convert. - /// The resulting Vector4d. - public static explicit operator Vector4d(Vector4h h4) - { - Vector4d result = new Vector4d(); - result.X = h4.X.ToSingle(); - result.Y = h4.Y.ToSingle(); - result.Z = h4.Z.ToSingle(); - result.W = h4.W.ToSingle(); - return result; - } - - #endregion Conversions - - #region Constants - - /// The size in bytes for an instance of the Half4 struct is 8. - public static readonly int SizeInBytes = 8; - - #endregion Constants - - #region ISerializable - - /// Constructor used by ISerializable to deserialize the object. - /// - /// - public Vector4h(SerializationInfo info, StreamingContext context) - { - this.X = (Half)info.GetValue("X", typeof(Half)); - this.Y = (Half)info.GetValue("Y", typeof(Half)); - this.Z = (Half)info.GetValue("Z", typeof(Half)); - this.W = (Half)info.GetValue("W", typeof(Half)); - } - - /// Used by ISerialize to serialize the object. - /// - /// - public void GetObjectData(SerializationInfo info, StreamingContext context) - { - info.AddValue("X", this.X); - info.AddValue("Y", this.Y); - info.AddValue("Z", this.Z); - info.AddValue("W", this.W); - } - - #endregion ISerializable - - #region Binary dump - - /// Updates the X,Y,Z and W components of this instance by reading from a Stream. - /// A BinaryReader instance associated with an open Stream. - public void FromBinaryStream(BinaryReader bin) - { - X.FromBinaryStream(bin); - Y.FromBinaryStream(bin); - Z.FromBinaryStream(bin); - W.FromBinaryStream(bin); - } - - /// Writes the X,Y,Z and W components of this instance into a Stream. - /// A BinaryWriter instance associated with an open Stream. - public void ToBinaryStream(BinaryWriter bin) - { - X.ToBinaryStream(bin); - Y.ToBinaryStream(bin); - Z.ToBinaryStream(bin); - W.ToBinaryStream(bin); - } - - #endregion Binary dump - - #region IEquatable Members - - /// Returns a value indicating whether this instance is equal to a specified OpenTK.Half4 vector. - /// OpenTK.Half4 to compare to this instance.. - /// True, if other is equal to this instance; false otherwise. - public bool Equals(Vector4h other) - { - return (this.X.Equals(other.X) && this.Y.Equals(other.Y) && this.Z.Equals(other.Z) && this.W.Equals(other.W)); - } - - #endregion - - #region ToString() - - private static string listSeparator = System.Globalization.CultureInfo.CurrentCulture.TextInfo.ListSeparator; - /// Returns a string that contains this Half4's numbers in human-legible form. - public override string ToString() - { - return String.Format("({0}{4} {1}{4} {2}{4} {3})", X.ToString(), Y.ToString(), Z.ToString(), W.ToString(), listSeparator); - } - - #endregion ToString() - - #region BitConverter - - /// Returns the Half4 as an array of bytes. - /// The Half4 to convert. - /// The input as byte array. - public static byte[] GetBytes(Vector4h h) - { - byte[] result = new byte[SizeInBytes]; - - byte[] temp = Half.GetBytes(h.X); - result[0] = temp[0]; - result[1] = temp[1]; - temp = Half.GetBytes(h.Y); - result[2] = temp[0]; - result[3] = temp[1]; - temp = Half.GetBytes(h.Z); - result[4] = temp[0]; - result[5] = temp[1]; - temp = Half.GetBytes(h.W); - result[6] = temp[0]; - result[7] = temp[1]; - - return result; - } - - /// Converts an array of bytes into Half4. - /// A Half4 in it's byte[] representation. - /// The starting position within value. - /// A new Half4 instance. - public static Vector4h FromBytes(byte[] value, int startIndex) - { - Vector4h h4 = new Vector4h(); - h4.X = Half.FromBytes(value, startIndex); - h4.Y = Half.FromBytes(value, startIndex + 2); - h4.Z = Half.FromBytes(value, startIndex + 4); - h4.W = Half.FromBytes(value, startIndex + 6); - return h4; - } - - #endregion BitConverter - } -} diff --git a/OpenTK/OpenTK.csproj b/OpenTK/OpenTK.csproj deleted file mode 100644 index 3334c66a..00000000 --- a/OpenTK/OpenTK.csproj +++ /dev/null @@ -1,107 +0,0 @@ - - - - - Debug - AnyCPU - {ABB9DB44-14F2-46E0-A4B8-B46C300CA982} - Library - Properties - OpenTK - OpenTK - v4.7.2 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - true - false - x64 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - true - x64 - false - - - bin\Editor Debug\ - TRACE - true - true - pdbonly - x86 - prompt - MinimumRecommendedRules.ruleset - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/OpenTK/Properties/AssemblyInfo.cs b/OpenTK/Properties/AssemblyInfo.cs deleted file mode 100644 index a9b6bba5..00000000 --- a/OpenTK/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; -using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("OpenTK")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("OpenTK")] -[assembly: AssemblyCopyright("Copyright © 2014")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// Setting ComVisible to false makes the types in this assembly not visible -// to COM components. If you need to access a type in this assembly from -// COM, set the ComVisible attribute to true on that type. -[assembly: ComVisible(false)] - -// The following GUID is for the ID of the typelib if this project is exposed to COM -[assembly: Guid("dddb367c-9590-4d8a-8bb1-a32446164876")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/RconClient/Properties/AssemblyInfo.cs b/RconClient/Properties/AssemblyInfo.cs index 3031906d..1aa987b1 100644 --- a/RconClient/Properties/AssemblyInfo.cs +++ b/RconClient/Properties/AssemblyInfo.cs @@ -1,16 +1,6 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("RCON Client")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LSLib")] -[assembly: AssemblyCopyright("Copyright © Norbyte 2012-2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -21,16 +11,3 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("ef82c289-53d6-41c8-b5c3-72b37655c7f3")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/RconClient/RconClient.csproj b/RconClient/RconClient.csproj index df482ba7..cc0917a7 100644 --- a/RconClient/RconClient.csproj +++ b/RconClient/RconClient.csproj @@ -1,65 +1,17 @@ - - - + - Debug - AnyCPU - {EF82C289-53D6-41C8-B5C3-72B37655C7F3} + net8.0 Exe - Properties LSLib.Rcon - RconClient - v4.7.2 - 512 - - - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - x64 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false + false x64 + RCON Client + LSLib + Copyright © Norbyte 2012-2018 + 1.0.0.0 + 1.0.0.0 - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/StatParser/Properties/AssemblyInfo.cs b/StatParser/Properties/AssemblyInfo.cs index 3e731079..5b733744 100644 --- a/StatParser/Properties/AssemblyInfo.cs +++ b/StatParser/Properties/AssemblyInfo.cs @@ -1,16 +1,6 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("StatParser")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("StatParser")] -[assembly: AssemblyCopyright("Copyright © 2019")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -21,16 +11,3 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("94d900d1-ec77-4170-8942-56e3736e44de")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/StatParser/StatParser.csproj b/StatParser/StatParser.csproj index 8e6833af..f0bb54f1 100644 --- a/StatParser/StatParser.csproj +++ b/StatParser/StatParser.csproj @@ -1,67 +1,19 @@ - - - + - Debug - AnyCPU - {94D900D1-EC77-4170-8942-56E3736E44DE} + net8.0 Exe - StatParser - StatParser - v4.7.2 - 512 - true - true - - - x64 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - + false x64 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false + StatParser + StatParser + Copyright © 2019 + 1.0.0.0 + 1.0.0.0 - - ..\packages\CommandLineArgumentsParser.3.0.20\lib\net452\CommandLineArgumentsParser.dll - - - - - - - - - - - - - - - - - - - + - - {46372C50-4288-4B8E-AF21-C934560600E0} - LSLib - + - \ No newline at end of file diff --git a/StatParser/packages.config b/StatParser/packages.config deleted file mode 100644 index e9cd0fb2..00000000 --- a/StatParser/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/StoryCompiler/DebugInfoSaver.cs b/StoryCompiler/DebugInfoSaver.cs index 39ad1a50..1ece6b7c 100644 --- a/StoryCompiler/DebugInfoSaver.cs +++ b/StoryCompiler/DebugInfoSaver.cs @@ -192,7 +192,7 @@ public void Save(Stream stream, StoryDebugInfo debugInfo) codedStream.Flush(); byte[] proto = ms.ToArray(); - byte flags = BinUtils.MakeCompressionFlags(LSLib.LS.Enums.CompressionMethod.LZ4, LSLib.LS.Enums.CompressionLevel.FastCompression); + byte flags = BinUtils.MakeCompressionFlags(LSLib.LS.Enums.CompressionMethod.LZ4, LSLib.LS.Enums.LSCompressionLevel.FastCompression); byte[] compressed = BinUtils.Compress(proto, flags); stream.Write(compressed, 0, compressed.Length); diff --git a/StoryCompiler/Properties/AssemblyInfo.cs b/StoryCompiler/Properties/AssemblyInfo.cs index 1a14f3f6..6f2ae9c8 100644 --- a/StoryCompiler/Properties/AssemblyInfo.cs +++ b/StoryCompiler/Properties/AssemblyInfo.cs @@ -1,16 +1,6 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Osiris Story Compiler")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LSLib")] -[assembly: AssemblyCopyright("Copyright © Norbyte 2012-2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -21,16 +11,3 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("32f08b9a-f50b-4c2e-ab56-533fed066dde")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/StoryCompiler/StoryCompiler.csproj b/StoryCompiler/StoryCompiler.csproj index e525bcc6..6cedeb7d 100644 --- a/StoryCompiler/StoryCompiler.csproj +++ b/StoryCompiler/StoryCompiler.csproj @@ -1,17 +1,8 @@ - - - + - Debug - AnyCPU - {32F08B9A-F50B-4C2E-AB56-533FED066DDE} + net8.0 Exe LSTools.StoryCompiler - StoryCompiler - v4.7.2 - 512 - true - false publish\ true @@ -27,70 +18,14 @@ 1.0.0.%2a false true - - - x64 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - + false x64 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false - - ..\packages\CommandLineArgumentsParser.3.0.19\lib\net452\CommandLineArgumentsParser.dll - - - ..\packages\Google.Protobuf.3.6.1\lib\net45\Google.Protobuf.dll - - - ..\packages\Newtonsoft.Json.13.0.1\lib\net45\Newtonsoft.Json.dll - - - - - - - - - - - - - + - - - - - - - - - - - - - - - - {46372c50-4288-4b8e-af21-c934560600e0} - LSLib - + @@ -104,8 +39,23 @@ false - + + + + + all + runtime; build; native; contentfiles; analyzers; buildtransitive + + + + + + - $(SolutionDir)\External\protoc\bin\protoc.exe --proto_path=$(ProjectDir) --csharp_out=$(ProjectDir) debuginfo.proto + Osiris Story Compiler + LSLib + Copyright © Norbyte 2012-2018 + 1.0.0.0 + 1.0.0.0 \ No newline at end of file diff --git a/StoryCompiler/packages.config b/StoryCompiler/packages.config deleted file mode 100644 index 623d717c..00000000 --- a/StoryCompiler/packages.config +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/StoryDecompiler/Properties/AssemblyInfo.cs b/StoryDecompiler/Properties/AssemblyInfo.cs index 44a53ac6..a8317ca3 100644 --- a/StoryDecompiler/Properties/AssemblyInfo.cs +++ b/StoryDecompiler/Properties/AssemblyInfo.cs @@ -1,16 +1,6 @@ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; - -// General Information about an assembly is controlled through the following -// set of attributes. Change these attribute values to modify the information -// associated with an assembly. -[assembly: AssemblyTitle("Osiris Story Decompiler")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("LSLib")] -[assembly: AssemblyCopyright("Copyright © Norbyte 2012-2018")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] @@ -21,16 +11,3 @@ // The following GUID is for the ID of the typelib if this project is exposed to COM [assembly: Guid("e4b4f95e-f027-44d7-ab93-b96ef2e661b6")] - -// Version information for an assembly consists of the following four values: -// -// Major Version -// Minor Version -// Build Number -// Revision -// -// You can specify all the values or you can default the Build and Revision Numbers -// by using the '*' as shown below: -// [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("1.0.0.0")] -[assembly: AssemblyFileVersion("1.0.0.0")] diff --git a/StoryDecompiler/StoryDecompiler.csproj b/StoryDecompiler/StoryDecompiler.csproj index 266960fa..eb7b59c6 100644 --- a/StoryDecompiler/StoryDecompiler.csproj +++ b/StoryDecompiler/StoryDecompiler.csproj @@ -1,70 +1,19 @@ - - - + - Debug - AnyCPU - {E4B4F95E-F027-44D7-AB93-B96EF2E661B6} + net8.0 Exe - StoryDecompiler - StoryDecompiler - v4.7.2 - 512 - true - - - - x64 - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - false - - + false x64 - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - false + Osiris Story Decompiler + LSLib + Copyright © Norbyte 2012-2018 + 1.0.0.0 + 1.0.0.0 - - ..\packages\CommandLineArgumentsParser.3.0.19\lib\net452\CommandLineArgumentsParser.dll - - - - - - - - - - - - - - - - - - - - - - + - - {46372c50-4288-4b8e-af21-c934560600e0} - LSLib - + - \ No newline at end of file diff --git a/StoryDecompiler/packages.config b/StoryDecompiler/packages.config deleted file mode 100644 index 312644b4..00000000 --- a/StoryDecompiler/packages.config +++ /dev/null @@ -1,4 +0,0 @@ - - - - \ No newline at end of file diff --git a/TerrainFixup/Program.cs b/TerrainFixup/Program.cs deleted file mode 100644 index 9cbab7c6..00000000 --- a/TerrainFixup/Program.cs +++ /dev/null @@ -1,307 +0,0 @@ -using LSLib.LS; -using OpenTK; -using System; -using System.Collections.Generic; -using System.IO; -using System.Runtime.InteropServices; - -namespace TerrainFixup -{ - [StructLayout(LayoutKind.Sequential)] - public struct TerrainPatchHeader - { - [MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)] - public byte[] Signature; // PVersion - - public UInt32 Version; - } - - public class TerrainPatchLayer - { - public int Index; - public int[] Data; - public byte[] Data2; - } - - public class TerrainPatch - { - public string Path; - public TerrainPatchHeader Header; - public int X; - public int Y; - public int Width; - public int Height; - public float[] Heightmap; - public Vector2d[] Vertices; - public int[] Indices; - public int PatchIndex; - public TerrainPatchLayer[] Layers; - } - - public class Terrain - { - public string Directory; - public string GUID; - public int Width; - public int Height; - public int CellsX; - public int CellsY; - public int PatchesX; - public int PatchesY; - public int NumPatches; - public TerrainPatch[] Patches; - } - - class Program - { - static void Main(string[] args) - { - if (args.Length < 2 || args.Length > 3) - { - Console.WriteLine("Usage: TerrainFixup []"); - return; - } - - Console.WriteLine($"Loading terrains from {args[1]} ..."); - var terrains = new Dictionary(); - LoadTerrainsFromPath(args[0], args[1], terrains); - - var referenceTerrains = new Dictionary(); - if (args.Length > 2) - { - Console.WriteLine($"Loading reference terrains from {args[2]} ..."); - LoadTerrainsFromPath(args[0], args[2], referenceTerrains); - } - - Console.WriteLine($"Updating terrain meshes ..."); - foreach (var terrain in terrains) - { - Terrain refTerrain = null; - referenceTerrains.TryGetValue(terrain.Key, out refTerrain); - PatchTerrain(terrain.Value, refTerrain); - } - - Console.WriteLine($"Updating patches ..."); - foreach (var terrain in terrains) - { - SaveTerrainPatches(terrain.Value); - } - } - - private static void PatchTerrain(Terrain terrain, Terrain refTerrain) - { - if (refTerrain != null) - { - if (refTerrain.CellsX == terrain.CellsX && refTerrain.CellsY == terrain.CellsY) - { - Console.WriteLine($"Patching reference data to terrain {terrain.GUID}."); - for (var i = 0; i < terrain.Patches.Length; i++) - { - Console.WriteLine($"Patch {i}: {refTerrain.Patches[i].Indices.Length} inds, {refTerrain.Patches[i].Vertices.Length} verts"); - terrain.Patches[i].Indices = refTerrain.Patches[i].Indices; - terrain.Patches[i].Vertices = refTerrain.Patches[i].Vertices; - } - - return; - } - else - { - Console.WriteLine($"Terrain {terrain.GUID} patch size differs; couldnt apply ref mesh."); - } - } - - Console.WriteLine($"Terrain {terrain.GUID} has no reference data, clearing vertex buffers."); - foreach (var patch in terrain.Patches) - { - patch.Indices = new int[0]; - patch.Vertices = new Vector2d[0]; - } - } - - private static void LoadTerrainsFromPath(string path, string patchDir, Dictionary terrains) - { - foreach (var lsfPath in Directory.GetFiles(path, "*.lsf")) - { - LoadTerrainsFromLSF(lsfPath, patchDir, terrains); - } - } - - private static void LoadTerrainsFromLSF(string path, string patchDir, Dictionary terrains) - { - var loadParams = ResourceLoadParameters.FromGameVersion(LSLib.LS.Enums.Game.DivinityOriginalSin2DE); - var terrainRes = ResourceUtils.LoadResource(path, loadParams); - var tmpls = terrainRes.Regions["Templates"]; - if (tmpls.Children.TryGetValue("GameObjects", out List terrainTemplates)) - { - foreach (var tmpl in terrainTemplates) - { - var terrain = LoadTerrainFromNode(patchDir, tmpl); - terrain.Directory = patchDir; - terrains.Add(terrain.GUID, terrain); - } - } - } - - private static Terrain LoadTerrainFromNode(string dir, Node node) - { - var terrain = new Terrain(); - terrain.GUID = (string)node.Attributes["MapKey"].Value; - terrain.Width = (int)node.Children["Visual"][0].Attributes["Width"].Value; - terrain.Height = (int)node.Children["Visual"][0].Attributes["Height"].Value; - terrain.CellsX = (int)Math.Ceiling(terrain.Width * 0.5f) + 1; - terrain.CellsY = (int)Math.Ceiling(terrain.Height * 0.5f) + 1; - terrain.PatchesX = (int)Math.Ceiling(terrain.Width * 0.015625f); - terrain.PatchesY = (int)Math.Ceiling(terrain.Height * 0.015625f); - terrain.NumPatches = terrain.PatchesX * terrain.PatchesY; - terrain.Patches = new TerrainPatch[terrain.NumPatches]; - - int offsetY = 0; - for (int y = 0; y < terrain.PatchesY; y++) - { - int sizeY = Math.Min(terrain.CellsY - offsetY - 1, 32) + 1; - int offsetX = 0; - for (int x = 0; x < terrain.PatchesX; x++) - { - int sizeX = Math.Min(terrain.CellsX - offsetX - 1, 32) + 1; - - var patchPath = Path.Join(dir, $"{terrain.GUID}_{x}_{y}.patch"); - var patch = new TerrainPatch(); - patch.X = x; - patch.Y = y; - patch.Width = sizeX; - patch.Height = sizeY; - LoadPatch(patch, patchPath); - terrain.Patches[x + y * terrain.PatchesX] = patch; - offsetX += 32; - } - offsetY += 32; - } - - return terrain; - } - - private static void SaveTerrainPatches(Terrain terrain) - { - foreach (var patch in terrain.Patches) - { - SavePatch(patch, patch.Path); - } - } - - private static void LoadPatch(TerrainPatch patch, string sourcePath) - { - using (var fs = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - using (var reader = new BinaryReader(fs)) - { - patch.Path = sourcePath; - patch.Header = BinUtils.ReadStruct(reader); - if (patch.Header.Version != 4) - throw new InvalidFormatException(String.Format("Can only read version 4 terrain patch files; this file is v{0}", patch.Header.Version)); - - patch.Heightmap = new float[patch.Width * patch.Height]; - for (var i = 0; i < patch.Width * patch.Height; i++) - { - patch.Heightmap[i] = reader.ReadSingle(); - } - - int numVertices = reader.ReadInt32(); - patch.Vertices = new Vector2d[numVertices]; - for (var i = 0; i < numVertices; i++) - { - int x = reader.ReadInt32(); - int y = reader.ReadInt32(); - patch.Vertices[i] = new Vector2d(x, y); - } - - int numIndices = reader.ReadInt32(); - patch.Indices = new int[numIndices/4]; - for (var i = 0; i < numIndices / 4; i++) - { - patch.Indices[i] = reader.ReadInt32(); - } - - patch.PatchIndex = reader.ReadInt32(); - int numLayers = reader.ReadInt32(); - - patch.Layers = new TerrainPatchLayer[numLayers]; - for (var i = 0; i < numLayers; i++) - { - var layer = new TerrainPatchLayer(); - layer.Index = reader.ReadInt32(); - if (layer.Index != -1) - { - int layerBytes = reader.ReadInt32(); - layer.Data = new int[layerBytes/4]; - for (int j = 0; j < layerBytes/4; j++) - { - layer.Data[j] = reader.ReadInt32(); - } - int layerBytes2 = reader.ReadInt32(); - layer.Data2 = new byte[layerBytes2]; - for (int j = 0; j < layerBytes2; j++) - { - layer.Data2[j] = reader.ReadByte(); - } - } - - patch.Layers[i] = layer; - } - - if (fs.Position != fs.Length) - { - throw new InvalidDataException("Did not reach EOF?"); - } - } - } - - private static void SavePatch(TerrainPatch patch, string sourcePath) - { - using (var fs = new FileStream(sourcePath, FileMode.Create, FileAccess.Write, FileShare.ReadWrite)) - using (var writer = new BinaryWriter(fs)) - { - BinUtils.WriteStruct(writer, ref patch.Header); - - for (var i = 0; i < patch.Width * patch.Height; i++) - { - writer.Write(patch.Heightmap[i]); - } - - writer.Write((Int32)patch.Vertices.Length); - for (var i = 0; i < patch.Vertices.Length; i++) - { - writer.Write(patch.Vertices[i].X); - writer.Write(patch.Vertices[i].Y); - } - - writer.Write((Int32)patch.Indices.Length * 4); - for (var i = 0; i < patch.Indices.Length; i++) - { - writer.Write(patch.Indices[i]); - } - - writer.Write(patch.PatchIndex); - writer.Write((Int32)patch.Layers.Length); - - for (var i = 0; i < patch.Layers.Length; i++) - { - var layer = patch.Layers[i]; - writer.Write(layer.Index); - if (layer.Index != -1) - { - writer.Write((Int32)layer.Data.Length*4); - for (int j = 0; j < layer.Data.Length; j++) - { - writer.Write(layer.Data[j]); - } - - writer.Write((Int32)layer.Data2.Length); - for (int j = 0; j < layer.Data2.Length; j++) - { - writer.Write(layer.Data2[j]); - } - } - } - } - } - } -} diff --git a/TerrainFixup/TerrainFixup.csproj b/TerrainFixup/TerrainFixup.csproj deleted file mode 100644 index 75c276b7..00000000 --- a/TerrainFixup/TerrainFixup.csproj +++ /dev/null @@ -1,13 +0,0 @@ - - - - Exe - net5.0 - - - - - - - - diff --git a/UnpackGrid/Program.cs b/UnpackGrid/Program.cs deleted file mode 100644 index a4639b68..00000000 --- a/UnpackGrid/Program.cs +++ /dev/null @@ -1,69 +0,0 @@ -using LSLib.LS; -using System; -using System.IO; -using System.Runtime.InteropServices; - -namespace UnpackGrid -{ - [StructLayout(LayoutKind.Sequential)] - public struct AIGridHeader - { - public UInt32 Version; - public Int32 Width; - public Int32 Height; - public Single OffsetX; - public Single OffsetY; - public Single OffsetZ; - } - - [StructLayout(LayoutKind.Sequential)] - public struct AIGridCompressionHeader - { - public Int32 UncompressedSize; - public Int32 CompressedSize; - } - - class Program - { - static void Main(string[] args) - { - if (args.Length != 2) - { - Console.WriteLine("Usage: UnpackGrid "); - return; - } - - UnpackAiGrid(args[0], args[1]); - } - - private static void UnpackAiGrid(string sourcePath, string destinationPath) - { - using (var fs = new FileStream(sourcePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) - using (var reader = new BinaryReader(fs)) - { - var header = BinUtils.ReadStruct(reader); - if (header.Version != 4) - throw new InvalidFormatException(String.Format("Can only decompress version 4 AI grid files; this file is v{0}", header.Version)); - - var compHeader = BinUtils.ReadStruct(reader); - - if (fs.Length != compHeader.CompressedSize + fs.Position) - throw new InvalidFormatException(String.Format("Invalid AI grid file size; expected {0}, got {1}", compHeader.CompressedSize + fs.Position, fs.Length)); - - var compressedBlob = reader.ReadBytes(compHeader.CompressedSize); - var uncompressed = BinUtils.Decompress(compressedBlob, compHeader.UncompressedSize, 0x21); - var uncompressed2 = BinUtils.Decompress(uncompressed, 16 * header.Width * header.Height, 0x42); - - header.Version = 2; - using (var unpackedFs = new FileStream(destinationPath, FileMode.Create)) - using (var writer = new BinaryWriter(unpackedFs)) - { - BinUtils.WriteStruct(writer, ref header); - writer.Write(uncompressed2); - } - } - - Console.WriteLine($"Wrote resource to: {destinationPath}"); - } - } -} diff --git a/UnpackGrid/UnpackGrid.csproj b/UnpackGrid/UnpackGrid.csproj deleted file mode 100644 index 5a506c33..00000000 --- a/UnpackGrid/UnpackGrid.csproj +++ /dev/null @@ -1,12 +0,0 @@ - - - - Exe - net5.0 - - - - - - - diff --git a/VTexTool/App.config b/VTexTool/App.config new file mode 100644 index 00000000..ecdcf8a5 --- /dev/null +++ b/VTexTool/App.config @@ -0,0 +1,6 @@ + + + + + + diff --git a/VTexTool/Program.cs b/VTexTool/Program.cs new file mode 100644 index 00000000..5ceceac4 --- /dev/null +++ b/VTexTool/Program.cs @@ -0,0 +1,55 @@ +using LSLib.LS; +using LSLib.VirtualTextures; +using System; +using System.IO; +using System.Linq; + +namespace LSTools.StoryDecompiler +{ + class Program + { + static void Main(string[] args) + { + if (args.Length != 2) + { + Console.WriteLine("Usage: VTexTool.exe "); + Environment.Exit(1); + } + + Console.WriteLine($"LSLib Virtual Tile Set Generator (v{Common.MajorVersion}.{Common.MinorVersion}.{Common.PatchVersion})"); + + try + { + var configPath = Path.Combine(args[0], args[1]); + var descriptor = new TileSetDescriptor + { + RootPath = args[0] + }; + descriptor.Load(configPath); + + var builder = new TileSetBuilder(descriptor.Config); + foreach (var texture in descriptor.Textures) + { + var layerPaths = texture.Layers.Select(name => name != null ? Path.Combine(descriptor.SourceTexturePath, name) : null).ToList(); + builder.AddTexture(texture.Name, layerPaths); + } + + builder.Build(descriptor.VirtualTexturePath); + } + catch (InvalidDataException e) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(e.Message); + Console.ForegroundColor = ConsoleColor.Gray; + Environment.Exit(1); + } + catch (FileNotFoundException e) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine(e.Message); + Console.ForegroundColor = ConsoleColor.Gray; + Environment.Exit(1); + } + } + } +} diff --git a/VTexTool/Properties/AssemblyInfo.cs b/VTexTool/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..bd2d8575 --- /dev/null +++ b/VTexTool/Properties/AssemblyInfo.cs @@ -0,0 +1,13 @@ +using System.Reflection; +using System.Runtime.CompilerServices; +using System.Runtime.InteropServices; +[assembly: AssemblyTrademark("")] +[assembly: AssemblyCulture("")] + +// Setting ComVisible to false makes the types in this assembly not visible +// to COM components. If you need to access a type in this assembly from +// COM, set the ComVisible attribute to true on that type. +[assembly: ComVisible(false)] + +// The following GUID is for the ID of the typelib if this project is exposed to COM +[assembly: Guid("67e646c2-3c3c-4327-a0b4-40c1db32579f")] diff --git a/VTexTool/VTexTool.csproj b/VTexTool/VTexTool.csproj new file mode 100644 index 00000000..dd14a5d9 --- /dev/null +++ b/VTexTool/VTexTool.csproj @@ -0,0 +1,16 @@ + + + net8.0 + Exe + false + x64 + Osiris Story Decompiler + LSLib + Copyright © Norbyte 2012-2018 + 1.0.0.0 + 1.0.0.0 + + + + + \ No newline at end of file