public KCL(byte[] Data) { EndianBinaryReader er = new EndianBinaryReader(new MemoryStream(Data), Endianness.LittleEndian); try { Header = new MK7KCLHeader(er); er.BaseStream.Position = Header.VerticesOffset; uint nr = (Header.NormalsOffset - Header.VerticesOffset) / 0xC; Vertices = new Vector3[nr]; for (int i = 0; i < nr; i++) { Vertices[i] = er.ReadVector3(); } er.BaseStream.Position = Header.NormalsOffset; nr = (Header.PlanesOffset - Header.NormalsOffset) / 0xC; Normals = new Vector3[nr]; for (int i = 0; i < nr; i++) { Normals[i] = er.ReadVector3(); } er.BaseStream.Position = Header.PlanesOffset; nr = (Header.OctreeOffset - Header.PlanesOffset) / 0x10; Planes = new KCLPlane[nr]; for (int i = 0; i < nr; i++) { Planes[i] = new KCLPlane(er); } er.BaseStream.Position = Header.OctreeOffset; int nodes = (int)( ((~Header.XMask >> (int)Header.CoordShift) + 1) * ((~Header.YMask >> (int)Header.CoordShift) + 1) * ((~Header.ZMask >> (int)Header.CoordShift) + 1)); Octree = new KCLOctree(er, nodes); } finally { er.Close(); } }
public static KCLOctree FromTriangles(Triangle[] Triangles, MK7KCLHeader Header, int MaxRootSize = 2048, int MinRootSize = 128, int MinCubeSize = 32, int MaxNrTris = 10)//35) { Header.Unknown1 = 30; Header.Unknown2 = 25; Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue); Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue); Dictionary <ushort, Triangle> tt = new Dictionary <ushort, Triangle>(); ushort index = 0; foreach (var t in Triangles) { if (t.PointA.X < min.X) { min.X = t.PointA.X; } if (t.PointA.Y < min.Y) { min.Y = t.PointA.Y; } if (t.PointA.Z < min.Z) { min.Z = t.PointA.Z; } if (t.PointA.X > max.X) { max.X = t.PointA.X; } if (t.PointA.Y > max.Y) { max.Y = t.PointA.Y; } if (t.PointA.Z > max.Z) { max.Z = t.PointA.Z; } if (t.PointB.X < min.X) { min.X = t.PointB.X; } if (t.PointB.Y < min.Y) { min.Y = t.PointB.Y; } if (t.PointB.Z < min.Z) { min.Z = t.PointB.Z; } if (t.PointB.X > max.X) { max.X = t.PointB.X; } if (t.PointB.Y > max.Y) { max.Y = t.PointB.Y; } if (t.PointB.Z > max.Z) { max.Z = t.PointB.Z; } if (t.PointC.X < min.X) { min.X = t.PointC.X; } if (t.PointC.Y < min.Y) { min.Y = t.PointC.Y; } if (t.PointC.Z < min.Z) { min.Z = t.PointC.Z; } if (t.PointC.X > max.X) { max.X = t.PointC.X; } if (t.PointC.Y > max.Y) { max.Y = t.PointC.Y; } if (t.PointC.Z > max.Z) { max.Z = t.PointC.Z; } tt.Add(index, t); index++; } //in real mkds, 25 is subtracted from the min pos min -= new Vector3(25, 25, 25); //TODO: after that, from some of the components (may be more than one) 30 is subtracted aswell => How do I know from which ones I have to do that? //Assume the same is done for max: max += new Vector3(25, 25, 25); //TODO: +30 Header.OctreeOrigin = min; Vector3 size = max - min; float mincomp = Math.Min(Math.Min(size.X, size.Y), size.Z); int CoordShift = MathUtil.GetNearest2Power(mincomp); if (CoordShift > MathUtil.GetNearest2Power(MaxRootSize)) { CoordShift = MathUtil.GetNearest2Power(MaxRootSize); } //else if (CoordShift < Get2Power(MinRootSize)) CoordShift = Get2Power(MinRootSize); Header.CoordShift = (uint)CoordShift; int cubesize = 1 << CoordShift; int NrX = (1 << MathUtil.GetNearest2Power(size.X)) / cubesize; int NrY = (1 << MathUtil.GetNearest2Power(size.Y)) / cubesize; int NrZ = (1 << MathUtil.GetNearest2Power(size.Z)) / cubesize; if (NrX <= 0) { NrX = 1; } if (NrY <= 0) { NrY = 1; } if (NrZ <= 0) { NrZ = 1; } Header.YShift = (uint)(MathUtil.GetNearest2Power(size.X) - CoordShift); Header.ZShift = (uint)(MathUtil.GetNearest2Power(size.X) - CoordShift + MathUtil.GetNearest2Power(size.Y) - CoordShift); Header.XMask = 0xFFFFFFFF << MathUtil.GetNearest2Power(size.X); Header.YMask = 0xFFFFFFFF << MathUtil.GetNearest2Power(size.Y); Header.ZMask = 0xFFFFFFFF << MathUtil.GetNearest2Power(size.Z); KCLOctree k = new KCLOctree(); k.RootNodes = new KCLOctreeNode[NrX * NrY * NrZ]; int i = 0; int maxOCtree = NrX * NrY * NrZ; for (int z = 0; z < NrZ; z++) { for (int y = 0; y < NrY; y++) { for (int x = 0; x < NrX; x++) { Vector3 pos = min + ((float)cubesize) * new Vector3(x, y, z); k.RootNodes[i] = KCLOctreeNode.Generate(tt, pos, cubesize, MaxNrTris, MinCubeSize, maxOCtree, i + 1); i++; } } } return(k); }
public KCL() { Header = new MK7KCLHeader(); }
public List <String> CreateFromFile(byte[] Data) //Return mat count to create pa { OBJ o = new OBJ(Data); List <String> matnames = new List <string>(); foreach (var v in o.Faces) { if (!matnames.Contains(v.Material)) { matnames.Add(v.Material); } } Dictionary <string, ushort> Mapping = new Dictionary <string, ushort>(); Dictionary <string, bool> Colli = new Dictionary <string, bool>(); for (ushort i = 0; i < matnames.Count; i++) { Mapping.Add(matnames[i], i); } foreach (string str in matnames) { Colli.Add(str, true); } List <Vector3> Vertex = new List <Vector3>(); List <Vector3> Normals = new List <Vector3>(); List <KCLPlane> planes = new List <KCLPlane>(); List <Triangle> Triangles = new List <Triangle>(); int face = 0; foreach (var v in o.Faces) { Console.Write("\r -Adding face " + (++face).ToString() + "/" + o.Faces.Count.ToString()); if (Colli[v.Material]) { Triangle t = new Triangle(o.Vertices[v.VertexIndieces[0]], o.Vertices[v.VertexIndieces[1]], o.Vertices[v.VertexIndieces[2]]); Vector3 qq = (t.PointB - t.PointA).Cross(t.PointC - t.PointA); if ((qq.X * qq.X + qq.Y * qq.Y + qq.Z * qq.Z) < 0.01) { continue; } KCLPlane p = new KCLPlane(); p.CollisionType = Mapping[v.Material]; Vector3 a = (t.PointC - t.PointA).Cross(t.Normal); a.Normalize(); a = -a; Vector3 b = (t.PointB - t.PointA).Cross(t.Normal); b.Normalize(); Vector3 c = (t.PointC - t.PointB).Cross(t.Normal); c.Normalize(); p.Length = (t.PointC - t.PointA).Dot(c); int q = ContainsVector3(t.PointA, Vertex); if (q == -1) { p.VertexIndex = (ushort)Vertex.Count; Vertex.Add(t.PointA); } else { p.VertexIndex = (ushort)q; } q = ContainsVector3(t.Normal, Normals); if (q == -1) { p.NormalIndex = (ushort)Normals.Count; Normals.Add(t.Normal); } else { p.NormalIndex = (ushort)q; } q = ContainsVector3(a, Normals); if (q == -1) { p.NormalAIndex = (ushort)Normals.Count; Normals.Add(a); } else { p.NormalAIndex = (ushort)q; } q = ContainsVector3(b, Normals); if (q == -1) { p.NormalBIndex = (ushort)Normals.Count; Normals.Add(b); } else { p.NormalBIndex = (ushort)q; } q = ContainsVector3(c, Normals); if (q == -1) { p.NormalCIndex = (ushort)Normals.Count; Normals.Add(c); } else { p.NormalCIndex = (ushort)q; } planes.Add(p); Triangles.Add(t); } } Vertices = Vertex.ToArray(); this.Normals = Normals.ToArray(); Planes = planes.ToArray(); Header = new MK7KCLHeader(); Octree = KCLOctree.FromTriangles(Triangles.ToArray(), Header, 2048, 128, 128, 50); return(matnames); }
public bool CreateFromFile() { System.Windows.Forms.OpenFileDialog f = new System.Windows.Forms.OpenFileDialog(); f.Filter = OBJ.Identifier.GetFileFilter(); if (f.ShowDialog() == System.Windows.Forms.DialogResult.OK && f.FileName.Length > 0) { OBJ o = new OBJ(File.ReadAllBytes(f.FileName)); List <String> matnames = new List <string>(); foreach (var v in o.Faces) { if (!matnames.Contains(v.Material)) { matnames.Add(v.Material); } } UI.KCLCollisionTypeSelector ty = new UI.KCLCollisionTypeSelector(matnames.ToArray()); ty.DialogResult = System.Windows.Forms.DialogResult.None; ty.ShowDialog(); while (ty.DialogResult != System.Windows.Forms.DialogResult.OK) { ; } Dictionary <string, ushort> Mapping; Dictionary <string, bool> Colli; Mapping = ty.Mapping; Colli = ty.Colli; List <Vector3> Vertex = new List <Vector3>(); List <Vector3> Normals = new List <Vector3>(); List <KCLPlane> planes = new List <KCLPlane>(); List <Triangle> Triangles = new List <Triangle>(); foreach (var v in o.Faces) { if (Colli[v.Material]) { Triangle t = new Triangle(o.Vertices[v.VertexIndieces[0]], o.Vertices[v.VertexIndieces[1]], o.Vertices[v.VertexIndieces[2]]); Vector3 qq = (t.PointB - t.PointA).Cross(t.PointC - t.PointA); if ((qq.X * qq.X + qq.Y * qq.Y + qq.Z * qq.Z) < 0.01) { continue; } KCLPlane p = new KCLPlane(); p.CollisionType = Mapping[v.Material]; Vector3 a = (t.PointC - t.PointA).Cross(t.Normal); a.Normalize(); a = -a; Vector3 b = (t.PointB - t.PointA).Cross(t.Normal); b.Normalize(); Vector3 c = (t.PointC - t.PointB).Cross(t.Normal); c.Normalize(); p.Length = (t.PointC - t.PointA).Dot(c); int q = ContainsVector3(t.PointA, Vertex); if (q == -1) { p.VertexIndex = (ushort)Vertex.Count; Vertex.Add(t.PointA); } else { p.VertexIndex = (ushort)q; } q = ContainsVector3(t.Normal, Normals); if (q == -1) { p.NormalIndex = (ushort)Normals.Count; Normals.Add(t.Normal); } else { p.NormalIndex = (ushort)q; } q = ContainsVector3(a, Normals); if (q == -1) { p.NormalAIndex = (ushort)Normals.Count; Normals.Add(a); } else { p.NormalAIndex = (ushort)q; } q = ContainsVector3(b, Normals); if (q == -1) { p.NormalBIndex = (ushort)Normals.Count; Normals.Add(b); } else { p.NormalBIndex = (ushort)q; } q = ContainsVector3(c, Normals); if (q == -1) { p.NormalCIndex = (ushort)Normals.Count; Normals.Add(c); } else { p.NormalCIndex = (ushort)q; } planes.Add(p); Triangles.Add(t); } } Vertices = Vertex.ToArray(); this.Normals = Normals.ToArray(); Planes = planes.ToArray(); Header = new MK7KCLHeader(); Octree = KCLOctree.FromTriangles(Triangles.ToArray(), Header, 2048, 128, 128, 50); return(true); } return(false); }
public bool BackGroundWorkerTask(System.ComponentModel.BackgroundWorker worker, object argument) { BGArgs userState = (BGArgs)argument; OBJ o = new OBJ(File.ReadAllBytes(userState.filename)); List <String> matnames = new List <string>(); foreach (var v in o.Faces) { if (!matnames.Contains(v.Material)) { matnames.Add(v.Material); } } UI.KCLCollisionTypeSelector ty = new UI.KCLCollisionTypeSelector(matnames.ToArray(), userState.filename); ty.loadMK7KCLInformations(); ty.DialogResult = System.Windows.Forms.DialogResult.None; ty.ShowDialog(); while (ty.DialogResult != System.Windows.Forms.DialogResult.OK) { ; } roundVertexPositions(o); Dictionary <string, ushort> Mapping; Dictionary <string, bool> Colli; Mapping = ty.Mapping; Colli = ty.Colli; List <Vector3> Vertex = new List <Vector3>(); List <Vector3> Normals = new List <Vector3>(); List <KCLPlane> planes = new List <KCLPlane>(); List <Triangle> Triangles = new List <Triangle>(); userState.state = 1; userState.currProg = 0; userState.totProg = o.Faces.Count; foreach (var v in o.Faces) { if (Colli[v.Material]) { Triangle t = new Triangle(o.Vertices[v.VertexIndieces[0]], o.Vertices[v.VertexIndieces[1]], o.Vertices[v.VertexIndieces[2]]); Vector3 qq = (t.PointB - t.PointA).Cross(t.PointC - t.PointA); if ((qq.X * qq.X + qq.Y * qq.Y + qq.Z * qq.Z) < 0.1) { continue; } KCLPlane p = new KCLPlane(); p.CollisionType = Mapping[v.Material]; Vector3 a = (t.PointC - t.PointA).Cross(t.Normal); a.Normalize(); a = -a; Vector3 b = (t.PointB - t.PointA).Cross(t.Normal); b.Normalize(); Vector3 c = (t.PointC - t.PointB).Cross(t.Normal); c.Normalize(); p.Length = (t.PointC - t.PointA).Dot(c); int q = ContainsVector3(t.PointA, Vertex); if (q == -1) { p.VertexIndex = (ushort)Vertex.Count; Vertex.Add(t.PointA); } else { p.VertexIndex = (ushort)q; } q = ContainsVector3(t.Normal, Normals); if (q == -1) { p.NormalIndex = (ushort)Normals.Count; Normals.Add(t.Normal); } else { p.NormalIndex = (ushort)q; } q = ContainsVector3(a, Normals); if (q == -1) { p.NormalAIndex = (ushort)Normals.Count; Normals.Add(a); } else { p.NormalAIndex = (ushort)q; } q = ContainsVector3(b, Normals); if (q == -1) { p.NormalBIndex = (ushort)Normals.Count; Normals.Add(b); } else { p.NormalBIndex = (ushort)q; } q = ContainsVector3(c, Normals); if (q == -1) { p.NormalCIndex = (ushort)Normals.Count; Normals.Add(c); } else { p.NormalCIndex = (ushort)q; } planes.Add(p); Triangles.Add(t); } userState.currProg++; worker.ReportProgress(0, userState); if (worker.CancellationPending) { return(false); } } Vertices = Vertex.ToArray(); this.Normals = Normals.ToArray(); Planes = planes.ToArray(); Header = new MK7KCLHeader(); Octree = KCLOctree.FromTriangles(Triangles.ToArray(), Header, 2048, 128, 32, 10, userState, worker); if (Octree == null) { return(false); } return(true); }