/// <summary>
        ///
        /// </summary>
        /// <param name="jobj"></param>
        public static void CalculateCollisionFlags(this KAR_grCollisionNode coll)
        {
            var verts = coll.Vertices;
            var tris  = coll.Triangles;

            foreach (var tri in tris)
            {
                // calculate surface normal
                var v0 = GXTranslator.toVector3(verts[tri.V1]);
                var v1 = GXTranslator.toVector3(verts[tri.V2]);
                var v2 = GXTranslator.toVector3(verts[tri.V3]);

                var faceNrm = Vector3.Cross(v1 - v0, v2 - v0).Normalized();

                tri.Flags &= ~0x7;

                // guess flag
                if (faceNrm.Y > 0.5f)
                {
                    tri.Flags |= 0x04;
                }
                else
                if (faceNrm.Y <= 0.5f && faceNrm.Y > -0.5f)
                {
                    tri.Flags |= 0x02;
                }
                else
                {
                    tri.Flags |= 0x01;
                }
            }

            coll.Triangles = tris;
        }
Beispiel #2
0
 public void Clear()
 {
     Node          = null;
     Vertices      = null;
     Triangles     = null;
     Joints        = null;
     ZoneVertices  = null;
     ZoneTriangles = null;
     ZoneJoints    = null;
 }
Beispiel #3
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="node"></param>
        private void LoadZones(KAR_grCollisionNode node)
        {
            var vertices = node.ZoneVertices;
            var faces    = node.ZoneTriangles;

            foreach (var j in node.ZoneJoints)
            {
                // create collision joint
                var c = new GrZoneJoint()
                {
                    JointIndex = j.BoneID,
                };
                c.Mtx[0]  = j.Mtx00;
                c.Mtx[1]  = j.Mtx10;
                c.Mtx[2]  = j.Mtx20;
                c.Mtx[3]  = j.Mtx30;
                c.Mtx[4]  = j.Mtx01;
                c.Mtx[5]  = j.Mtx11;
                c.Mtx[6]  = j.Mtx21;
                c.Mtx[7]  = j.Mtx31;
                c.Mtx[8]  = j.Mtx02;
                c.Mtx[9]  = j.Mtx12;
                c.Mtx[10] = j.Mtx22;
                c.Mtx[11] = j.Mtx32;

                // unknown data
                if (j._s.References.ContainsKey(0x14))
                {
                    c.Unknown = j._s.References[0x14];
                }

                if (j._s.References.ContainsKey(0x18))
                {
                    c.Params = j._s.References[0x18];
                }

                // convert faces
                for (int i = j.ZoneFaceStart; i < j.ZoneFaceStart + j.ZoneFaceSize; i++)
                {
                    var face = faces[i];
                    c.Faces.Add(new GrZoneFace()
                    {
                        CollFlag    = face.CollFlags,
                        TypeFlag    = face.TypeFlags,
                        UnknownFlag = face.UnkFlags,
                        p0          = vertices[face.V1],
                        p1          = vertices[face.V2],
                        p2          = vertices[face.V3],
                    });
                }

                // add to collection
                ZoneJoints.Add(c);
            }
        }
