コード例 #1
0
ファイル: KCL.cs プロジェクト: RR0000/Odyssave
        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();
            }
        }
コード例 #2
0
ファイル: KCL.cs プロジェクト: RR0000/Odyssave
        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);
        }
コード例 #3
0
ファイル: KCL.cs プロジェクト: RR0000/Odyssave
 public KCL()
 {
     Header = new MK7KCLHeader();
 }
コード例 #4
0
ファイル: KCL.cs プロジェクト: RR0000/Odyssave
        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);
        }
コード例 #5
0
 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);
 }
コード例 #6
0
        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);
        }