Main.cs 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619
  1. using System;
  2. using System.Threading.Tasks;
  3. using System.Windows.Forms;
  4. using System.Collections.Generic;
  5. using SlimDX;
  6. using SlimDX.D3DCompiler;
  7. using SlimDX.Direct3D11;
  8. using SlimDX.DXGI;
  9. using SlimDX.Windows;
  10. using Device = SlimDX.Direct3D11.Device;
  11. using Resource = SlimDX.Direct3D11.Resource;
  12. using Buffer = SlimDX.Direct3D11.Buffer;
  13. using Everquest2.Util;
  14. using Everquest2.Visualization;
  15. using System.IO;
  16. namespace EQ2ModelViewer
  17. {
  18. public partial class frmMain : Form
  19. {
  20. private System.Collections.Generic.List<Model> m_Models = new System.Collections.Generic.List<Model>();
  21. private GraphicClass Graphics = new GraphicClass();
  22. public Model SelectedModel = null;
  23. private string ZoneFile;
  24. private bool Render3DAspect = true;
  25. private bool AutoExportOnLoad = false;
  26. private String AutoLoadFileName = "";
  27. public frmMain()
  28. {
  29. InitializeComponent();
  30. }
  31. private void exitToolStripMenuItem_Click(object sender, EventArgs e)
  32. {
  33. Close();
  34. }
  35. private void CleanUp()
  36. {
  37. foreach (Model model in m_Models)
  38. model.ShutDown();
  39. if (Graphics != null)
  40. Graphics.ShutDown();
  41. }
  42. private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
  43. {
  44. CleanUp();
  45. }
  46. private CameraClass camera;
  47. private void frmMain_Load(object sender, EventArgs e)
  48. {
  49. this.WindowState = FormWindowState.Maximized;
  50. Graphics.Initialize(pGraphics);
  51. /*LightShaderClass lightShader = new LightShaderClass();
  52. lightShader.Initialize(Graphics.Device);*/
  53. camera = new CameraClass();
  54. // Initialize a base view matrix for 2D rendering
  55. camera.SetPosition(0.0f, 0.0f, -1.0f);
  56. camera.Render();
  57. Matrix baseViewMatrix = camera.GetViewMatrix();
  58. // now set the cameras starting position
  59. camera.SetPosition(0.0f, 1.50f, -3.0f);
  60. PositionClass position = new PositionClass();
  61. position.SetPosition(0.0f, 1.50f, -3.0f);
  62. InputClass input = new InputClass();
  63. input.Initialize(this);
  64. TimerClass timer = new TimerClass();
  65. timer.Initialize();
  66. FPSClass fps = new FPSClass();
  67. fps.Initialize();
  68. TextClass text = new TextClass();
  69. text.Initialize(Graphics.Device, Graphics.Context, pGraphics.ClientSize.Width, pGraphics.ClientSize.Height, baseViewMatrix);
  70. BitmapClass bmp = new BitmapClass();
  71. bmp.Initialize(Graphics.Device, pGraphics.ClientSize.Width, pGraphics.ClientSize.Height, "Background.bmp", 145, 220, baseViewMatrix);
  72. string[] args = Environment.GetCommandLineArgs();
  73. if (args.Length > 1)
  74. {
  75. for (int i = 1; i < args.Length; i++)
  76. {
  77. string cmd = args[i].ToLower();
  78. if (cmd.Equals("norender"))
  79. {
  80. Render3DAspect = false;
  81. }
  82. else if (cmd.Equals("export"))
  83. {
  84. AutoExportOnLoad = true;
  85. }
  86. else
  87. {
  88. AutoLoadFileName = args[i];
  89. break;
  90. }
  91. }
  92. }
  93. if (AutoLoadFileName.Length > 0)
  94. LoadZoneFile(AutoLoadFileName);
  95. if (AutoExportOnLoad)
  96. exportToolStripMenuItem_Click(null, EventArgs.Empty);
  97. if (!Render3DAspect)
  98. {
  99. Application.Exit();
  100. return;
  101. }
  102. // FrustumClass frustum = new FrustumClass();
  103. try
  104. {
  105. MessagePump.Run(this, () =>
  106. {
  107. if (!Graphics.SwapChain.Disposed) {
  108. timer.Frame();
  109. fps.Frame();
  110. // Input code
  111. input.Frame();
  112. position.SetFrameTime(timer.GetTime());
  113. if (this.Focused)
  114. {
  115. if (input.IsKeyPressed(SlimDX.DirectInput.Key.LeftShift) ||
  116. input.IsKeyPressed(SlimDX.DirectInput.Key.RightShift))
  117. position.m_ShiftDown = true;
  118. else
  119. position.m_ShiftDown = false;
  120. position.TurnLeft(input.IsLeftPressed());
  121. position.TurnRight(input.IsRightPressed());
  122. position.MoveForward(input.IsUpPressed());
  123. position.MoveBackward(input.IsDownPressed());
  124. position.MoveUpward(input.IsAPressed());
  125. position.MoveDownward(input.IsZPressed());
  126. position.LookUpward(input.IsPgUpPressed());
  127. position.LookDownward(input.IsPgDownPressed());
  128. if (input.IsLeftMousePressed())
  129. {
  130. TestIntersection(input.GetMouseX(), input.GetMouseY());
  131. }
  132. if (SelectedModel != null)
  133. {
  134. if (input.IsKeyPressed(SlimDX.DirectInput.Key.Delete))
  135. {
  136. m_Models.Remove(SelectedModel);
  137. SelectedModel = null;
  138. }
  139. else if (input.IsKeyPressed(SlimDX.DirectInput.Key.Escape))
  140. {
  141. SelectedModel = null;
  142. }
  143. }
  144. }
  145. camera.SetPosition(position.GetPosition());
  146. camera.SetRotation(position.GetRotation());
  147. // Render Code
  148. Graphics.BeginScene();
  149. // 3D
  150. // View matrix
  151. camera.Render();
  152. //frustum.ConstructFrustum(1000.0f, Graphics.GetProjectionMatrix(), camera.GetViewMatrix());
  153. foreach (Model model in m_Models) {
  154. //if (frustum.CheckSphere(model.Position.X, model.Position.Y, model.Position.Z, 10.0f))
  155. //{
  156. /*Matrix temp = Matrix.Multiply(Graphics.GetWorldMatrix(), Matrix.Scaling(model.Scale, model.Scale, model.Scale));
  157. temp = Matrix.Multiply(temp, Matrix.RotationYawPitchRoll(model.Rotation.X, model.Rotation.Y, model.Rotation.Z));
  158. temp = Matrix.Multiply(temp, Matrix.Translation(model.Position.X, model.Position.Y, model.Position.Z));*/
  159. model.Render(Graphics, camera, (model == SelectedModel)/*Graphics.Context*/);
  160. //lightShader.Render(Graphics.Context, model.GetIndexCount(), temp, camera.GetViewMatrix(), Graphics.GetProjectionMatrix(), model.GetTexture(), new Vector3(0.0f, 0.0f, 0.0f), new Vector4(1.0f, 1.0f, 1.0f, 1.0f), new Vector4(0.0f, 0.0f, 0.0f, 0.0f), camera.GetPosition(), new Vector4(0.0f, 0.0f, 0.0f, 0.0f), 0.0f);
  161. //}
  162. }
  163. // 2D
  164. Graphics.TurnZBufferOff();
  165. Graphics.TurnOnAlphaBlending();
  166. bmp.Render(Graphics, 10, 10);
  167. text.SetFPS(fps.GetFPS(), Graphics.Context);
  168. text.SetPosition(position.GetPosition(), Graphics.Context);
  169. text.SetSelectedModel(SelectedModel, Graphics.Context);
  170. text.Render(Graphics.Context, Graphics.GetWorldMatrix(), Graphics.GetOrthoMatrix());
  171. Graphics.TurnOffAlphaBlending();
  172. Graphics.TurnZBufferOn();
  173. Graphics.EndScene();
  174. }
  175. });
  176. }
  177. catch (Exception exception) { }
  178. }
  179. public bool TestIntersection(int mouseX, int mouseY) {
  180. float pointX, pointY;
  181. Matrix projectionMatrix, viewMatrix, inverseViewMatrix;
  182. projectionMatrix = Graphics.GetProjectionMatrix();
  183. pointX = (2.0F * (float)mouseX / (float)pGraphics.ClientSize.Width - 1.0f) / projectionMatrix.M11;
  184. pointY = (-2.0f * (float)mouseY / (float)pGraphics.ClientSize.Height + 1.0f) / projectionMatrix.M22;
  185. Ray ray = new Ray(new Vector3(), new Vector3(pointX, pointY, 1.0f));
  186. viewMatrix = camera.GetViewMatrix();
  187. inverseViewMatrix = Matrix.Invert(viewMatrix);
  188. ray = new Ray(Vector3.TransformCoordinate(ray.Position, inverseViewMatrix), Vector3.TransformNormal(ray.Direction, inverseViewMatrix));
  189. ray.Direction.Normalize();
  190. float selectionDistance = 0.0f;
  191. foreach (Model model in m_Models) {
  192. float distance = model.TestIntersection(ray, Graphics);
  193. if (distance > 0.0f && (selectionDistance == 0.0f || distance < selectionDistance)) {
  194. selectionDistance = distance;
  195. SelectedModel = model;
  196. }
  197. }
  198. return false;
  199. }
  200. public static void AppendLoadFile(String txt)
  201. {
  202. StreamWriter sw = File.AppendText("loaded.txt");
  203. sw.WriteLine(txt);
  204. sw.Close();
  205. }
  206. private void loadZoneToolStripMenuItem_Click(object sender, EventArgs e)
  207. {
  208. LoadZoneFile();
  209. }
  210. private void LoadZoneFile(String filename="")
  211. {
  212. bool isDrawFile = false;
  213. string fullName = "";
  214. String dirName = "";
  215. if (filename.Length < 1)
  216. {
  217. OpenFileDialog fd = new OpenFileDialog();
  218. fd.Filter = "lut/draw files (*.lut;*.draw)|*.lut;*.draw|lut files (*.lut)|*.lut|draw files (*.draw)|*.draw";
  219. if (fd.ShowDialog() == DialogResult.OK)
  220. {
  221. AppendLoadFile("===================================================");
  222. AppendLoadFile("Loading " + fd.FileName);
  223. if (fd.FileName.EndsWith(".draw"))
  224. {
  225. isDrawFile = true;
  226. string temp = fd.FileName.Substring(0, fd.FileName.LastIndexOf("\\"));
  227. ZoneFile = fd.SafeFileName.Substring(0, fd.SafeFileName.IndexOf(".draw"));
  228. fullName = ZoneFile;
  229. dirName = temp;
  230. filename = fd.FileName;
  231. }
  232. else
  233. {
  234. string temp = fd.FileName.Substring(0, fd.FileName.IndexOf("zones"));
  235. ZoneFile = fd.SafeFileName.Substring(0, fd.SafeFileName.IndexOf(".lut"));
  236. fullName = ZoneFile;
  237. dirName = temp;
  238. filename = fd.FileName;
  239. }
  240. }
  241. }
  242. else
  243. {
  244. if (filename.EndsWith(".draw"))
  245. {
  246. isDrawFile = true;
  247. string temp = filename.Substring(0, filename.LastIndexOf("\\"));
  248. ZoneFile = filename.Substring(0, filename.IndexOf(".draw"));
  249. fullName = filename;
  250. dirName = temp;
  251. }
  252. else
  253. {
  254. string temp = filename.Substring(0, filename.IndexOf("zones"));
  255. ZoneFile = filename.Substring(0, filename.IndexOf(".lut"));
  256. fullName = filename;
  257. dirName = temp;
  258. }
  259. }
  260. if (isDrawFile)
  261. {
  262. Model tmpModel = new Model();
  263. string[] textures = new string[1];
  264. textures[0] = "goblin_ice.dds";
  265. tmpModel.Initialize(Graphics.Device, filename, textures);
  266. tmpModel.Position.X = 0;
  267. tmpModel.Position.Y = 0;
  268. tmpModel.Position.Z = 0;
  269. tmpModel.Rotation.X = 0;
  270. tmpModel.Rotation.Y = 0;
  271. tmpModel.Rotation.Z = 0;
  272. tmpModel.Scale = 1;
  273. tmpModel.WidgetID = 1;
  274. tmpModel.GridID = 1;
  275. m_Models.Add(tmpModel);
  276. return;
  277. }
  278. if (fullName.Length < 1)
  279. {
  280. MessageBox.Show("No filename provided for loading a zonefile!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
  281. return;
  282. }
  283. System.IO.BinaryReader reader2 = new System.IO.BinaryReader(new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read));
  284. // Image(2020): Was ReadUint32, qey_harbor.lut however has 00 1F 00 7A, so that as an int32 is a very large number!
  285. reader2.ReadUInt32();
  286. do
  287. {
  288. if (reader2.BaseStream.Position + 2 >= reader2.BaseStream.Length)
  289. {
  290. break;
  291. }
  292. UInt16 size = reader2.ReadUInt16();
  293. string file = new string(reader2.ReadChars(size));
  294. // was duplicating drive name
  295. file = file.Replace("/", "\\");
  296. file = dirName + file;
  297. AppendLoadFile("VOC Loading: " + file);
  298. Eq2Reader reader = new Eq2Reader(new System.IO.FileStream(file, System.IO.FileMode.Open, System.IO.FileAccess.Read));
  299. VeNode venode = reader.ReadNodeObject();
  300. CheckNode(dirName, venode);
  301. //MessageBox.Show("Done!");
  302. // 16 bytes between file names, grid id's maybe?
  303. reader2.ReadBytes(16);
  304. } while (true);
  305. }
  306. float x, y, z = 0;
  307. float yaw, pitch, roll = 0;
  308. float scale = 0;
  309. UInt32 widgetID;
  310. UInt32 GridID;
  311. bool flipStatus = false;
  312. private void CheckNode(string temp, object item)
  313. {
  314. if (item is VeMeshGeometryNode)
  315. {
  316. widgetID = ((VeNode)item).WidgetID;
  317. // testing antonica spires which are not oriented correctly
  318. if ( widgetID == 2990295910 )
  319. {
  320. int test = 0;
  321. }
  322. Model model = new Model();
  323. model.Initialize(Graphics.Device, (VeMeshGeometryNode)item, temp);
  324. model.Position.X = x;
  325. model.Position.Y = y;
  326. model.Position.Z = z;
  327. model.Rotation.X = yaw;
  328. model.Rotation.Y = pitch;
  329. model.Rotation.Z = roll;
  330. model.Scale = scale;
  331. model.WidgetID = widgetID;
  332. model.GridID = GridID;
  333. m_Models.Add(model);
  334. }
  335. else
  336. {
  337. float x1 = 0.0f;
  338. float y1 = 0.0f;
  339. float z1 = 0.0f;
  340. if (item is VeRoomItemNode)
  341. {
  342. yaw = ((VeRoomItemNode)item).orientation[0];
  343. pitch = ((VeRoomItemNode)item).orientation[1];
  344. roll = ((VeRoomItemNode)item).orientation[2];
  345. GridID = ((VeRoomItemNode)item).myId_grid;
  346. }
  347. else if (item is VeXformNode)
  348. {
  349. x1 = ((VeXformNode)item).position[0];
  350. y1 = ((VeXformNode)item).position[1];
  351. z1 = ((VeXformNode)item).position[2];
  352. yaw = (((VeXformNode)item).orientation[0]) * (3.141592654f / 180.0f);
  353. pitch = (((VeXformNode)item).orientation[1]) * (3.141592654f / 180.0f);
  354. roll = (((VeXformNode)item).orientation[2]) * (3.141592654f / 180.0f);
  355. scale = ((VeXformNode)item).scale;
  356. x += x1;
  357. y += y1;
  358. z += z1;
  359. }
  360. if (item != null)
  361. {
  362. System.Collections.IEnumerator enumerator = ((VeNode)item).EnumerateChildren();
  363. while (enumerator.MoveNext())
  364. {
  365. CheckNode(temp, enumerator.Current);
  366. }
  367. x -= x1;
  368. y -= y1;
  369. z -= z1;
  370. }
  371. }
  372. }
  373. public static string[] GetTextureFile(string[] spPath, string basePath)
  374. {
  375. string ret = "goblin_ice.dds";
  376. System.Collections.Generic.List<string> strings = new System.Collections.Generic.List<string>();
  377. int i = 0;
  378. while (i < spPath.Length /*&& ret == "goblin_ice.dds"*/)
  379. {
  380. Eq2Reader reader = new Eq2Reader(new System.IO.FileStream(basePath + spPath[i], System.IO.FileMode.Open, System.IO.FileAccess.Read));
  381. VeBase sp = reader.ReadObject();
  382. reader.Close();
  383. if (sp is VeShaderPalette)
  384. {
  385. bool found = false;
  386. for (int s = 0; s < ((VeShaderPalette)sp).shaderNames.Length; s++)
  387. {
  388. String fileName = basePath + ((VeShaderPalette)sp).shaderNames[s];
  389. fileName = fileName.Replace("/", "\\");
  390. System.IO.StreamReader reader2 = new System.IO.StreamReader(fileName);
  391. while (!reader2.EndOfStream)
  392. {
  393. string lineOrig = reader2.ReadLine();
  394. if (lineOrig.Contains("name = \"@tex") && !lineOrig.Contains("Blend") && !lineOrig.Contains("UVSet"))
  395. {
  396. String line = reader2.ReadLine();
  397. while (line.Length < 1)
  398. line = reader2.ReadLine();
  399. line = line.Substring(line.IndexOf('"') + 1);
  400. line = line.Substring(0, line.Length - 1);
  401. ret = basePath + line;
  402. strings.Add(ret);
  403. found = true;
  404. break;
  405. //break;
  406. }
  407. if (found)
  408. break;
  409. }
  410. reader2.Close();
  411. }
  412. }
  413. i++;
  414. }
  415. if (strings.Count == 0)
  416. strings.Add(ret);
  417. return strings.ToArray();
  418. }
  419. private void exportToolStripMenuItem_Click(object sender, EventArgs e)
  420. {
  421. //List<Vector3> MasterVertexList = new List<Vector3>();
  422. Dictionary<UInt32, List<Vector3>> MasterVertexList = new Dictionary<UInt32, List<Vector3>>();
  423. foreach (Model model in m_Models)
  424. {
  425. if (model.WidgetID == 1253219127)
  426. {
  427. int test = 0;
  428. }
  429. List<Vector3> VertexList = model.GetVertices();
  430. UInt32 grid = model.GridID;
  431. if (!MasterVertexList.ContainsKey(grid))
  432. MasterVertexList[grid] = new List<Vector3>();
  433. List<Vector3> convertedVertices = new List<Vector3>();
  434. foreach(Vector3 vect in VertexList)
  435. {
  436. Quaternion rotation = Quaternion.RotationYawPitchRoll(model.Rotation.X, model.Rotation.Y, model.Rotation.Z);
  437. var matrix = Matrix.Identity;
  438. Matrix.RotationQuaternion(ref rotation, out matrix);
  439. Matrix scaled = Matrix.Multiply(matrix, Matrix.Scaling(model.Scale, model.Scale, model.Scale));
  440. Vector3 result = Vector3.Add(Vector3.TransformNormal(vect, scaled), model.Position);
  441. convertedVertices.Add(result);
  442. }
  443. MasterVertexList[grid].AddRange(convertedVertices);
  444. }
  445. float minX = float.NaN;
  446. float minZ = float.NaN;
  447. float maxX = float.NaN;
  448. float maxZ = float.NaN;
  449. foreach (KeyValuePair<UInt32, List<Vector3>> entry in MasterVertexList)
  450. {
  451. foreach (Vector3 v in entry.Value)
  452. {
  453. if (float.IsNaN(minX))
  454. {
  455. minX = v.X;
  456. maxX = v.X;
  457. minZ = v.Z;
  458. maxZ = v.Z;
  459. }
  460. else
  461. {
  462. if (v.X < minX)
  463. minX = v.X;
  464. if (v.X > maxX)
  465. maxX = v.X;
  466. if (v.Z < minZ)
  467. minZ = v.Z;
  468. if (v.Z > maxZ)
  469. maxZ = v.Z;
  470. }
  471. }
  472. }
  473. using (StreamWriter file = new StreamWriter(ZoneFile + ".obj"))
  474. {
  475. // file.WriteLine(ZoneFile);
  476. // file.WriteLine("Min");
  477. // file.WriteLine(minX + " " + minZ);
  478. // file.WriteLine("Max");
  479. // file.WriteLine(maxX + " " + maxZ);
  480. // file.WriteLine("Grid count");
  481. // file.WriteLine(MasterVertexList.Count);
  482. // file.WriteLine();
  483. List<string> indices = new List<string>();
  484. int count = 0;
  485. string buildStr = "";
  486. int curcount = 0;
  487. foreach (KeyValuePair<UInt32, List<Vector3>> entry in MasterVertexList)
  488. {
  489. buildStr = "f ";
  490. // file.WriteLine("Grid");
  491. // file.WriteLine(entry.Key);
  492. // file.WriteLine("Face count");
  493. // file.WriteLine(entry.Value.Count);
  494. foreach (Vector3 v in entry.Value)
  495. {
  496. if (curcount > 2)
  497. {
  498. buildStr += count;
  499. indices.Add(buildStr);
  500. buildStr = "f ";
  501. curcount = 0;
  502. }
  503. else
  504. buildStr += count + " ";
  505. file.WriteLine("v " + v.X.ToString() + " " + v.Y.ToString()
  506. + " " + v.Z.ToString());
  507. count++;
  508. curcount++;
  509. }
  510. }
  511. foreach (string str in indices)
  512. {
  513. file.WriteLine(str);
  514. }
  515. file.Close();
  516. }
  517. using (BinaryWriter file = new BinaryWriter(File.Open(ZoneFile + ".EQ2Map", FileMode.Create)))
  518. {
  519. file.Write(ZoneFile);
  520. file.Write(minX);
  521. file.Write(minZ);
  522. file.Write(maxX);
  523. file.Write(maxZ);
  524. file.Write(MasterVertexList.Count);
  525. foreach (KeyValuePair<UInt32, List<Vector3>> entry in MasterVertexList)
  526. {
  527. file.Write(entry.Key);
  528. file.Write(entry.Value.Count);
  529. foreach (Vector3 v in entry.Value)
  530. {
  531. file.Write(v.X);
  532. file.Write(v.Y);
  533. file.Write(v.Z);
  534. }
  535. }
  536. file.Close();
  537. }
  538. if (sender != null)
  539. MessageBox.Show("Export Complete!");
  540. }
  541. }
  542. }