private void exportTo3DSToolStripMenuItem_Click(object sender, EventArgs e) { int n; if (stm != null) { n = stm.index; } else if (skm != null) { n = skm.MyIndex; } else { return; } if (pcc.Exports[n].ClassName == "StaticMesh") { SaveFileDialog d = new SaveFileDialog(); d.Filter = "*.3ds|*.3ds"; if (d.ShowDialog() == DialogResult.OK) { if (File.Exists(d.FileName)) { File.Delete(d.FileName); } PSKFile p = stm.ExportToPsk(); Helper3DS.ConvertPSKto3DS(p, d.FileName); MessageBox.Show("Done."); } } }
private void openToolStripMenuItem_Click(object sender, EventArgs e) { OpenFileDialog d = new OpenFileDialog(); d.Filter = "*.psk|*.psk;*.pskx"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { string path = d.FileName; psk = new PSKFile(); psk.ImportPSK(path); CurrFile = path; RefreshTree(); } }
private void toolStripButton2_Click(object sender, EventArgs e) { if (mesh == null) { return; } SaveFileDialog d = new SaveFileDialog(); d.Filter = "*.psk|*.psk"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { PSKFile psk = new PSKFile(mesh); psk.Export(d.FileName); MessageBox.Show("Done."); } }
private void exportTo3DSToolStripMenuItem_Click(object sender, EventArgs e) { int n = listBox1.SelectedIndex; if (n == -1 | pcc == null) { return; } if (pcc.Exports[Objects[n].index].ClassName == "StaticMesh") { SaveFileDialog d = new SaveFileDialog(); d.Filter = "*.3ds|*.3ds"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { if (File.Exists(d.FileName)) { File.Delete(d.FileName); } PSKFile p = stm.ExportToPsk(); Helper3DS.ConvertPSKto3DS(p, d.FileName); MessageBox.Show("Done."); } } }
private void toolStripButton2_Click(object sender, EventArgs e) { if (mesh == null) return; SaveFileDialog d = new SaveFileDialog(); d.Filter = "*.psk|*.psk"; if (d.ShowDialog() == System.Windows.Forms.DialogResult.OK) { PSKFile psk = new PSKFile(mesh); psk.Export(d.FileName); MessageBox.Show("Done."); } }
public Vector3 ToVec3(PSKFile.PSKPoint p) { return new Vector3(p.x, p.y, p.z); }
public void ImportFromPsk(string path, int lod) { DebugOutput.Clear(); DebugOutput.PrintLn("Loading \"" + Path.GetFileName(path) + "\"..."); psk = new PSKFile(); //source psk object psk.ImportPSK(path); //load file LOD l = Mesh.LODs[lod]; //target LOD object l.Indexes = new List<ushort>(); //Init l.Headers = new List<LODHeader>(); l.UnkSec1 = new List<UnknownSection>(); DebugOutput.PrintLn("Creating bone conversion table..."); List<int> pskBone2skm = new List<int>(); //to convert psk boneindex to skm boneindex foreach (PSKFile.PSKBone b in psk.psk.bones) //loop all psk bones for (int i = 0; i < Mesh.Bones.Count; i++) //for each loop all skm bones if (b.name.TrimEnd(' ') == pcc.getNameEntry(Mesh.Bones[i].name)) //if match, ... { pskBone2skm.Add(i); //...then add if (MPOpt.SKM_importbones) { Bone t = Mesh.Bones[i]; t.position = b.location.ToVector3(); t.orientation = new Quad(b.rotation.ToVector4()); t.position.Y *= -1; t.orientation.y *= -1; if (i == 0) t.orientation.w *= -1; Mesh.Bones[i] = t; } break; //break search for match on this bone } DebugOutput.PrintLn("Importing Materials..."); if (psk.psk.materials.Count > Mesh.Materials.Count()) //If more Materials are needed to import { int count = psk.psk.materials.Count - Mesh.Materials.Count(); int mat = Mesh.Materials[0]; for (int i = 0; i < count; i++) Mesh.Materials.Add(mat); //Fill up with first material used } l.UnkCount1 = psk.psk.materials.Count; DebugOutput.PrintLn("Importing Indexes..."); int facesoffset = 0; //faceoffset for current section for (int i = 0; i < psk.psk.materials.Count; i++) //Section count = Material Count { int count = 0; //Face count of this section LODHeader h = new LODHeader(); //Header object for Current Section h.index = (ushort)i; //yeah same as material h.matindex = (ushort)i; //yeah same as material h.offset = (ushort)facesoffset; //offset in index buffer foreach (PSKFile.PSKFace f in psk.psk.faces) //go through all faces if (f.material == i) //Face has current material? { l.Indexes.Add((ushort)psk.psk.edges[f.v0].index); //add corners to index buffer l.Indexes.Add((ushort)psk.psk.edges[f.v2].index); l.Indexes.Add((ushort)psk.psk.edges[f.v1].index); //culling swap facesoffset += 3; //3 indexes added count++; //1 face added } h.count = (uint)count; //sum faces h.unk1 = 0; //always zero l.Headers.Add(h); //add new header } l.Edges = new List<Edge>(); //reset edge list, first step: import coords and UVS DebugOutput.PrintLn("Importing Vertices and UVs..."); for (int i = 0; i < psk.psk.points.Count; i++) //loop all edges/vertices in psk { Edge ne = new Edge(); //the new skm edge PSKFile.PSKEdge e = new PSKFile.PSKEdge(); PSKFile.PSKPoint p = psk.psk.points[i]; //actual point from psk foreach(PSKFile.PSKEdge t in psk.psk.edges) if (t.index == i) { e = t; break; } ne.Position = p.ToVector3(); //set coords&UVs ne.Position.Y *= -1; //flip Y axis ne.UV = new Vector2(e.U, e.V); //offsets for light fix ne.Influences = new List<Influence>(); //prepare foreach (PSKFile.PSKWeight w in psk.psk.weights) if (w.point == i) ne.Influences.Add(new Influence(w.weight, pskBone2skm[w.bone])); ne.Unk1 = 0; //tangent space quad1 ne.Unk2 = 0; //tangent space quad2 l.Edges.Add(ne); } DebugOutput.PrintLn("Adding Dup Influences..."); int ccnt = 0; int ccnt2 = 0; foreach (Edge e in l.Edges) { bool done = false; if (e.Influences.Count() == 0) { foreach (Edge e2 in l.Edges) if (e2.Position == e.Position && e2.Influences.Count() != 0 && !done) { foreach (Influence i in e2.Influences) { Influence ni; ni.bone = i.bone; ni.weight = i.weight; e.Influences.Add(ni); } done = true; ccnt2++; } else if (done) break; ccnt++; } } for (int i = 0; i < l.Edges.Count; i++) { List<Influence> tinf = new List<Influence>(); for (int j = 0; j < l.Edges[i].Influences.Count; j++) if (l.Edges[i].Influences[j].weight > 0) tinf.Add(l.Edges[i].Influences[j]); Edge e = l.Edges[i]; e.Influences = tinf; l.Edges[i] = e; } List<int> tempidx = new List<int>(); for (int i = 0; i < l.Edges.Count; i++) if (l.Edges[i].Influences.Count == 1) tempidx.Add(i); for (int i = 0; i < l.Edges.Count; i++) if (l.Edges[i].Influences.Count > 1) tempidx.Add(i); List<Edge> tmpedges = new List<Edge>(); foreach (int n in tempidx) tmpedges.Add(l.Edges[n]); l.Edges = tmpedges; for(int i=0;i<l.Indexes.Count;i++) for(int j=0;j<tmpedges.Count;j++) if (tempidx[j] == l.Indexes[i]) { l.Indexes[i] = (ushort)j; break; } DebugOutput.PrintLn(ccnt + " " + ccnt2 + " Filling up Influences..."); foreach (Edge e in l.Edges) //loop all edges and fill up influences to 4 { int count = e.Influences.Count(); //current influence count for (int i = count; i < 4; i++) //add until 4 e.Influences.Add(new Influence(0, 0)); //add placeholder } DebugOutput.PrintLn("Creating active bone list..."); l.ActiveBones = new List<byte>(); //Init List, Get Active Bone List l.ActiveBones.Add(0); //add god node foreach (Edge e in l.Edges) //loop all edges for (int i = 0; i < 4; i++) //and each influence if (e.Influences[i].weight != 0) //if has influence { byte bone = e.Influences[i].bone; //get bone bool found = false; //search if already in list for (int j = 0; j < l.ActiveBones.Count; j++) if (l.ActiveBones[j] == bone) found = true; if (!found) //if not in list, add l.ActiveBones.Add(bone); } l.ActiveBones.Sort(); //Sort list int lastbone = l.ActiveBones[l.ActiveBones.Count - 1]; l.ActiveBones = new List<byte>(); for (byte i = 0; i <= lastbone; i++) l.ActiveBones.Add(i); DebugOutput.PrintLn("Creating sub bone lists..."); foreach (LODHeader h in l.Headers) //Get sub bonelists, loop each section { UnknownSection s = new UnknownSection(); //init s.Unkn = new byte[24]; //zero for now, !!!TODO!!! s.Indexes = new List<ushort>(); foreach (byte b in l.ActiveBones) s.Indexes.Add(b); //sort list l.UnkSec1.Add(s); //add this section } DebugOutput.PrintLn("Creating unknown bone list..."); l.UnkIndexes1 = new List<ushort>(); foreach (byte b in l.ActiveBones) l.UnkIndexes1.Add(b); int edgeoffset = 0; DebugOutput.PrintLn("Creating unknown sections..."); for (int i = 0; i < l.Headers.Count; i++) //update values in unknown section { LODHeader h = l.Headers[i]; int pos = (int)h.offset; int maxsimple = -1; int maxmulti = -1; int minsimple = l.Edges.Count; int minmulti = l.Edges.Count; int lensimple = 0, lenmulti = 0; for (int j = 0; j < h.count * 3; j++) //determine min,max edge indexes { Edge e = l.Edges[l.Indexes[pos]]; int index = l.Indexes[pos]; int count = 0; foreach (Influence inf in e.Influences) if (inf.weight != 0) count++; if (count == 0) { MessageBox.Show("Error: Found vertex without influences!"); return; } if (count == 1) { if (index < minsimple) minsimple = index; if (index > maxsimple) maxsimple = index; } if (count > 1) { if (index < minmulti) minmulti = index; if (index > maxmulti) maxmulti = index; } pos++; } lensimple = (maxsimple - minsimple) + 1; lenmulti = (maxmulti - minmulti) + 1; lensimple = Math.Max(lensimple, 0); lenmulti = Math.Max(lenmulti, 0); byte[] buff = BitConverter.GetBytes(lensimple); for (int j = 0; j < 4; j++) l.UnkSec1[i].Unkn[j] = buff[j]; buff = BitConverter.GetBytes(lenmulti); for (int j = 0; j < 4; j++) l.UnkSec1[i].Unkn[j + 4] = buff[j]; l.UnkSec1[i].Unkn[8] = 4; int sum = lensimple + lenmulti; edgeoffset += sum; if (i == l.Headers.Count - 1) { buff = BitConverter.GetBytes(edgeoffset); for (int j = 0; j < 4; j++) l.UnkSec1[i].Unkn[j + 16] = buff[j]; } else { buff = BitConverter.GetBytes(edgeoffset); for (int j = 0; j < 4; j++) l.UnkSec1[i].Unkn[j + 12] = buff[j]; } } DebugOutput.PrintLn("Calculating 4D tangent space quaternions..."); CalcTangentSpace2(l); //Calc 4D Tangents DebugOutput.PrintLn("Done."); DebugOutput.PrintLn("Saving pcc..."); Mesh.LODs[lod] = l; //assign lod }
private void WriteChild(TreeNode t, int index,PSKFile.PSKContainer PSK) { int bn = Convert.ToInt32(t.Text); PSKFile.PSKBone b = new PSKFile.PSKBone(); Bone mb = Mesh.Bones[bn]; b.name = pcc.getNameEntry(mb.name); b.childs = mb.childcount; int p = 0; if (t.Parent != null) p = Convert.ToInt32(t.Parent.Text); if (bn != 0) b.parent = Mesh.Bones[p].index; else b.parent = 0; mb.index = bonecount; Mesh.Bones[bn] = mb; b.location.x = mb.position.X; b.location.y = mb.position.Y *-1; b.location.z = mb.position.Z; b.rotation.x = mb.orientation.x; b.rotation.y = mb.orientation.y; b.rotation.z = mb.orientation.z; b.rotation.w = mb.orientation.w; if (bn == 0) b.rotation.w *= -1; b.rotation.y *= -1; PSK.bones.Add(b); bonecount++; }
private void WriteBone(TreeNode t,PSKFile.PSKContainer PSK) { int bn = Convert.ToInt32(t.Text); WriteChild(t, bonecount,PSK); for (int i = 0; i < t.Nodes.Count; i++) WriteBone(t.Nodes[i],PSK); }
public PSKFile.PSKContainer WriteWeights(PSKFile.PSKContainer PSK, int lod) { PSK.weights = new List<PSKFile.PSKWeight>(); for (int i = 0; i < Mesh.LODs[lod].Edges.Count; i++) { Edge e = Mesh.LODs[lod].Edges[i]; e._imported = false; Mesh.LODs[lod].Edges[i] = e; } for (int i = 0; i < Mesh.LODs[lod].Headers.Count; i++) { LOD l = Mesh.LODs[lod]; LODHeader h = l.Headers[i]; int start = (int)h.offset; int count = (int)h.count * 3; for (int j = start; j < start + count; j++) { int index = l.Indexes[j]; Edge e = l.Edges[index]; if (!e._imported) { for (int k = 0; k < 4; k++) { float w = e.Influences[k].weight / 255f; if (w != 0) { int bone = e.Influences[k].bone; //THIS IS bone = l.UnkSec1[i].Indexes[bone]; //BEYOND bone = Mesh.Bones[bone].index; //Ridiculose PSK.weights.Add(new PSKFile.PSKWeight(w, index, bone)); } } e._imported = true; Mesh.LODs[lod].Edges[index] = e; } } } for (int i = 0; i < Mesh.LODs[lod].Edges.Count; i++) { bool found = false; Edge e = Mesh.LODs[lod].Edges[i]; for (int j = 0; j < PSK.weights.Count; j++) if (PSK.weights[j].point == i) found = true; if(!found) PSK.weights.Add(new PSKFile.PSKWeight(1.0f, i, 0)); } return PSK; }
public PSKFile.PSKContainer WriteBones(PSKFile.PSKContainer PSK) { bonecount = 0; TreeNode rootbone = new TreeNode("0"); rootbone = GetChild(rootbone); PSK.bones = new List<PSKFile.PSKBone>(); WriteBone(rootbone, PSK); return PSK; }
public void ExportToPsk(string path,int LOD) { PSKFile.PSKContainer pskc = new PSKFile.PSKContainer(); LOD l = Mesh.LODs[LOD]; pskc = WriteBones(pskc); pskc = WriteWeights(pskc,LOD); pskc.points = new List<PSKFile.PSKPoint>(); pskc.edges = new List<PSKFile.PSKEdge>(); for (int i = 0; i < l.Edges.Count; i++) { Edge e =l.Edges[i]; Vector3 p = e.Position; p.Y *= -1; pskc.points.Add(new PSKFile.PSKPoint(p)); pskc.edges.Add(new PSKFile.PSKEdge((short)i,e.UV,0)); } pskc.faces = new List<PSKFile.PSKFace>(); foreach (LODHeader h in l.Headers) { for (int i = 0; i < h.count; i++) { PSKFile.PSKFace f = new PSKFile.PSKFace(l.Indexes[(int)h.offset + i * 3], l.Indexes[(int)h.offset + i * 3 + 2], l.Indexes[(int)h.offset + i * 3 + 1], (byte)h.matindex); pskc.faces.Add(f); PSKFile.PSKEdge e = pskc.edges[f.v0]; e.material = (byte)h.matindex; pskc.edges[f.v0] = e; e = pskc.edges[f.v1]; e.material = (byte)h.matindex; pskc.edges[f.v1] = e; e = pskc.edges[f.v2]; e.material = (byte)h.matindex; pskc.edges[f.v2] = e; } } pskc.materials = new List<PSKFile.PSKMaterial>(); foreach (int i in Mesh.Materials) pskc.materials.Add(new PSKFile.PSKMaterial(pcc.getObjectName(i), 0)); psk = new PSKFile(); psk.psk = pskc; psk.Export(path); }