Exemplo n.º 1
0
        public void PointNearestToOtherRay(TRay r, ref float point)
        {
            Vector3 t = Vector3.Cross(dir, r.dir);
            TPlane  p = new TPlane(Vector3.Cross(t, r.dir), r.pos);

            Inters(p, ref point);
        }
Exemplo n.º 2
0
        public bool Inters(TPlane plane, ref float t)
        {
            float v = Vector3.Dot(plane.normal, dir);

            if (v == 0)
            {
                return(false);
            }
            t = (plane.dist - Vector3.Dot(pos, plane.normal)) / v;
            return(t > 0);
        }
Exemplo n.º 3
0
        void CutTriangleByPlane(TPlane plane, int tri)
        {
            TMeshTri t = triangle[tri];
            float
                d0 = plane.DistToPlane(pos[t.p0]),
                d1 = plane.DistToPlane(pos[t.p1]),
                d2 = plane.DistToPlane(pos[t.p2]);
            bool d0_sign = d0 >= 0;
            bool d1_sign = d1 >= 0;
            bool d2_sign = d2 >= 0;
            int  vert0 = -1, vert1 = -1, vert2 = -1;

            {
                int zero_count = 0;
                if (d0 == 0.0f)
                {
                    zero_count++;
                }
                if (d1 == 0.0f)
                {
                    zero_count++;
                }
                if (d2 == 0.0f)
                {
                    zero_count++;
                }
                if (zero_count == 3 || zero_count == 2)
                {
                    return;
                }
            }
            if (d0 == 0.0f || d1 == 0.0f || d2 == 0.0f)
            {
                float x = 0;
                if (d0 == 0.0f)
                {
                    if (d1_sign == d2_sign)
                    {
                        return;
                    }
                    vert0 = 0;
                    vert1 = 1;
                    vert2 = 2;
                    x     = d1 / (d1 - d2);
                }
                else if (d1 == 0.0f)
                {
                    if (d0_sign == d2_sign)
                    {
                        return;
                    }
                    vert0 = 1;
                    vert1 = 2;
                    vert2 = 0;
                    x     = d2 / (d2 - d0);
                }
                else// if (d2 == 0.0f)
                {
                    if (d0_sign == d1_sign)
                    {
                        return;
                    }
                    vert0 = 2;
                    vert1 = 0;
                    vert2 = 1;
                    x     = d0 / (d0 - d1);
                }
                Vector3 new_pos    = Blend(pos[t.GetPos(vert1)], pos[t.GetPos(vert2)], x);
                Vector3 new_normal = Blend(normal[t.GetNormal(vert1)], normal[t.GetNormal(vert2)], x);
                new_normal.Normalize();
                Debug.Assert(!float.IsNaN(new_pos.X) && !float.IsNaN(new_pos.Y) && !float.IsNaN(new_pos.Z));
                pos.Add(new_pos);
                normal.Add(new_normal);
                TMeshTri temp = triangle[tri];
                triangle[tri] = new TMeshTri(
                    temp.GetPos(vert0), temp.GetPos(vert1), pos.High,
                    temp.GetNormal(vert0), temp.GetNormal(vert1), normal.High,
                    0, 0, 0);
                triangle.Add(new TMeshTri(
                                 temp.GetPos(vert0), pos.High, temp.GetPos(vert2),
                                 temp.GetNormal(vert0), normal.High, temp.GetNormal(vert2),
                                 0, 0, 0));
            }
            else
            {
                float x1 = 0, x2 = 0;
                if ((d0_sign == d1_sign) && (d0_sign != d2_sign))
                {
                    vert0 = 2;
                    vert1 = 0;
                    vert2 = 1;
                    x1    = d2 / (d2 - d0);
                    x2    = d2 / (d2 - d1);
                }
                else if ((d0_sign == d2_sign) && (d0_sign != d1_sign))
                {
                    vert0 = 1;
                    vert1 = 2;
                    vert2 = 0;
                    x1    = d1 / (d1 - d2);
                    x2    = d1 / (d1 - d0);
                }
                else if ((d1_sign == d2_sign) && (d0_sign != d1_sign))
                {
                    vert0 = 0;
                    vert1 = 1;
                    vert2 = 2;
                    x1    = d0 / (d0 - d1);
                    x2    = d0 / (d0 - d2);
                }
                else
                {
                    return; //треугольники могут пересекаются из-за неточностей
                }
                Vector3 new_pos1    = Blend(pos[t.GetPos(vert0)], pos[t.GetPos(vert1)], x1);
                Vector3 new_pos2    = Blend(pos[t.GetPos(vert0)], pos[t.GetPos(vert2)], x2);
                Vector3 new_normal1 = Blend(normal[t.GetNormal(vert0)], normal[t.GetNormal(vert1)], x1);
                Vector3 new_normal2 = Blend(normal[t.GetNormal(vert0)], normal[t.GetNormal(vert2)], x2);
                new_normal1.Normalize();
                new_normal2.Normalize();
                pos.Add(new_pos1);
                pos.Add(new_pos2);
                Debug.Assert(!float.IsNaN(new_pos1.X) && !float.IsNaN(new_pos1.Y) && !float.IsNaN(new_pos1.Z));
                Debug.Assert(!float.IsNaN(new_pos2.X) && !float.IsNaN(new_pos2.Y) && !float.IsNaN(new_pos2.Z));
                normal.Add(new_normal1);
                normal.Add(new_normal2);
                TMeshTri temp = triangle[tri];
                //TODO выбирать наиболее короткое ребро
                triangle[tri] = new TMeshTri(
                    temp.GetPos(vert0), pos.High - 1, pos.High,
                    temp.GetNormal(vert0), normal.High - 1, normal.High,
                    0, 0, 0);
                triangle.Add(new TMeshTri(
                                 pos.High - 1, temp.GetPos(vert1), temp.GetPos(vert2),
                                 normal.High - 1, temp.GetNormal(vert1), temp.GetNormal(vert2),
                                 0, 0, 0));
                triangle.Add(new TMeshTri(
                                 pos.High - 1, temp.GetPos(vert2), pos.High,
                                 normal.High - 1, temp.GetNormal(vert2), normal.High,
                                 0, 0, 0));
            }
        }