Model viewer changes to export region maps

This commit is contained in:
Image 2020-10-14 22:30:22 -04:00
parent 282b783249
commit 0dae7dccb7
6 changed files with 285 additions and 58 deletions
EQ2/devtools/EQ2ModelViewer/EQ2ModelViewer

View file

@ -31,10 +31,11 @@
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.fileToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.loadVPLToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.exitToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pGraphics = new System.Windows.Forms.Panel();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.exportToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripMenuItemExportWater = new System.Windows.Forms.ToolStripMenuItem();
this.menuStrip1.SuspendLayout();
this.SuspendLayout();
//
@ -52,6 +53,7 @@
//
this.fileToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.loadVPLToolStripMenuItem,
this.toolStripMenuItemExportWater,
this.exportToolStripMenuItem,
this.toolStripSeparator2,
this.exitToolStripMenuItem});
@ -62,14 +64,26 @@
// loadVPLToolStripMenuItem
//
this.loadVPLToolStripMenuItem.Name = "loadVPLToolStripMenuItem";
this.loadVPLToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.loadVPLToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.loadVPLToolStripMenuItem.Text = "Load Zone";
this.loadVPLToolStripMenuItem.Click += new System.EventHandler(this.loadZoneToolStripMenuItem_Click);
//
// exportToolStripMenuItem
//
this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
this.exportToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.exportToolStripMenuItem.Text = "Export";
this.exportToolStripMenuItem.Click += new System.EventHandler(this.exportToolStripMenuItem_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(177, 6);
//
// exitToolStripMenuItem
//
this.exitToolStripMenuItem.Name = "exitToolStripMenuItem";
this.exitToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.exitToolStripMenuItem.Size = new System.Drawing.Size(180, 22);
this.exitToolStripMenuItem.Text = "Exit";
this.exitToolStripMenuItem.Click += new System.EventHandler(this.exitToolStripMenuItem_Click);
//
@ -82,17 +96,12 @@
this.pGraphics.Size = new System.Drawing.Size(851, 448);
this.pGraphics.TabIndex = 1;
//
// toolStripSeparator2
// toolStripMenuItemExportWater
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
this.toolStripSeparator2.Size = new System.Drawing.Size(149, 6);
//
// exportToolStripMenuItem
//
this.exportToolStripMenuItem.Name = "exportToolStripMenuItem";
this.exportToolStripMenuItem.Size = new System.Drawing.Size(152, 22);
this.exportToolStripMenuItem.Text = "Export";
this.exportToolStripMenuItem.Click += new System.EventHandler(this.exportToolStripMenuItem_Click);
this.toolStripMenuItemExportWater.Name = "toolStripMenuItemExportWater";
this.toolStripMenuItemExportWater.Size = new System.Drawing.Size(180, 22);
this.toolStripMenuItemExportWater.Text = "Export Water";
this.toolStripMenuItemExportWater.Click += new System.EventHandler(this.toolStripMenuItemExportWater_Click);
//
// frmMain
//
@ -122,6 +131,7 @@
private System.Windows.Forms.ToolStripMenuItem loadVPLToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem exportToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
private System.Windows.Forms.ToolStripMenuItem toolStripMenuItemExportWater;
}
}

View file