Beispiel #4
0
        public void Render(HSDAccessor a, int windowWidth, int windowHeight)
        {
            if (a is KAR_grCollisionNode cn && cn != Node)
            {
                Node      = cn;
                Vertices  = Node.Vertices;
                Triangles = Node.Triangles;
                Joints    = Node.Joints;

                ZoneVertices  = Node.ZoneVertices;
                ZoneTriangles = Node.ZoneTriangles;
                ZoneJoints    = Node.ZoneJoints;
            }

            if (Node == null)
            {
                return;
            }

            GL.PushAttrib(AttribMask.AllAttribBits);

            GL.Enable(EnableCap.Blend);
            GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha);

            GL.Begin(PrimitiveType.Triangles);

            foreach (var t in Triangles)
            {
                if ((t.Flags & 0x1) == 0x1)
                {
                    GL.Color4(1f, 0f, 0f, 0.5f);
                }
                if ((t.Flags & 0x2) == 0x2)
                {
                    GL.Color4(0f, 1f, 0f, 0.5f);
                }
                if ((t.Flags & 0x4) == 0x4)
                {
                    GL.Color4(0f, 0f, 1f, 0.5f);
                }

                GL.Vertex3(GXTranslator.toVector3(Vertices[t.V1]));
                GL.Vertex3(GXTranslator.toVector3(Vertices[t.V2]));
                GL.Vertex3(GXTranslator.toVector3(Vertices[t.V3]));
            }

            GL.End();

            GL.PopAttrib();
        }
        public static KAR_grCollisionTree GenerateBucketPartition(KAR_grCollisionNode coll)
        {
            var v         = coll.Vertices;
            var bucketGen = new BucketGen(
                v.Min(e => e.X) - 10,
                Math.Min(-1000, v.Min(e => e.Y) - 10),
                v.Min(e => e.Z) - 10,
                v.Max(e => e.X) + 10,
                Math.Max(1000, v.Min(e => e.Y) + 10),
                v.Max(e => e.Z) + 10);

            var tris = coll.Triangles.ToList();

            foreach (var t in tris)
            {
                bucketGen.AddTriangle(t, v[t.V1], v[t.V2], v[t.V3]);
            }

            return(bucketGen.ProcessBuckets(tris));
        }
Beispiel #6
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="node"></param>
        private void LoadCollisions(KAR_grCollisionNode node)
        {
            var vertices = node.Vertices;
            var faces    = node.Triangles;

            foreach (var j in node.Joints)
            {
                // create collision joint
                var c = new GrCollisionJoint()
                {
                    JointIndex = j.BoneID,
                    Flags      = j.Flags
                };

                // unknown data
                if (j._s.References.ContainsKey(0x18))
                {
                    c.Unknown = j._s.References[0x18];
                }

                // convert faces
                for (int i = j.FaceStart; i < j.FaceStart + j.FaceSize; i++)
                {
                    var face = faces[i];
                    c.Faces.Add(new GrCollisionFace()
                    {
                        Flags    = face.Flags,
                        Material = face.Material,
                        p0       = vertices[face.V1],
                        p1       = vertices[face.V2],
                        p2       = vertices[face.V3],
                    });
                }

                // add to collection
                CollisionJoints.Add(c);
            }
        }
