Main.cs 48 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108
  1. using System;
  2. using System.Threading.Tasks;
  3. using System.Windows.Forms;
  4. using System.Collections.Generic;
  5. using System.IO.Compression;
  6. using System.Xml;
  7. using System.Text.RegularExpressions;
  8. using SlimDX;
  9. using SlimDX.D3DCompiler;
  10. using SlimDX.Direct3D11;
  11. using SlimDX.DXGI;
  12. using SlimDX.Windows;
  13. using Device = SlimDX.Direct3D11.Device;
  14. using Resource = SlimDX.Direct3D11.Resource;
  15. using Buffer = SlimDX.Direct3D11.Buffer;
  16. using Everquest2.Util;
  17. using Everquest2.Visualization;
  18. using System.IO;
  19. using SlimDX.DirectInput;
  20. using SlimDX.Direct2D;
  21. using System.Security.Permissions;
  22. namespace EQ2ModelViewer
  23. {
  24. public partial class frmMain : Form
  25. {
  26. private System.Collections.Generic.List<Model> m_Models = new System.Collections.Generic.List<Model>();
  27. private System.Collections.Generic.List<VeRegion> m_Regions = new System.Collections.Generic.List<VeRegion>();
  28. private GraphicClass Graphics = new GraphicClass();
  29. public Model SelectedModel = null;
  30. private string ZoneFile;
  31. private string AppendFileStr = "";
  32. private bool Render3DAspect = true;
  33. private bool AutoExportOnLoad = false;
  34. private bool AutoExportRegionOnLoad = false;
  35. private String AutoLoadFileName = "";
  36. private bool IsLoaded = false;
  37. private bool WriteObjFile = false;
  38. public frmMain()
  39. {
  40. InitializeComponent();
  41. }
  42. private void exitToolStripMenuItem_Click(object sender, EventArgs e)
  43. {
  44. Close();
  45. }
  46. private void CleanUp()
  47. {
  48. foreach (Model model in m_Models)
  49. model.ShutDown();
  50. if (Graphics != null)
  51. Graphics.ShutDown();
  52. }
  53. private void frmMain_FormClosing(object sender, FormClosingEventArgs e)
  54. {
  55. CleanUp();
  56. }
  57. private Key hitKey = Key.NoConvert;
  58. double timestamp = 0;
  59. private CameraClass camera;
  60. int region_nodes = 0;
  61. private void frmMain_Load(object sender, EventArgs e)
  62. {
  63. this.WindowState = FormWindowState.Maximized;
  64. Graphics.Initialize(pGraphics);
  65. /*LightShaderClass lightShader = new LightShaderClass();
  66. lightShader.Initialize(Graphics.Device);*/
  67. camera = new CameraClass();
  68. // Initialize a base view matrix for 2D rendering
  69. camera.SetPosition(0.0f, 0.0f, -1.0f);
  70. camera.Render();
  71. Matrix baseViewMatrix = camera.GetViewMatrix();
  72. // now set the cameras starting position
  73. camera.SetPosition(0.0f, 1.50f, -3.0f);
  74. PositionClass position = new PositionClass();
  75. position.SetPosition(0.0f, 1.50f, -3.0f);
  76. InputClass input = new InputClass();
  77. input.Initialize(this);
  78. TimerClass timer = new TimerClass();
  79. timer.Initialize();
  80. FPSClass fps = new FPSClass();
  81. fps.Initialize();
  82. TextClass text = new TextClass();
  83. text.Initialize(Graphics.Device, Graphics.Context, pGraphics.ClientSize.Width, pGraphics.ClientSize.Height, baseViewMatrix);
  84. BitmapClass bmp = new BitmapClass();
  85. bmp.Initialize(Graphics.Device, pGraphics.ClientSize.Width, pGraphics.ClientSize.Height, "Background.bmp", 145, 260, baseViewMatrix);
  86. string[] args = Environment.GetCommandLineArgs();
  87. if (args.Length > 1)
  88. {
  89. for (int i = 1; i < args.Length; i++)
  90. {
  91. string cmd = args[i].ToLower();
  92. if (cmd.Equals("norender"))
  93. {
  94. Render3DAspect = false;
  95. }
  96. else if (cmd.Equals("export"))
  97. {
  98. AutoExportOnLoad = true;
  99. }
  100. else if (cmd.Equals("exportregion"))
  101. {
  102. AutoExportRegionOnLoad = true;
  103. }
  104. else if ( cmd.StartsWith("appendexportfile"))
  105. {
  106. int equalsSign = cmd.IndexOf("=");
  107. if (equalsSign > 0 && (equalsSign+1) < cmd.Length)
  108. {
  109. string appendFileVal = cmd.Substring(equalsSign+1, cmd.Length - equalsSign - 1);
  110. AppendFileStr = appendFileVal;
  111. }
  112. }
  113. else
  114. {
  115. AutoLoadFileName = args[i];
  116. break;
  117. }
  118. }
  119. }
  120. if (AutoLoadFileName.Length > 0)
  121. LoadZoneFile(AutoLoadFileName);
  122. if (AutoExportOnLoad)
  123. exportToolStripMenuItem_Click(null, EventArgs.Empty);
  124. if (AutoExportRegionOnLoad)
  125. toolStripMenuItemExportWater_Click(null, EventArgs.Empty);
  126. if (!Render3DAspect)
  127. {
  128. Application.Exit();
  129. return;
  130. }
  131. // FrustumClass frustum = new FrustumClass();
  132. try
  133. {
  134. MessagePump.Run(this, () =>
  135. {
  136. if (!Graphics.SwapChain.Disposed) {
  137. timer.Frame();
  138. fps.Frame();
  139. // Input code
  140. input.Frame();
  141. position.SetFrameTime(timer.GetTime());
  142. if (this.Focused)
  143. {
  144. if (input.IsKeyPressed(SlimDX.DirectInput.Key.LeftShift) ||
  145. input.IsKeyPressed(SlimDX.DirectInput.Key.RightShift))
  146. position.m_ShiftDown = true;
  147. else
  148. position.m_ShiftDown = false;
  149. position.TurnLeft(input.IsLeftPressed());
  150. position.TurnRight(input.IsRightPressed());
  151. position.MoveForward(input.IsUpPressed());
  152. position.MoveBackward(input.IsDownPressed());
  153. position.MoveUpward(input.IsAPressed());
  154. position.MoveDownward(input.IsZPressed());
  155. position.LookUpward(input.IsPgUpPressed());
  156. position.LookDownward(input.IsPgDownPressed());
  157. if (input.IsLeftMousePressed())
  158. {
  159. TestIntersection(input.GetMouseX(), input.GetMouseY());
  160. }
  161. if (SelectedModel != null)
  162. {
  163. if (input.IsKeyPressed(SlimDX.DirectInput.Key.Delete))
  164. {
  165. m_Models.Remove(SelectedModel);
  166. SelectedModel = null;
  167. }
  168. else if (input.IsKeyPressed(SlimDX.DirectInput.Key.Escape))
  169. {
  170. SelectedModel = null;
  171. }
  172. if (input.IsKeyPressed(SlimDX.DirectInput.Key.LeftControl))
  173. {
  174. if (hitKey == Key.NoConvert)
  175. {
  176. if (input.IsKeyPressed(SlimDX.DirectInput.Key.R))
  177. hitKey = Key.R;
  178. else if (input.IsKeyPressed(SlimDX.DirectInput.Key.T))
  179. hitKey = Key.T;
  180. else if (input.IsKeyPressed(SlimDX.DirectInput.Key.Y))
  181. hitKey = Key.Y;
  182. }
  183. double curTime = (DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalMilliseconds;
  184. if ((curTime - timestamp) > 50)
  185. {
  186. if (hitKey == Key.R)
  187. {
  188. if (input.IsKeyReleased(SlimDX.DirectInput.Key.R))
  189. hitKey = Key.NoConvert;
  190. SelectedModel.Rotation += new Vector3(0.01f, 0.0f, 0.0f);
  191. timestamp = curTime;
  192. }
  193. else if (hitKey == Key.T)
  194. {
  195. if (input.IsKeyReleased(SlimDX.DirectInput.Key.T))
  196. hitKey = Key.NoConvert;
  197. SelectedModel.Rotation += new Vector3(0.0f, 0.01f, 0.0f);
  198. timestamp = curTime;
  199. }
  200. else if (hitKey == Key.Y)
  201. {
  202. if (input.IsKeyReleased(SlimDX.DirectInput.Key.Y))
  203. hitKey = Key.NoConvert;
  204. SelectedModel.Rotation += new Vector3(0.0f, 0.0f, 0.01f);
  205. timestamp = curTime;
  206. }
  207. if (SelectedModel.Rotation.X > 360.0f)
  208. SelectedModel.Rotation.X = 0.0f;
  209. if (SelectedModel.Rotation.Y > 360.0f)
  210. SelectedModel.Rotation.Y = 0.0f;
  211. if (SelectedModel.Rotation.Z > 360.0f)
  212. SelectedModel.Rotation.Z = 0.0f;
  213. }
  214. }
  215. }
  216. }
  217. camera.SetPosition(position.GetPosition());
  218. camera.SetRotation(position.GetRotation());
  219. // Render Code
  220. Graphics.BeginScene();
  221. // 3D
  222. // View matrix
  223. camera.Render();
  224. //frustum.ConstructFrustum(1000.0f, Graphics.GetProjectionMatrix(), camera.GetViewMatrix());
  225. foreach (Model model in m_Models) {
  226. //if (frustum.CheckSphere(model.Position.X, model.Position.Y, model.Position.Z, 10.0f))
  227. //{
  228. /*Matrix temp = Matrix.Multiply(Graphics.GetWorldMatrix(), Matrix.Scaling(model.Scale, model.Scale, model.Scale));
  229. temp = Matrix.Multiply(temp, Matrix.RotationYawPitchRoll(model.Rotation.X, model.Rotation.Y, model.Rotation.Z));
  230. temp = Matrix.Multiply(temp, Matrix.Translation(model.Position.X, model.Position.Y, model.Position.Z));*/
  231. model.Render(Graphics, camera, (model == SelectedModel)/*Graphics.Context*/);
  232. //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);
  233. //}
  234. }
  235. // 2D
  236. Graphics.TurnZBufferOff();
  237. Graphics.TurnOnAlphaBlending();
  238. bmp.Render(Graphics, 10, 10);
  239. text.SetFPS(fps.GetFPS(), Graphics.Context);
  240. text.SetPosition(position.GetPosition(), Graphics.Context);
  241. text.SetSelectedModel(SelectedModel, Graphics.Context);
  242. text.Render(Graphics.Context, Graphics.GetWorldMatrix(), Graphics.GetOrthoMatrix());
  243. Graphics.TurnOffAlphaBlending();
  244. Graphics.TurnZBufferOn();
  245. Graphics.EndScene();
  246. }
  247. });
  248. }
  249. catch (Exception exception) { }
  250. }
  251. public bool TestIntersection(int mouseX, int mouseY) {
  252. float pointX, pointY;
  253. Matrix projectionMatrix, viewMatrix, inverseViewMatrix;
  254. projectionMatrix = Graphics.GetProjectionMatrix();
  255. pointX = (2.0F * (float)mouseX / (float)pGraphics.ClientSize.Width - 1.0f) / projectionMatrix.M11;
  256. pointY = (-2.0f * (float)mouseY / (float)pGraphics.ClientSize.Height + 1.0f) / projectionMatrix.M22;
  257. Ray ray = new Ray(new Vector3(), new Vector3(pointX, pointY, 1.0f));
  258. viewMatrix = camera.GetViewMatrix();
  259. inverseViewMatrix = Matrix.Invert(viewMatrix);
  260. ray = new Ray(Vector3.TransformCoordinate(ray.Position, inverseViewMatrix), Vector3.TransformNormal(ray.Direction, inverseViewMatrix));
  261. ray.Direction.Normalize();
  262. float selectionDistance = 0.0f;
  263. foreach (Model model in m_Models) {
  264. float distance = model.TestIntersection(ray, Graphics);
  265. if (distance > 0.0f && (selectionDistance == 0.0f || distance < selectionDistance)) {
  266. selectionDistance = distance;
  267. SelectedModel = model;
  268. }
  269. }
  270. return false;
  271. }
  272. public static void AppendLoadFile(String txt)
  273. {
  274. StreamWriter sw = File.AppendText("loaded.txt");
  275. sw.WriteLine(txt);
  276. sw.Close();
  277. }
  278. private void loadZoneToolStripMenuItem_Click(object sender, EventArgs e)
  279. {
  280. LoadZoneFile();
  281. }
  282. public static String DirName = "";
  283. private void LoadZoneFile(String filename="")
  284. {
  285. IsLoaded = false;
  286. bool isDrawFile = false;
  287. string fullName = "";
  288. DirName = "";
  289. if (filename.Length < 1)
  290. {
  291. OpenFileDialog fd = new OpenFileDialog();
  292. fd.Filter = "lut/draw files (*.lut;*.draw)|*.lut;*.draw|lut files (*.lut)|*.lut|draw files (*.draw)|*.draw";
  293. if (fd.ShowDialog() == DialogResult.OK)
  294. {
  295. AppendLoadFile("===================================================");
  296. AppendLoadFile("Loading " + fd.FileName);
  297. if (fd.FileName.EndsWith(".draw"))
  298. {
  299. isDrawFile = true;
  300. string temp = fd.FileName.Substring(0, fd.FileName.LastIndexOf("\\"));
  301. ZoneFile = fd.SafeFileName.Substring(0, fd.SafeFileName.IndexOf(".draw"));
  302. fullName = ZoneFile;
  303. DirName = temp;
  304. filename = fd.FileName;
  305. }
  306. else
  307. {
  308. string temp = fd.FileName.Substring(0, fd.FileName.IndexOf("zones"));
  309. ZoneFile = fd.SafeFileName.Substring(0, fd.SafeFileName.IndexOf(".lut"));
  310. fullName = ZoneFile;
  311. DirName = temp;
  312. filename = fd.FileName;
  313. }
  314. }
  315. }
  316. else
  317. {
  318. if (filename.EndsWith(".draw"))
  319. {
  320. isDrawFile = true;
  321. string temp = filename.Substring(0, filename.LastIndexOf("\\"));
  322. ZoneFile = filename.Substring(0, filename.IndexOf(".draw"));
  323. fullName = filename;
  324. DirName = temp;
  325. }
  326. else
  327. {
  328. string temp = filename.Substring(0, filename.IndexOf("zones"));
  329. ZoneFile = filename.Substring(0, filename.IndexOf(".lut"));
  330. fullName = filename;
  331. DirName = temp;
  332. }
  333. }
  334. if (isDrawFile)
  335. {
  336. Model tmpModel = new Model();
  337. string[] textures = new string[1];
  338. textures[0] = "goblin_ice.dds";
  339. tmpModel.Initialize(Graphics.Device, filename, textures);
  340. tmpModel.Position.X = 0;
  341. tmpModel.Position.Y = 0;
  342. tmpModel.Position.Z = 0;
  343. tmpModel.Rotation.X = 0;
  344. tmpModel.Rotation.Y = 0;
  345. tmpModel.Rotation.Z = 0;
  346. tmpModel.Scale = 1;
  347. tmpModel.WidgetID = 1;
  348. tmpModel.GridID = 1;
  349. m_Models.Add(tmpModel);
  350. return;
  351. }
  352. if (fullName.Length < 1)
  353. {
  354. MessageBox.Show("No filename provided for loading a zonefile!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
  355. return;
  356. }
  357. region_nodes = 0;
  358. if (!File.Exists(filename))
  359. return;
  360. System.IO.BinaryReader reader2 = new System.IO.BinaryReader(new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read));
  361. // Image(2020): Was ReadUint32, qey_harbor.lut however has 00 1F 00 7A, so that as an int32 is a very large number!
  362. reader2.ReadUInt32();
  363. do
  364. {
  365. if (reader2.BaseStream.Position + 2 >= reader2.BaseStream.Length)
  366. {
  367. break;
  368. }
  369. UInt16 size = reader2.ReadUInt16();
  370. string file = new string(reader2.ReadChars(size));
  371. // was duplicating drive name
  372. file = file.Replace("/", "\\");
  373. file = DirName + file;
  374. AppendLoadFile("VOC Loading: " + file);
  375. if ( file.Contains("qey_harbor_qey_terrain_harbor_geo05_rmob_0"))
  376. {
  377. int test = 0;
  378. }
  379. Eq2Reader reader = new Eq2Reader(new System.IO.FileStream(file, System.IO.FileMode.Open, System.IO.FileAccess.Read));
  380. VeNode venode = reader.ReadNodeObject();
  381. CheckNode(DirName, venode, false, null, null, false);
  382. //MessageBox.Show("Done!");
  383. // 16 bytes between file names, grid id's maybe?
  384. reader2.ReadBytes(16);
  385. } while (true);
  386. IsLoaded = true;
  387. }
  388. float x, y, z = 0;
  389. float yaw, pitch, roll = 0;
  390. float scale = 0;
  391. UInt32 widgetID;
  392. UInt32 regionMapVersion = 2;
  393. private void toolStripMenuItemExportWater_Click(object sender, EventArgs e)
  394. {
  395. if (!IsLoaded)
  396. return;
  397. StreamWriter swfile = new StreamWriter(ZoneFile + AppendFileStr + ".regionread");
  398. using (BinaryWriter file = new BinaryWriter(File.Open(ZoneFile + AppendFileStr + ".EQ2Region", FileMode.Create)))
  399. {
  400. file.Write(ZoneFile);
  401. file.Write(regionMapVersion);
  402. file.Write(m_Regions.Count);
  403. Int32 regionNum = 0;
  404. foreach (VeRegion region in m_Regions)
  405. {
  406. file.Write(regionNum);
  407. regionNum += 1;
  408. Int32 node = 0;
  409. file.Write(region.region_type);
  410. file.Write(region.position[0]);
  411. file.Write(region.position[1]);
  412. file.Write(region.position[2]);
  413. file.Write(region.splitdistance);
  414. file.Write(region.envFileChosen);
  415. String outFile = "";
  416. Regex trimmer = new Regex(@"(?!.*\/)(\w|\s|-)+\.region");
  417. Match out_ = trimmer.Match(region.parentNode.regionDefinitionFile);
  418. if (out_.Success && out_.Groups.Count > 0)
  419. outFile = out_.Value;
  420. file.Write(outFile);
  421. file.Write(region.GridID);
  422. file.Write(region.vert_count);
  423. swfile.WriteLine();
  424. swfile.WriteLine("REGION: " + region.position[0] + " " + region.position[1] + " " + region.position[2] + " " + region.splitdistance + " - RegionType: " + region.region_type);
  425. if (region.parentNode.regionDefinitionFile != null)
  426. swfile.WriteLine("REGIONFILE: " + region.parentNode.regionDefinitionFile);
  427. if (region.parentNode.environmentDefinitions != null)
  428. {
  429. foreach (string str in region.parentNode.environmentDefinitions)
  430. swfile.WriteLine("EnvDefinition: " + str);
  431. }
  432. swfile.WriteLine("EnvData: " + region.unkcount + " / " + region.parentNode.unk1 + " / " + region.parentNode.unk2);
  433. for (ushort i = 0; i < region.vert_count; ++i)
  434. {
  435. Int32 regiontype = 1;
  436. Int32 special = region.special;
  437. swfile.WriteLine(node + " " + region.m_normals[i, 0] + " " + region.m_normals[i, 1] + " " +
  438. region.m_normals[i, 2] + " " + region.m_distance[i] + " " + regiontype + " " + special + " " +
  439. region.m_childindex[i, 0] + " " + region.m_childindex[i, 1]);
  440. file.Write(node);
  441. node += 1;
  442. file.Write(region.m_normals[i, 0]);
  443. file.Write(region.m_normals[i, 1]);
  444. file.Write(region.m_normals[i, 2]);
  445. file.Write(region.m_distance[i]);
  446. file.Write(regiontype);
  447. file.Write(special);
  448. file.Write((Int32)region.m_childindex[i, 0]);
  449. file.Write((Int32)region.m_childindex[i, 1]);
  450. }
  451. }
  452. file.Close();
  453. }
  454. swfile.Close();
  455. }
  456. UInt32 GridID;
  457. private void CheckNode(string temp, object item, bool parentXform, object next, object parentNode, bool selectNodeParent)
  458. {
  459. if (item is VeMeshGeometryNode)
  460. {
  461. widgetID = ((VeNode)item).WidgetID;
  462. // testing antonica spires which are not oriented correctly
  463. //if ( widgetID == 2990295910 )
  464. // testing tutorial_island02 boat
  465. //if (== 1253219127)
  466. // tutorial_island02 water
  467. if(widgetID == 337652899)
  468. {
  469. int test = 0;
  470. }
  471. if(widgetID == 625647901)
  472. {
  473. int test = 0;
  474. }
  475. Model model = new Model();
  476. model.Initialize(Graphics.Device, (VeMeshGeometryNode)item, temp);
  477. model.Position.X = x;
  478. model.Position.Y = y;
  479. model.Position.Z = z;
  480. model.Rotation.X = yaw;
  481. model.Rotation.Y = pitch;
  482. model.Rotation.Z = roll;
  483. model.Scale = scale;
  484. model.WidgetID = widgetID;
  485. model.GridID = GridID;
  486. model.nodeFlags = ((VeNode)item).nodeFlags;
  487. m_Models.Add(model);
  488. }
  489. else
  490. {
  491. if (widgetID == 2720558016)
  492. {
  493. int test = 0;
  494. }
  495. float x1 = 0.0f;
  496. float y1 = 0.0f;
  497. float z1 = 0.0f;
  498. if (item is VeEnvironmentNode)
  499. {
  500. String envFile = "";
  501. String writeFileName = "";
  502. VeEnvironmentNode env = (VeEnvironmentNode)item;
  503. bool noFly = false;
  504. if (env.environmentDefinitions != null)
  505. {
  506. foreach (string str in env.environmentDefinitions)
  507. {
  508. if (str.Contains("no_fly.xml"))
  509. {
  510. /* <VdlFile xmlns="Vdl" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="Vdl BaseClasses.xsd">
  511. <Environment VDLTYPE="OBJECT">
  512. <iPriority VDLTYPE="INT">1</iPriority>
  513. <bOverrideZoneAllowFlying VDLTYPE="BOOL">true</bOverrideZoneAllowFlying>
  514. <bAllowFlying VDLTYPE="BOOL">false</bAllowFlying>
  515. </Environment>
  516. </VdlFile>
  517. */
  518. noFly = true;
  519. break;
  520. }
  521. }
  522. }
  523. if (noFly || env.regionDefinitionFile != null && env.regionDefinitionFile.Length > 0)
  524. {
  525. int waterType = 0;
  526. if (!noFly && env.environmentDefinitions != null)
  527. {
  528. foreach (string str in env.environmentDefinitions)
  529. {
  530. writeFileName = str;
  531. Regex trimmer = new Regex(@"(?!.*\/)(\w|\s|-)+\.xml");
  532. Match out_ = trimmer.Match(writeFileName);
  533. if (out_.Success && out_.Groups.Count > 0)
  534. writeFileName = out_.Value;
  535. envFile = str;
  536. envFile = envFile.Replace("/", "\\");
  537. envFile = DirName + envFile;
  538. waterType = LoadEnvXmlParseLiquid(envFile);
  539. if (waterType != 0)
  540. break;
  541. }
  542. }
  543. if (noFly)
  544. {
  545. /* no fly does not have normals in a env.regionDefinitionFile
  546. ** perhaps they expect us to use the VolumeBox at the parent level?
  547. */
  548. }
  549. else
  550. {
  551. bool watervol = env.regionDefinitionFile.Contains("watervol");
  552. bool waterregion = env.regionDefinitionFile.Contains("waterregion");
  553. bool waterregion2 = env.regionDefinitionFile.Contains("water_region");
  554. bool iswater = env.regionDefinitionFile.Contains("water");
  555. bool isocean = env.regionDefinitionFile.Contains("ocean");
  556. bool isvolume = env.regionDefinitionFile.Contains("volume");
  557. AppendLoadFile("Region established: " + waterType + ", " + envFile
  558. + " WaterVol: " + watervol + " WaterRegion: " + waterregion +
  559. " WaterRegion2: " + waterregion2 + " IsWater: " + iswater +
  560. " IsOcean: " + isocean + " IsVolume: " + isvolume);
  561. if (waterType == -2 || waterType == -3) // lava
  562. {
  563. AppendLoadFile("Lava region accepted: " + waterType + ", " + envFile);
  564. Eq2Reader reader2 = new Eq2Reader(new System.IO.FileStream(DirName + env.regionDefinitionFile, System.IO.FileMode.Open, System.IO.FileAccess.Read));
  565. VeRegion region = (VeRegion)reader2.ReadObject();
  566. region.parentNode = env;
  567. region.region_type = 1; // default 'region' algorithm
  568. region.special = -3;
  569. region.envFileChosen = writeFileName;
  570. region.GridID = GridID;
  571. region_nodes += region.vert_count;
  572. m_Regions.Add(region);
  573. }
  574. else if (waterType > 0)
  575. {
  576. AppendLoadFile("Region accepted: " + waterType + ", " + envFile
  577. + " WaterVol: " + watervol + " WaterRegion: " + waterregion +
  578. " WaterRegion2: " + waterregion2 + " IsWater: " + iswater +
  579. " IsOcean: " + isocean + " IsVolume: " + isvolume);
  580. Eq2Reader reader2 = new Eq2Reader(new System.IO.FileStream(DirName + env.regionDefinitionFile, System.IO.FileMode.Open, System.IO.FileAccess.Read));
  581. VeRegion region = (VeRegion)reader2.ReadObject();
  582. region.parentNode = env;
  583. region.region_type = 0; // default water volume
  584. if (waterregion) // 'sea'/ocean/waterregion in tutorial_island02 / qeynos_harbor
  585. region.region_type = 1;
  586. else if (waterregion2)
  587. region.region_type = 0;
  588. else if (isvolume && selectNodeParent)
  589. region.region_type = 4;
  590. else if ((isocean && selectNodeParent)) // ocean in antonica/commonlands/tutorial
  591. region.region_type = 3;
  592. else if (isocean && iswater) // caves in frostfang(halas)
  593. region.region_type = 4;
  594. else if (isocean)
  595. region.region_type = 5;
  596. region.special = waterType;
  597. region_nodes += region.vert_count;
  598. region.envFileChosen = writeFileName;
  599. region.GridID = GridID;
  600. m_Regions.Add(region);
  601. }
  602. else
  603. {
  604. if (env.regionDefinitionFile != null)
  605. {
  606. AppendLoadFile("Region skipped: " + env.regionDefinitionFile);
  607. }
  608. else
  609. AppendLoadFile("Region skipped: ???");
  610. if (env.environmentDefinitions != null)
  611. {
  612. foreach (string str in env.environmentDefinitions)
  613. AppendLoadFile("EnvDefinition: " + str);
  614. }
  615. }
  616. }
  617. }
  618. }
  619. else if (item is VeRoomItemNode)
  620. {
  621. yaw = ((VeRoomItemNode)item).orientation[0];
  622. pitch = ((VeRoomItemNode)item).orientation[1];
  623. roll = ((VeRoomItemNode)item).orientation[2];
  624. GridID = ((VeRoomItemNode)item).myId_grid;
  625. }
  626. else if (item is VeXformNode)
  627. {
  628. VeXformNode tmp = (VeXformNode)item;
  629. x1 = ((VeXformNode)item).position[0];
  630. y1 = ((VeXformNode)item).position[1];
  631. z1 = ((VeXformNode)item).position[2];
  632. if ( x1 < -16.39 && x1 > -16.41)
  633. {
  634. int test = 0;
  635. }
  636. if (parentXform)
  637. {
  638. yaw += (((VeXformNode)item).orientation[0]) * (3.141592654f / 180.0f);
  639. pitch += (((VeXformNode)item).orientation[1]) * (3.141592654f / 180.0f);
  640. roll += (((VeXformNode)item).orientation[2]) * (3.141592654f / 180.0f);
  641. }
  642. else
  643. {
  644. yaw = (((VeXformNode)item).orientation[0]) * (3.141592654f / 180.0f);
  645. pitch = (((VeXformNode)item).orientation[1]) * (3.141592654f / 180.0f);
  646. roll = (((VeXformNode)item).orientation[2]) * (3.141592654f / 180.0f);
  647. }
  648. scale = ((VeXformNode)item).scale;
  649. x += x1;
  650. y += y1;
  651. z += z1;
  652. }
  653. if (item != null)
  654. {
  655. float old_x = x, old_y = y, old_z = z;
  656. float old_yaw = yaw, old_pitch = pitch, old_roll = roll;
  657. float old_scale = scale;
  658. System.Collections.IEnumerator enumerator = ((VeNode)item).EnumerateChildren();
  659. bool parentBool = item is VeXformNode;
  660. bool parentSelect = item is VeSelectNode;
  661. if (enumerator.MoveNext())
  662. {
  663. object prevNode = null;
  664. do
  665. {
  666. object curNode = enumerator.Current;
  667. object nextNode = null;
  668. object newParentNode = parentNode;
  669. if (item is VeXformNode)
  670. newParentNode = item;
  671. else if ((item is VeSelectNode))
  672. newParentNode = item;
  673. if (enumerator.MoveNext())
  674. nextNode = enumerator.Current;
  675. if (prevNode != null && prevNode is VeXformNode)
  676. parentBool = false;
  677. CheckNode(temp, curNode, parentBool, nextNode, newParentNode, selectNodeParent ? true : parentSelect);
  678. prevNode = curNode;
  679. if (nextNode == null)
  680. break;
  681. } while (true);
  682. }
  683. if (parentNode is VeSelectNode && parentBool && !parentXform)
  684. {
  685. x = old_x;
  686. y = old_y;
  687. z = old_z;
  688. yaw = old_yaw;
  689. pitch = old_pitch;
  690. roll = old_roll;
  691. x -= x1;
  692. y -= y1;
  693. z -= z1;
  694. }
  695. else if(parentNode is VeSelectNode && next == null)
  696. {
  697. x = 0;
  698. y = 0;
  699. z = 0;
  700. yaw = 0;
  701. pitch = 0;
  702. roll = 0;
  703. }
  704. else if(parentBool && next != null)
  705. {
  706. x = old_x;
  707. y = old_y;
  708. z = old_z;
  709. if (((VeNode)next).WidgetID != ((VeNode)item).WidgetID)
  710. {
  711. yaw = 0;
  712. pitch = 0;
  713. roll = 0;
  714. }
  715. else
  716. {
  717. yaw = old_yaw;
  718. pitch = old_pitch;
  719. roll = old_roll;
  720. }
  721. x -= x1;
  722. y -= y1;
  723. z -= z1;
  724. }
  725. else
  726. {
  727. x = old_x;
  728. y = old_y;
  729. z = old_z;
  730. yaw = old_yaw;
  731. pitch = old_pitch;
  732. roll = old_roll;
  733. x -= x1;
  734. y -= y1;
  735. z -= z1;
  736. }
  737. }
  738. }
  739. }
  740. public static string[] GetTextureFile(string[] spPath, string basePath)
  741. {
  742. string ret = "goblin_ice.dds";
  743. System.Collections.Generic.List<string> strings = new System.Collections.Generic.List<string>();
  744. int i = 0;
  745. while (i < spPath.Length /*&& ret == "goblin_ice.dds"*/)
  746. {
  747. Eq2Reader reader = new Eq2Reader(new System.IO.FileStream(basePath + spPath[i], System.IO.FileMode.Open, System.IO.FileAccess.Read));
  748. VeBase sp = reader.ReadObject();
  749. reader.Close();
  750. if (sp is VeShaderPalette)
  751. {
  752. bool found = false;
  753. for (int s = 0; s < ((VeShaderPalette)sp).shaderNames.Length; s++)
  754. {
  755. String fileName = basePath + ((VeShaderPalette)sp).shaderNames[s];
  756. fileName = fileName.Replace("/", "\\");
  757. System.IO.StreamReader reader2 = new System.IO.StreamReader(fileName);
  758. while (!reader2.EndOfStream)
  759. {
  760. string lineOrig = reader2.ReadLine();
  761. if (lineOrig.Contains("name = \"@tex") && !lineOrig.Contains("Blend") && !lineOrig.Contains("UVSet"))
  762. {
  763. String line = reader2.ReadLine();
  764. while (line.Length < 1)
  765. line = reader2.ReadLine();
  766. line = line.Substring(line.IndexOf('"') + 1);
  767. line = line.Substring(0, line.Length - 1);
  768. ret = basePath + line;
  769. strings.Add(ret);
  770. found = true;
  771. break;
  772. //break;
  773. }
  774. if (found)
  775. break;
  776. }
  777. reader2.Close();
  778. }
  779. }
  780. i++;
  781. }
  782. if (strings.Count == 0)
  783. strings.Add(ret);
  784. return strings.ToArray();
  785. }
  786. private void exportToolStripMenuItem_Click(object sender, EventArgs e)
  787. {
  788. if (!IsLoaded)
  789. return;
  790. //List<Vector3> MasterVertexList = new List<Vector3>();
  791. Dictionary<UInt32, List<ModelVertexMap>> MasterVertexList = new Dictionary<UInt32, List<ModelVertexMap>>();
  792. foreach (Model model in m_Models)
  793. {
  794. if (model.WidgetID == 1253219127)
  795. {
  796. int test = 0;
  797. }
  798. List<Vector3> VertexList = model.GetVertices();
  799. UInt32 grid = model.GridID;
  800. if (!MasterVertexList.ContainsKey(grid))
  801. MasterVertexList[grid] = new List<ModelVertexMap>();
  802. List<Vector3> convertedVertices = new List<Vector3>();
  803. foreach(Vector3 vect in VertexList)
  804. {
  805. Quaternion rotation = Quaternion.RotationYawPitchRoll(model.Rotation.X, model.Rotation.Y, model.Rotation.Z);
  806. var matrix = Matrix.Identity;
  807. Matrix.RotationQuaternion(ref rotation, out matrix);
  808. Matrix scaled = Matrix.Multiply(matrix, Matrix.Scaling(model.Scale, model.Scale, model.Scale));
  809. Vector3 result = Vector3.Add(Vector3.TransformNormal(vect, scaled), model.Position);
  810. convertedVertices.Add(result);
  811. }
  812. ModelVertexMap mapping = new ModelVertexMap();
  813. mapping.Verts.AddRange(convertedVertices);
  814. mapping.WidgetID = model.WidgetID;
  815. mapping.Position = model.Position;
  816. MasterVertexList[grid].Add(mapping);
  817. }
  818. float minX = float.NaN;
  819. float minY = float.NaN;
  820. float minZ = float.NaN;
  821. float maxX = float.NaN;
  822. float maxY = float.NaN;
  823. float maxZ = float.NaN;
  824. foreach (KeyValuePair<UInt32, List<ModelVertexMap>> entry in MasterVertexList)
  825. {
  826. foreach (ModelVertexMap mvm in entry.Value)
  827. {
  828. foreach (Vector3 v in mvm.Verts)
  829. {
  830. if (float.IsNaN(minX))
  831. {
  832. minX = v.X;
  833. maxX = v.X;
  834. minY = v.Y;
  835. maxY = v.Y;
  836. minZ = v.Z;
  837. maxZ = v.Z;
  838. }
  839. else
  840. {
  841. if (v.X < minX)
  842. minX = v.X;
  843. if (v.X > maxX)
  844. maxX = v.X;
  845. if (v.Y < minY)
  846. minY = v.Y;
  847. if (v.Y > maxY)
  848. minY = v.Y;
  849. if (v.Z < minZ)
  850. minZ = v.Z;
  851. if (v.Z > maxZ)
  852. maxZ = v.Z;
  853. }
  854. }
  855. }
  856. }
  857. if (WriteObjFile)
  858. {
  859. using (StreamWriter file = new StreamWriter(ZoneFile + AppendFileStr + ".obj"))
  860. {
  861. // file.WriteLine(ZoneFile);
  862. // file.WriteLine("Min");
  863. // file.WriteLine(minX + " " + minZ);
  864. // file.WriteLine("Max");
  865. // file.WriteLine(maxX + " " + maxZ);
  866. // file.WriteLine("Grid count");
  867. // file.WriteLine(MasterVertexList.Count);
  868. // file.WriteLine();
  869. List<string> indices = new List<string>();
  870. int count = 0;
  871. string buildStr = "";
  872. int curcount = 0;
  873. foreach (KeyValuePair<UInt32, List<ModelVertexMap>> entry in MasterVertexList)
  874. {
  875. buildStr = "f ";
  876. // file.WriteLine("Grid");
  877. // file.WriteLine(entry.Key);
  878. // file.WriteLine("Face count");
  879. // file.WriteLine(entry.Value.Count);
  880. foreach (ModelVertexMap mvm in entry.Value)
  881. {
  882. foreach (Vector3 v in mvm.Verts)
  883. {
  884. if (curcount > 2)
  885. {
  886. buildStr += count;
  887. indices.Add(buildStr);
  888. buildStr = "f ";
  889. curcount = 0;
  890. }
  891. else
  892. buildStr += count + " ";
  893. file.WriteLine("v " + v.X.ToString() + " " + v.Y.ToString()
  894. + " " + v.Z.ToString());
  895. count++;
  896. curcount++;
  897. }
  898. }
  899. }
  900. foreach (string str in indices)
  901. {
  902. file.WriteLine(str);
  903. }
  904. file.Close();
  905. }
  906. }
  907. UInt32 mapVersion = 3;
  908. String toolName = "EQ2EmuMapTool";
  909. using (BinaryWriter file = new BinaryWriter(File.Open(ZoneFile + AppendFileStr + ".EQ2Map", FileMode.Create)))
  910. {
  911. file.Write(toolName);
  912. file.Write(mapVersion);
  913. file.Write(ZoneFile);
  914. file.Write(minX);
  915. file.Write(minY);
  916. file.Write(minZ);
  917. file.Write(maxX);
  918. file.Write(maxY);
  919. file.Write(maxZ);
  920. file.Write(MasterVertexList.Count);
  921. foreach (KeyValuePair<UInt32, List<ModelVertexMap>> entry in MasterVertexList)
  922. {
  923. file.Write(entry.Key);
  924. file.Write(entry.Value.Count);
  925. foreach (ModelVertexMap mvm in entry.Value)
  926. {
  927. file.Write(mvm.WidgetID);
  928. file.Write(mvm.Position.X);
  929. file.Write(mvm.Position.Y);
  930. file.Write(mvm.Position.Z);
  931. file.Write(mvm.Verts.Count);
  932. foreach (Vector3 v in mvm.Verts)
  933. {
  934. file.Write(v.X);
  935. file.Write(v.Y);
  936. file.Write(v.Z);
  937. }
  938. }
  939. }
  940. file.Close();
  941. }
  942. FileInfo fileToCompress = new FileInfo(ZoneFile + AppendFileStr + ".EQ2Map");
  943. using (FileStream originalFileStream = fileToCompress.OpenRead())
  944. {
  945. if ((File.GetAttributes(fileToCompress.FullName) &
  946. FileAttributes.Hidden) != FileAttributes.Hidden & fileToCompress.Extension != ".gz")
  947. {
  948. using (FileStream compressedFileStream = File.Create(ZoneFile + AppendFileStr + ".EQ2MapDeflated"))
  949. {
  950. using (GZipStream compressionStream = new GZipStream(compressedFileStream,
  951. CompressionMode.Compress))
  952. {
  953. originalFileStream.CopyTo(compressionStream);
  954. }
  955. }
  956. FileInfo info = new FileInfo(ZoneFile + AppendFileStr + ".EQ2MapDeflated");
  957. Console.WriteLine($"Compressed {fileToCompress.Name} from {fileToCompress.Length.ToString()} to {info.Length.ToString()} bytes.");
  958. }
  959. }
  960. if (sender != null)
  961. MessageBox.Show("Export Complete!");
  962. }
  963. private int LoadEnvXmlParseLiquid(string filename)
  964. {
  965. try
  966. {
  967. XmlDocument xmlDoc = new XmlDocument();
  968. xmlDoc.Load(filename);
  969. var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
  970. nsmgr.AddNamespace("vdl", "Vdl");
  971. nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
  972. XmlNode atmosphereNode = xmlDoc.SelectSingleNode("/vdl:VdlFile/vdl:Environment/vdl:iAtmosphere", nsmgr);
  973. if (atmosphereNode != null && Convert.ToInt32(atmosphereNode.InnerText) < 0)
  974. return Convert.ToInt32(atmosphereNode.InnerText); // lava
  975. XmlNode liquidNode = xmlDoc.SelectSingleNode("/vdl:VdlFile/vdl:Environment/vdl:nLiquid", nsmgr);
  976. if (liquidNode != null)
  977. return Convert.ToInt32(liquidNode.InnerText);
  978. }
  979. catch (Exception ex)
  980. {
  981. }
  982. return 0;
  983. }
  984. }
  985. }