Пример #1
0
        private Cb4aCollisionMeshSoupFace BuildCollisionFaceSoupFace(BspCollisionFaceSoupFace f, Cb4aCollisionMeshSoup soup)
        {
            var r = new Cb4aCollisionMeshSoupFace();

            Vector3 n = Vector3.UnitZ;
            float maxLength = float.MinValue;
            for (int i=0; i<f.Vertices.Count-1;++i)
            {
                Vector3 edge0 = f.Vertices[i] - f.Vertices[(i + 1) % f.Vertices.Count];
                Vector3 nn = Vector3.Cross(f.Vertices[(i + 1) % f.Vertices.Count] - f.Vertices[(i + 2) % f.Vertices.Count], edge0);
                float l = nn.LengthSquared;
                if (l> maxLength)
                {
                    maxLength = l;
                    n = nn;
                }

            }
            if (maxLength < 1)
            {
                maxLength = maxLength;
                //throw new ApplicationException("face is almost zero area!");
            }
            n.Normalize();

            r.startPlane = soup.Planes.Count;
            soup.Planes.Add(new CIwPlane() { k = (int)(Vector3.Dot(f.Vertices[0], n)) * AirplaySDKMath.IW_GEOM_ONE, v = GetVec3Fixed(n) });

            int lastD = int.MinValue;
            CIwVec3 lastN = CIwVec3.g_Zero;
            for (int i = 0; i < f.Vertices.Count; ++i)
            {
                var d = Vector3.Cross(n,f.Vertices[i] - f.Vertices[(i + 1) % f.Vertices.Count]);
                d.Normalize();
                CIwVec3 newN = GetVec3Fixed(d);
                CIwVec3 v3 = GetVec3(f.Vertices[i]);
                int newD = newN.x * v3.x + newN.y * v3.y + newN.z * v3.z;//(int)(Vector3.Dot(d, f.Vertices[i]) * AirplaySDKMath.IW_GEOM_ONE);
                if (newN != lastN || newD != lastD)
                {
                    lastD=newD;
                    lastN = newN;

                    //test
                    //for (int j = 0; j < f.Vertices.Count; ++j)
                    //{
                    //    if ((newN.x * f.Vertices[j].X + newN.y * f.Vertices[j].Y + newN.z * f.Vertices[j].Z) - lastD < -64)
                    //    {
                    //        //TODO: Split such faces into individual triangles. Think how to handle it in graphics
                    //        //throw new ApplicationException("wrong edge normal " + newN);
                    //    }
                    //}

                    soup.Planes.Add(new CIwPlane() { k = newD, v = newN });
                    //r.edges.Add(new Cb4aCollisionMeshSoupFaceEdge(){Normal=newN, Distance=newD});
                }
            }
            r.numPlanes = soup.Planes.Count - r.startPlane-1;
            return r;
        }
Пример #2
0
 private Ib4aCollider BuildCollisionFaceSoup(BspCollisionFaceSoup bspCollisionFaceSoup)
 {
     var soup = new Cb4aCollisionMeshSoup();
     foreach (var f in bspCollisionFaceSoup.Faces)
     {
         soup.Faces.Add(BuildCollisionFaceSoupFace(f, soup));
     }
     return soup;
 }