Beispiel #7
0
        public static KAR_grCollisionNode KCLtoKAR(string kclFile, out KAR_grCollisionTree tree)
        {
            KAR_grCollisionNode node = new KAR_grCollisionNode();

            List <KAR_CollisionTriangle> tris  = new List <KAR_CollisionTriangle>();
            List <GXVector3>             verts = new List <GXVector3>();

            using (FileStream f = new FileStream(kclFile, FileMode.Open))
                using (BinaryReaderExt r = new BinaryReaderExt(f))
                {
                    r.BigEndian = true;

                    var posOffset  = r.ReadInt32();
                    var nrmOffset  = r.ReadInt32();
                    var triOffset  = r.ReadInt32() + 0x10;
                    var partOffste = r.ReadInt32();

                    var triCount = (partOffste - triOffset) / 0x10;
                    for (int i = 0; i < triCount; i++)
                    {
                        r.Seek((uint)(triOffset + i * 0x10));

                        var length = r.ReadSingle();
                        var pi     = r.ReadUInt16();
                        var di     = r.ReadUInt16();
                        var n1     = r.ReadUInt16();
                        var n2     = r.ReadUInt16();
                        var n3     = r.ReadUInt16();
                        var fl     = r.ReadUInt16();

                        r.Seek((uint)(posOffset + pi * 0xC));
                        var position = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        r.Seek((uint)(nrmOffset + di * 0xC));
                        var direction = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        r.Seek((uint)(nrmOffset + n1 * 0xC));
                        var normalA = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        r.Seek((uint)(nrmOffset + n2 * 0xC));
                        var normalB = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        r.Seek((uint)(nrmOffset + n3 * 0xC));
                        var normalC = new Vector3(r.ReadSingle(), r.ReadSingle(), r.ReadSingle());

                        var crossA  = Vector3.Cross(normalA, direction);
                        var crossB  = Vector3.Cross(normalB, direction);
                        var vertex1 = position;
                        var vertex2 = position + crossB * (length / Vector3.Dot(crossB, normalC));
                        var vertex3 = position + crossA * (length / Vector3.Dot(crossA, normalC));

                        tris.Add(new KAR_CollisionTriangle()
                        {
                            Flags = 0x81,
                            V1    = verts.Count + 2,
                            V2    = verts.Count + 1,
                            V3    = verts.Count
                        });

                        // scale
                        vertex1 *= Scale;
                        vertex2 *= Scale;
                        vertex3 *= Scale;

                        vertex1.Y += YTrans;
                        vertex2.Y += YTrans;
                        vertex3.Y += YTrans;

                        verts.Add(new GXVector3()
                        {
                            X = vertex1.X, Y = vertex1.Y, Z = vertex1.Z
                        });
                        verts.Add(new GXVector3()
                        {
                            X = vertex2.X, Y = vertex2.Y, Z = vertex2.Z
                        });
                        verts.Add(new GXVector3()
                        {
                            X = vertex3.X, Y = vertex3.Y, Z = vertex3.Z
                        });
                    }
                }

            {
                var height = verts.Min(e => e.Y) - 10;

                var v1 = new Vector3(-10000, height, -10000);
                var v2 = new Vector3(10000, height, -10000);
                var v3 = new Vector3(10000, height, 10000);
                var v4 = new Vector3(-10000, height, 10000);

                tris.Add(new KAR_CollisionTriangle()
                {
                    Flags = 0x81,
                    V1    = verts.Count,
                    V2    = verts.Count + 1,
                    V3    = verts.Count + 2
                });

                verts.Add(new GXVector3()
                {
                    X = v1.X, Y = v1.Y, Z = v1.Z
                });
                verts.Add(new GXVector3()
                {
                    X = v2.X, Y = v2.Y, Z = v2.Z
                });
                verts.Add(new GXVector3()
                {
                    X = v3.X, Y = v3.Y, Z = v3.Z
                });

                tris.Add(new KAR_CollisionTriangle()
                {
                    Flags = 0x81,
                    V1    = verts.Count,
                    V2    = verts.Count + 1,
                    V3    = verts.Count + 2
                });

                verts.Add(new GXVector3()
                {
                    X = v1.X, Y = v1.Y, Z = v1.Z
                });
                verts.Add(new GXVector3()
                {
                    X = v3.X, Y = v3.Y, Z = v3.Z
                });
                verts.Add(new GXVector3()
                {
                    X = v4.X, Y = v4.Y, Z = v4.Z
                });
            }

            node.Triangles = tris.ToArray();
            node.Vertices  = verts.ToArray();
            node.Joints    = new KAR_CollisionJoint[]
            {
                new KAR_CollisionJoint()
                {
                    VertexStart = 0,
                    VertexSize  = verts.Count,
                    FaceStart   = 0,
                    FaceSize    = tris.Count
                }
            };

            tree = BucketGen.GenerateBucketPartition(node);

            return(node);
        }
Beispiel #8
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="node"></param>
 public void LoadFromCollision(KAR_grCollisionNode node)
 {
     LoadCollisions(node);
     LoadZones(node);
 }