@ -2,6 +2,7 @@
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Xml;
using SlimDX;
using SlimDX.D3DCompiler;
@ -16,17 +17,21 @@ using Everquest2.Util;
using Everquest2.Visualization;
using System.IO;
using SlimDX.DirectInput;
using SlimDX.Direct2D;
using System.Security.Permissions;
namespace EQ2ModelViewer
{
public partial class frmMain : Form
{
private System.Collections.Generic.List<Model> m_Models = new System.Collections.Generic.List<Model>();
private System.Collections.Generic.List<VeRegion> m_Regions = new System.Collections.Generic.List<VeRegion>();
private GraphicClass Graphics = new GraphicClass();
public Model SelectedModel = null;
private string ZoneFile;
private bool Render3DAspect = true;
private bool AutoExportOnLoad = false;
private bool AutoExportRegionOnLoad = false;
private String AutoLoadFileName = "";
public frmMain()
{
@ -55,6 +60,7 @@ namespace EQ2ModelViewer
private Key hitKey = Key.NoConvert;
double timestamp = 0;
private CameraClass camera;
int region_nodes = 0;
private void frmMain_Load(object sender, EventArgs e)
{
this.WindowState = FormWindowState.Maximized;
@ -104,6 +110,10 @@ namespace EQ2ModelViewer
{
AutoExportOnLoad = true;
}
else if (cmd.Equals("exportregion"))
{
AutoExportRegionOnLoad = true;
}
else
{
AutoLoadFileName = args[i];
@ -116,6 +126,8 @@ namespace EQ2ModelViewer
LoadZoneFile(AutoLoadFileName);
if (AutoExportOnLoad)
exportToolStripMenuItem_Click(null, EventArgs.Empty);
if (AutoExportRegionOnLoad)
toolStripMenuItemExportWater_Click(null, EventArgs.Empty);
if (!Render3DAspect)
{
@ -228,7 +240,6 @@ namespace EQ2ModelViewer
camera.Render();
//frustum.ConstructFrustum(1000.0f, Graphics.GetProjectionMatrix(), camera.GetViewMatrix());
foreach (Model model in m_Models) {
//if (frustum.CheckSphere(model.Position.X, model.Position.Y, model.Position.Z, 10.0f))
//{
@ -239,7 +250,6 @@ namespace EQ2ModelViewer
//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);
//}
}
// 2D
Graphics.TurnZBufferOff();
Graphics.TurnOnAlphaBlending();
@ -299,12 +309,13 @@ namespace EQ2ModelViewer
LoadZoneFile();
}
public String DirName = "";
private void LoadZoneFile(String filename="")
{
bool isDrawFile = false;
string fullName = "";
String dirName = "";
DirName = "";
if (filename.Length < 1)
{
OpenFileDialog fd = new OpenFileDialog();
@ -320,7 +331,7 @@ namespace EQ2ModelViewer
string temp = fd.FileName.Substring(0, fd.FileName.LastIndexOf("\\"));
ZoneFile = fd.SafeFileName.Substring(0, fd.SafeFileName.IndexOf(".draw"));
fullName = ZoneFile;
dirName = temp;
DirName = temp;
filename = fd.FileName;
}
else
@ -328,7 +339,7 @@ namespace EQ2ModelViewer
string temp = fd.FileName.Substring(0, fd.FileName.IndexOf("zones"));
ZoneFile = fd.SafeFileName.Substring(0, fd.SafeFileName.IndexOf(".lut"));
fullName = ZoneFile;
dirName = temp;
DirName = temp;
filename = fd.FileName;
}
}
@ -341,14 +352,14 @@ namespace EQ2ModelViewer
string temp = filename.Substring(0, filename.LastIndexOf("\\"));
ZoneFile = filename.Substring(0, filename.IndexOf(".draw"));
fullName = filename;
dirName = temp;
DirName = temp;
}
else
{
string temp = filename.Substring(0, filename.IndexOf("zones"));
ZoneFile = filename.Substring(0, filename.IndexOf(".lut"));
fullName = filename;
dirName = temp;
DirName = temp;
}
}
@ -376,7 +387,8 @@ namespace EQ2ModelViewer
MessageBox.Show("No filename provided for loading a zonefile!", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
System.IO.BinaryReader reader2 = new System.IO.BinaryReader(new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read));
region_nodes = 0;
System.IO.BinaryReader reader2 = new System.IO.BinaryReader(new System.IO.FileStream(filename, System.IO.FileMode.Open, System.IO.FileAccess.Read));
// Image(2020): Was ReadUint32, qey_harbor.lut however has 00 1F 00 7A, so that as an int32 is a very large number!
reader2.ReadUInt32();
do
@ -391,13 +403,17 @@ namespace EQ2ModelViewer
// was duplicating drive name
file = file.Replace("/", "\\");
file = dirName + file;
file = DirName + file;
AppendLoadFile("VOC Loading: " + file);
if ( file.Contains("qey_harbor_qey_terrain_harbor_geo05_rmob_0"))
{
int test = 0;
}
Eq2Reader reader = new Eq2Reader(new System.IO.FileStream(file, System.IO.FileMode.Open, System.IO.FileAccess.Read));
VeNode venode = reader.ReadNodeObject();
CheckNode(dirName, venode, false);
CheckNode(DirName, venode, false, false);
//MessageBox.Show("Done!");
@ -410,8 +426,66 @@ namespace EQ2ModelViewer
float yaw, pitch, roll = 0;
float scale = 0;
UInt32 widgetID;
UInt32 regionMapVersion = 1;
private void toolStripMenuItemExportWater_Click(object sender, EventArgs e)
{
StreamWriter swfile = new StreamWriter(ZoneFile + ".regionread");
using (BinaryWriter file = new BinaryWriter(File.Open(ZoneFile + ".EQ2Region", FileMode.Create)))
{
file.Write(ZoneFile);
file.Write(regionMapVersion);
file.Write(m_Regions.Count);
Int32 regionNum = 0;
foreach (VeRegion region in m_Regions)
{
file.Write(regionNum);
regionNum += 1;
Int32 node = 0;
file.Write(region.region_type);
file.Write(region.position[0]);
file.Write(region.position[1]);
file.Write(region.position[2]);
file.Write(region.splitdistance);
file.Write(region.vert_count);
swfile.WriteLine();
swfile.WriteLine("REGION: " + region.position[0] + " " + region.position[1] + " " + region.position[2] + " " + region.splitdistance + " - RegionType: " + region.region_type);
if (region.parentNode.regionDefinitionFile != null)
swfile.WriteLine("REGIONFILE: " + region.parentNode.regionDefinitionFile);
if (region.parentNode.environmentDefinitions != null)
{
foreach (string str in region.parentNode.environmentDefinitions)
swfile.WriteLine("EnvDefinition: " + str);
}
swfile.WriteLine("EnvData: " + region.unkcount + " / " + region.parentNode.unk1 + " / " + region.parentNode.unk2);
for (ushort i = 0; i < region.vert_count; ++i)
{
Int32 regiontype = 1;
Int32 special = region.special;
swfile.WriteLine(node + " " + region.m_normals[i, 0] + " " + region.m_normals[i, 1] + " " +
region.m_normals[i, 2] + " " + region.m_distance[i] + " " + regiontype + " " + special + " " +
region.m_childindex[i, 0] + " " + region.m_childindex[i, 1]);
file.Write(node);
node += 1;
file.Write(region.m_normals[i, 0]);
file.Write(region.m_normals[i, 1]);
file.Write(region.m_normals[i, 2]);
file.Write(region.m_distance[i]);
file.Write(regiontype);
file.Write(special);
file.Write((Int32)region.m_childindex[i, 0]);
file.Write((Int32)region.m_childindex[i, 1]);
}
}
file.Close();
}
swfile.Close();
}
UInt32 GridID;
private void CheckNode(string temp, object item, bool parentXform)
private void CheckNode(string temp, object item, bool parentXform, bool selectNodeParent)
{
if (item is VeMeshGeometryNode)
{
@ -422,6 +496,15 @@ namespace EQ2ModelViewer
// testing tutorial_island02 boat
//if (widgetID == 1253219127)
// tutorial_island02 water
if(widgetID == 1864854785)
{
int test = 0;
}
if(widgetID == 2720558016)
{
int test = 0;
}
Model model = new Model();
model.Initialize(Graphics.Device, (VeMeshGeometryNode)item, temp);
model.Position.X = x;
@ -437,10 +520,93 @@ namespace EQ2ModelViewer
}
else
{
if (widgetID == 2720558016)
{
int test = 0;
}
float x1 = 0.0f;
float y1 = 0.0f;
float z1 = 0.0f;
if (item is VeRoomItemNode)
if (item is VeEnvironmentNode)
{
VeEnvironmentNode env = (VeEnvironmentNode)item;
if (env.regionDefinitionFile != null && env.regionDefinitionFile.Length > 0)
{
int waterType = 0;
String envFile = "";
if (env.environmentDefinitions != null)
{
foreach (string str in env.environmentDefinitions)
{
envFile = str;
envFile = envFile.Replace("/", "\\");
envFile = DirName + envFile;
waterType = LoadEnvXmlParseLiquid(envFile);
if (waterType != 0)
break;
}
}
bool watervol = env.regionDefinitionFile.Contains("watervol");
bool waterregion = env.regionDefinitionFile.Contains("waterregion");
bool waterregion2 = env.regionDefinitionFile.Contains("water_region");
bool iswater = env.regionDefinitionFile.Contains("water");
bool isocean = env.regionDefinitionFile.Contains("ocean");
bool isvolume = env.regionDefinitionFile.Contains("volume");
AppendLoadFile("Region established: " + waterType + ", " + envFile
+ " WaterVol: " + watervol + " WaterRegion: " + waterregion +
" WaterRegion2: " + waterregion2 + " IsWater: " + iswater +
" IsOcean: " + isocean + " IsVolume: " + isvolume);
if (waterType>0)
{
AppendLoadFile("Region accepted: " + waterType + ", " + envFile
+ " WaterVol: " + watervol + " WaterRegion: " + waterregion +
" WaterRegion2: " + waterregion2 + " IsWater: " + iswater +
" IsOcean: " + isocean + " IsVolume: " + isvolume);
Eq2Reader reader2 = new Eq2Reader(new System.IO.FileStream(DirName + env.regionDefinitionFile, System.IO.FileMode.Open, System.IO.FileAccess.Read));
VeRegion region = (VeRegion)reader2.ReadObject();
region.parentNode = env;
region.region_type = 0; // default water volume
if (waterregion) // 'sea'/ocean/waterregion in tutorial_island02 / qeynos_harbor
region.region_type = 1;
else if (waterregion2)
region.region_type = 0;
else if (isvolume && selectNodeParent)
region.region_type = 4;
else if ((isocean && selectNodeParent)) // ocean in antonica/commonlands/tutorial
region.region_type = 3;
else if (isocean && iswater) // caves in frostfang(halas)
region.region_type = 4;
else if (isocean)
region.region_type = 5;
region.special = waterType;
MeshClass tmpMesh = new MeshClass();
region_nodes += region.vert_count;
m_Regions.Add(region);
}
else
{
if (env.regionDefinitionFile != null)
{
AppendLoadFile("Region skipped: " + env.regionDefinitionFile);
}
else
AppendLoadFile("Region skipped: ???");
if (env.environmentDefinitions != null)
{
foreach (string str in env.environmentDefinitions)
AppendLoadFile("EnvDefinition: " + str);
}
}
}
}
else if (item is VeRoomItemNode)
{
yaw = ((VeRoomItemNode)item).orientation[0];
pitch = ((VeRoomItemNode)item).orientation[1];
@ -482,9 +648,10 @@ namespace EQ2ModelViewer
System.Collections.IEnumerator enumerator = ((VeNode)item).EnumerateChildren();
bool parentBool = item is VeXformNode;
bool selectNode = item is VeSelectNode;
while (enumerator.MoveNext())
{
CheckNode(temp, enumerator.Current, parentBool);
CheckNode(temp, enumerator.Current, parentBool, selectNodeParent ? true : selectNode);
}
x = old_x;
@ -689,5 +856,29 @@ namespace EQ2ModelViewer
if (sender != null)
MessageBox.Show("Export Complete!");
}
private int LoadEnvXmlParseLiquid(string filename)
{
try
{
XmlDocument xmlDoc = new XmlDocument();
xmlDoc.Load(filename);
var nsmgr = new XmlNamespaceManager(xmlDoc.NameTable);
nsmgr.AddNamespace("vdl", "Vdl");
nsmgr.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
XmlNode atmosphereNode = xmlDoc.SelectSingleNode("/vdl:VdlFile/vdl:Environment/vdl:iAtmosphere", nsmgr);
if (atmosphereNode != null && Convert.ToInt32(atmosphereNode.InnerText) < 0)
return Convert.ToInt32(atmosphereNode.InnerText); // lava
XmlNode liquidNode = xmlDoc.SelectSingleNode("/vdl:VdlFile/vdl:Environment/vdl:nLiquid", nsmgr);
if (liquidNode != null)
return Convert.ToInt32(liquidNode.InnerText);
}catch(Exception ex)
{
}
return 0;
}
}
}

View file

@ -115,6 +115,15 @@ namespace EQ2ModelViewer
context.InputAssembler.SetIndexBuffer(m_IndexBuffer, Format.R32_UInt, 0);
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
}
public void RenderBuffersExt(DeviceContext context)
{
int stride = System.Runtime.InteropServices.Marshal.SizeOf(typeof(EQ2Region));
int offset = 0;
context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(m_VertexBuffer, stride, offset));
context.InputAssembler.SetIndexBuffer(m_IndexBuffer, Format.R32_UInt, 0);
context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
}
public void ShutDown()
{
@ -130,12 +139,16 @@ namespace EQ2ModelViewer
public ShaderResourceView GetTexture()
{
if (m_Texture == null)
return null;
return m_Texture.GetTexture();
}
private void ReleaseTexture()
{
m_Texture.ShutDown();
if (m_Texture != null)
m_Texture.ShutDown();
}
public bool LoadTexture(Device device, string filename)

View file

@ -165,6 +165,9 @@ namespace EQ2ModelViewer
foreach (MeshClass mesh in m_meshes)
{
if (mesh.GetTexture() == null)
continue;
mesh.RenderBuffers(Graphics.Context);
lightShader.Render(Graphics.Context, mesh.GetIndexCount(), temp, camera.GetViewMatrix(), Graphics.GetProjectionMatrix(), mesh.GetTexture(), new Vector3(0.0f, 0.0f, 0.0f), ambientColor/*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);
}

View file

@ -50,7 +50,10 @@ namespace Everquest2.Visualization
bool hasRegionDefinition = reader.ReadBoolean();
if (hasRegionDefinition) regionDefinitionFile = reader.ReadString(2);
if (hasRegionDefinition)
{
regionDefinitionFile = reader.ReadString(2);
}
byte environmentDefinitionCount = reader.ReadByte();
@ -66,17 +69,19 @@ namespace Everquest2.Visualization
if (classVersion >= 2)
{
//4 bytes, not sure if its a float
float unk1 = reader.ReadSingle();
unk1 = reader.ReadInt32();
}
if (classVersion >= 3)
{
byte unk2 = reader.ReadByte();
unk2 = reader.ReadByte();
}
}
public string regionDefinitionFile;
public string[] environmentDefinitions;
public int unk1 = 0;
public int unk2 = 0;
}
}

View file

@ -46,43 +46,48 @@ namespace Everquest2.Visualization {
if (classVersion == 0) unk0 = reader.ReadSingle();
ushort count = reader.ReadUInt16();
unk1 = new float[count, 3];
unk2 = new float[count];
unk3 = new short[count, 2];
vert_count = count;
m_normals = new float[count, 3];
m_distance = new float[count];
m_childindex = new short[count, 2];
for (ushort i = 0; i < count; ++i) {
unk1[i, 0] = reader.ReadSingle();
unk1[i, 1] = reader.ReadSingle();
unk1[i, 2] = reader.ReadSingle();
unk2[i] = reader.ReadSingle();
unk3[i, 0] = reader.ReadInt16();
unk3[i, 1] = reader.ReadInt16();
m_normals[i, 0] = reader.ReadSingle();
m_normals[i, 1] = reader.ReadSingle();
m_normals[i, 2] = reader.ReadSingle();
m_distance[i] = reader.ReadSingle();
m_childindex[i, 0] = reader.ReadInt16();
m_childindex[i, 1] = reader.ReadInt16();
}
if (classVersion >= 2) {
uint unkcount = reader.ReadUInt32();
float[,] unk6 = new float[unkcount, 4];
unkcount = reader.ReadUInt32();
m_center = new float[unkcount, 4];
for (int i = 0; i < unkcount; i++) {
unk6[i, 0] = reader.ReadSingle();
unk6[i, 1] = reader.ReadSingle();
unk6[i, 2] = reader.ReadSingle();
unk6[i, 3] = reader.ReadSingle();
m_center[i, 0] = reader.ReadSingle();
m_center[i, 1] = reader.ReadSingle();
m_center[i, 2] = reader.ReadSingle();
m_center[i, 3] = reader.ReadSingle();
}
}
unk4[0] = reader.ReadSingle();
unk4[1] = reader.ReadSingle();
unk4[2] = reader.ReadSingle();
unk5 = reader.ReadSingle();
position[0] = reader.ReadSingle();
position[1] = reader.ReadSingle();
position[2] = reader.ReadSingle();
splitdistance = reader.ReadSingle();
}
private float unk0;
private float[,] unk1;
private float[] unk2;
private short[,] unk3;
private float[] unk4 = new float[3];
private float unk5;
public int vert_count;
public float unk0;
public uint unkcount;
public float[,] m_normals;
public float[] m_distance;
public short[,] m_childindex;
public float[] position = new float[3];
public float splitdistance;
public VeEnvironmentNode parentNode;
float[,] m_center; // 1-3 is vector center, 4th is radius
public int region_type;
public int special = 0;
}
}