Beispiel #9
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="collNode"></param>
        private void ProcessZones(KAR_grCollisionNode collNode)
        {
            // collect triangles and optimize points
            KAR_ZoneCollisionJoint[] joints = new KAR_ZoneCollisionJoint[ZoneJoints.Count];

            // collect points and faces
            List <GXVector3> points = new List <GXVector3>();
            List <KAR_ZoneCollisionTriangle> faces = new List <KAR_ZoneCollisionTriangle>();

            // process collision joints
            var faceIndex   = 0;
            var vertexIndex = 0;

            for (int i = 0; i < joints.Length; i++)
            {
                // convert collision joint
                var j     = ZoneJoints[i];
                var joint = new KAR_ZoneCollisionJoint()
                {
                    BoneID          = j.JointIndex,
                    Mtx00           = j.Mtx[0],
                    Mtx10           = j.Mtx[1],
                    Mtx20           = j.Mtx[2],
                    Mtx30           = j.Mtx[3],
                    Mtx01           = j.Mtx[4],
                    Mtx11           = j.Mtx[5],
                    Mtx21           = j.Mtx[6],
                    Mtx31           = j.Mtx[7],
                    Mtx02           = j.Mtx[8],
                    Mtx12           = j.Mtx[9],
                    Mtx22           = j.Mtx[10],
                    Mtx32           = j.Mtx[11],
                    ZoneVertexStart = vertexIndex,
                    ZoneFaceStart   = faceIndex,
                };
                if (j.Unknown != null)
                {
                    joint._s.SetReferenceStruct(0x14, j.Unknown);
                }
                if (j.Params != null)
                {
                    joint._s.SetReferenceStruct(0x18, j.Params);
                }
                joints[i] = joint;

                // add points and triangles
                Dictionary <GXVector3, int> pointToIndex = new Dictionary <GXVector3, int>();
                foreach (var tri in j.Faces)
                {
                    // generate and add face
                    var face = new KAR_ZoneCollisionTriangle()
                    {
                        CollFlags = tri.CollFlag,
                        TypeFlags = tri.TypeFlag,
                        UnkFlags  = tri.UnknownFlag,
                        V1        = GetPointIndex(tri.p0, ref pointToIndex, ref points),
                        V2        = GetPointIndex(tri.p1, ref pointToIndex, ref points),
                        V3        = GetPointIndex(tri.p2, ref pointToIndex, ref points),
                    };
                    faces.Add(face);
                }

                // update vertex and face sizes
                joint.ZoneFaceSize   = j.Faces.Count;
                joint.ZoneVertexSize = pointToIndex.Count;

                // increment vertex and face size
                vertexIndex += joint.ZoneVertexSize;
                faceIndex   += joint.ZoneFaceSize;
            }

            //
            collNode.ZoneVertices      = points.ToArray();
            collNode.ZoneVertexCount   = points.Count;
            collNode.ZoneTriangles     = faces.ToArray();
            collNode.ZoneTriangleCount = faces.Count;
            collNode.ZoneJoints        = joints;
            collNode.ZoneJointCount    = joints.Length;
        }
Beispiel #10
0
        /// <summary>
        ///
        /// </summary>
        public void ExportCollisions(out KAR_grCollisionNode collNode, out KAR_grCollisionTreeNode treeNode)
        {
            collNode = new KAR_grCollisionNode();
            treeNode = new KAR_grCollisionTreeNode();

            // collect triangles and optimize points
            KAR_CollisionJoint[] collJoints = new KAR_CollisionJoint[CollisionJoints.Count];

            // collect points and faces
            List <GXVector3>             points = new List <GXVector3>();
            List <KAR_CollisionTriangle> faces  = new List <KAR_CollisionTriangle>();

            // process collision joints
            var faceIndex   = 0;
            var vertexIndex = 0;

            for (int i = 0; i < collJoints.Length; i++)
            {
                // convert collision joint
                var j     = CollisionJoints[i];
                var joint = new KAR_CollisionJoint()
                {
                    BoneID      = j.JointIndex,
                    Flags       = j.Flags,
                    VertexStart = vertexIndex,
                    FaceStart   = faceIndex,
                };
                if (j.Unknown != null)
                {
                    joint._s.SetReferenceStruct(0x18, j.Unknown);
                }
                collJoints[i] = joint;

                // add points and triangles
                Dictionary <GXVector3, int> pointToIndex = new Dictionary <GXVector3, int>();
                foreach (var tri in j.Faces)
                {
                    // generate and add face
                    var face = new KAR_CollisionTriangle()
                    {
                        Flags    = tri.Flags,
                        Material = tri.Material,
                        V1       = GetPointIndex(tri.p0, ref pointToIndex, ref points),
                        V2       = GetPointIndex(tri.p1, ref pointToIndex, ref points),
                        V3       = GetPointIndex(tri.p2, ref pointToIndex, ref points),
                    };
                    faces.Add(face);
                }

                // update vertex and face sizes
                joint.FaceSize   = j.Faces.Count;
                joint.VertexSize = pointToIndex.Count;

                // increment vertex and face size
                vertexIndex += joint.VertexSize;
                faceIndex   += joint.FaceSize;
            }

            // generate partition buckets
            treeNode.Partition = GenerateBucketPartition(points, faces);

            collNode.Vertices      = points.ToArray();
            collNode.VertexCount   = points.Count;
            collNode.Triangles     = faces.ToArray();
            collNode.TriangleCount = faces.Count;
            collNode.Joints        = collJoints;
            collNode.JointCount    = collJoints.Length;

            ProcessZones(collNode);
        }
Beispiel #11
0
        /// <summary>
        /// 
        /// </summary>
        /// <param name="coll"></param>
        public void LoadCollision(KAR_grCollisionNode coll)
        {
            // Load Collisions
            var tris = coll.Triangles;
            var verts = coll.Vertices;

            Joints = new JointCollision[coll.JointCount];
            for(int i = 0; i < coll.JointCount; i++)
            {
                var joint = coll.Joints[i];
                Joints[i] = new JointCollision()
                {
                    Bone = joint.BoneID,
                    Faces = new CollisionFace[joint.FaceSize]
                };

                for (int j = joint.FaceStart; j < joint.FaceStart + joint.FaceSize; j++)
                {
                    var face = tris[j];

                    var v1 = verts[face.V1];
                    var v2 = verts[face.V2];
                    var v3 = verts[face.V3];

                    Joints[i].Faces[j - joint.FaceStart] = new CollisionFace()
                    {
                        Flags = face.Flags,
                        Unknown = face.Unknown,
                        v1 = new Vector3(v1.X, v1.Y, v1.Z),
                        v2 = new Vector3(v2.X, v2.Y, v2.Z),
                        v3 = new Vector3(v3.X, v3.Y, v3.Z),
                    };
                }
            }

            // Load Zones
            var ztris = coll.ZoneTriangles;
            verts = coll.ZoneVertices;

            ZoneJoints = new ZoneJointCollision[coll.ZoneJointCount];
            for (int i = 0; i < coll.ZoneJointCount; i++)
            {
                var joint = coll.ZoneJoints[i];
                ZoneJoints[i] = new ZoneJointCollision()
                {
                    Bone = joint.BoneID,
                    Faces = new ZoneCollisionFace[joint.ZoneFaceSize],
                    ZoneJoint = joint
                };

                for (int j = 0; j < joint.ZoneFaceSize; j++)
                {
                    var face = ztris[j + joint.ZoneFaceStart];

                    var v1 = verts[face.V1];
                    var v2 = verts[face.V2];
                    var v3 = verts[face.V3];

                    Joints[i].Faces[j] = new ZoneCollisionFace()
                    {
                        Flags = face.Color,
                        Unknown = face.Unknown,
                        UnknownZone = face.UnknownZone,
                        v1 = new Vector3(v1.X, v1.Y, v1.Z),
                        v2 = new Vector3(v2.X, v2.Y, v2.Z),
                        v3 = new Vector3(v3.X, v3.Y, v3.Z),
                    };
                }
            }
        }