예제 #1
0
        /// <summary>
        /// Predict from each possible triange, returning each candidate
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="n"></param>
        /// <returns>Only returns plausible candidates, if all are bad, the result is empty</returns>
        internal List <System.Drawing.Point> GetCandidates(int x, int y, List <PointMapping> n)
        {
            if (n.Count < 3)
            {
                throw new ArgumentException("at least 3 neighbours needed");
            }
            var targ = new System.Drawing.Point(x, y);
            var poss = new List <System.Drawing.Point>();

            for (int i = 0; i < n.Count - 2; i++)
            {
                for (int j = i + 1; j < n.Count; j++)
                {
                    for (int k = j + 1; k < n.Count; k++)
                    {
                        var b = new BarycentricCoordinate(targ, n[i].Image, n[j].Image, n[k].Image);
                        if (b.IsNearby)
                        {
                            poss.Add(b.GetCartesianCoordinates(n[i].Screen, n[j].Screen, n[k].Screen));
                        }
                    }
                }
            }
            return(poss);
        }
예제 #2
0
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     intersect = new Intersection();
     if (this.accelerationManager != null && this.accelerationManager.FindIntersection(ray, out intersect))
     {
         if (this.shadeType == ShadeType.Phong)
         {
             MeshTriangle          t    = (MeshTriangle)intersect.HitPrimitive;
             BarycentricCoordinate bary = t.CurrentBarycentricCoordinate;
             Vector3D v1 = bary.Alpha * t.Vertex1.Normal;
             Vector3D v2 = bary.Beta * t.Vertex2.Normal;
             Vector3D v3 = bary.Gama * t.Vertex3.Normal;
             intersect.Normal = (v1 + v2 + v3);
             intersect.Normal.Normalize();
         }
         if (intersect.Normal * ray.Direction > 0)
         {
             intersect.Normal.Flip();
         }
         intersect.HitPrimitive          = this;
         intersect.HitPrimitive.Material = this.material;
         return(true);
     }
     return(false);
 }
예제 #3
0
 //[MethodImpl(MethodImplOptions.AggressiveInlining | MethodImplOptions.Synchronized)]
 public override bool FindIntersection(Ray ray, out Intersection intersect)
 {
     intersect = new Intersection();
     //if (!this.BoundBox.Intersect(ray)) {
     //    return false;
     //}
     if (this.manager != null && this.manager.FindIntersection(ray, out intersect))
     {
         if (this.shadeType == ShadeType.Phong)
         {
             Triangle t = (Triangle)intersect.HitPrimitive;
             BarycentricCoordinate bary = t.CurrentBarycentricCoordinate;
             Vector3D v1 = bary.Alpha * t.NormalOnVertex1;
             Vector3D v2 = bary.Beta * t.NormalOnVertex2;
             Vector3D v3 = bary.Gama * t.NormalOnVertex3;
             intersect.Normal = (v1 + v2 + v3);
             intersect.Normal.Normalize();
         }
         if (intersect.Normal * ray.Direction > 0)
         {
             intersect.Normal.Flip();
         }
         intersect.HitPrimitive          = this;
         intersect.HitPrimitive.Material = this.material;
         return(true);
     }
     return(false);
 }
예제 #4
0
 public MeshTriangle(MeshVertex vertex1, MeshVertex vertex2, MeshVertex vertex3)
 {
     this.Vertex1 = vertex1;
     this.Vertex2 = vertex2;
     this.Vertex3 = vertex3;
     this.visible = true;
     this.CurrentBarycentricCoordinate = BarycentricCoordinate.Zero;
     this.material = null;
 }
예제 #5
0
 public override Vector3D NormalOnPoint(Point3D pointInPrimitive)
 {
     foreach (Triangle tri in this.triangles)
     {
         if (tri.PointInTriangle(pointInPrimitive))
         {
             BarycentricCoordinate bary = tri.CurrentBarycentricCoordinate;
             Vector3D v1 = bary.Alpha * tri.NormalOnVertex1;
             Vector3D v2 = bary.Beta * tri.NormalOnVertex2;
             Vector3D v3 = bary.Gama * tri.NormalOnVertex3;
             return(v1 + v2 + v3);
         }
     }
     return(Vector3D.Zero);
 }
        public override Point FromPresentation(Point p)
        {
            var x  = (int)Math.Round(p.X);
            var y  = (int)Math.Round(p.Y);
            var b1 = new BarycentricCoordinate(new System.Drawing.Point(x, y), Grid.TopLeft, Grid.TopRight,
                                               Grid.BottomLeft);
            var p1 = b1.GetCartesianCoordinates(new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Top),
                                                new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Top),
                                                new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Bottom));
            //return p1;
            //if (b1.IsInside)
            //    return p1;
            var b2 = new BarycentricCoordinate(new System.Drawing.Point(x, y), Grid.TopLeft,
                                               Grid.BottomLeft, Grid.BottomRight);
            var p2 = b2.GetCartesianCoordinates(new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Top),
                                                new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Bottom),
                                                new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Bottom));
            var b3 = new BarycentricCoordinate(new System.Drawing.Point(x, y), Grid.TopRight,
                                               Grid.BottomLeft, Grid.BottomRight);
            var p3 = b3.GetCartesianCoordinates(new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Top),
                                                new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Bottom),
                                                new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Bottom));
            var b4 = new BarycentricCoordinate(new System.Drawing.Point(x, y), Grid.TopLeft, Grid.TopRight, Grid.BottomRight);
            var p4 = b4.GetCartesianCoordinates(new System.Drawing.Point(Grid.ScreenSize.Left, Grid.ScreenSize.Top),
                                                new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Top),
                                                new System.Drawing.Point(Grid.ScreenSize.Right, Grid.ScreenSize.Bottom));

            //return p2;
            //if (b2.IsInside)
            //{
            //    return p2;
            //}
            if (!(b1.IsInside || b3.IsInside || b2.IsInside || b4.IsInside))
            {
                return(new Point(-1.0f, -1.0f));
            }
            return(new Point((p1.X + p2.X + p3.X + p4.X) / 4.0f, (p1.Y + p2.Y + p3.Y + p4.Y) / 4.0f));
            //if (!b1.IsInside && !b2.IsInside)
            //    return new Point();
            //return new Point((int) Math.Round((p1.X + p2.X)/2.0), (int) Math.Round((p1.Y + p2.Y)/2.0));
        }
예제 #7
0
        /// <summary>
        /// Converts to Trilinear coordinates.
        /// </summary>
        /// <param name="vertexA">The vertex a.</param>
        /// <param name="vertexB">The vertex b.</param>
        /// <param name="vertexC">The vertex c.</param>
        /// <returns>TrilinearCoordinate.</returns>
        public TrilinearCoordinate ToTrilinear(CartesianCoordinate vertexA, CartesianCoordinate vertexB, CartesianCoordinate vertexC)
        {
            BarycentricCoordinate barycentric = ToBarycentric(vertexA, vertexB, vertexC);

            return(barycentric.ToTrilinear(vertexA, vertexB, vertexC));
        }
예제 #8
0
        //public override bool FindIntersection(Ray ray, out Intersection intersect) {
        //    intersect = new Intersection();
        //    /* orientation of the ray with respect to the triangle's normal,
        //       also used to calculate output parameters*/
        //    float det = -(ray.Direction * this.normalNonNormalized);
        //    /* the non-culling branch */
        //    /* if determinant is near zero, ray is parallel to the plane of triangle */
        //    if ( det.NearZero()) {
        //        return false;
        //    }
        //    /* calculate vector from ray origin to this.vertex1 */
        //    Vector3D vect0 = this.vertex1 - ray.Origin;
        //    /* normal vector used to calculate u and v parameters */
        //    Vector3D nvect = ray.Direction ^ vect0;
        //    float inv_det = 1.0f / det;
        //    /* calculate vector from ray origin to this.vertex2*/
        //    Vector3D vect1 = this.vertex2 - ray.Origin;
        //    /* calculate v parameter and test bounds */
        //    float v = -(vect1 * nvect) * inv_det;
        //    if (v < 0.0f || v > 1.0f) {
        //        return false;
        //    }
        //    /* calculate vector from ray origin to this.vertex3*/
        //    vect1 = this.vertex3 - ray.Origin;
        //    /* calculate v parameter and test bounds */
        //    float u = (vect1 * nvect) * inv_det;
        //    if (u < 0.0f || u + v > 1.0f) {
        //        return false;
        //    }

        //    const double epsilon = 2E-2;
        //    float alpha = 1.0f - (u + v);
        //    if (this.Wireframed && (!u.NearZero(epsilon) && !v.NearZero(epsilon) && !alpha.NearZero(epsilon)))
        //    {
        //        return false;
        //    }

        //    /* calculate t, ray intersects triangle */
        //    float t = -(vect0 * this.normalNonNormalized) * inv_det;
        //    //if (t < 100)
        //    //    return false;
        //    // return 1;
        //    if (t >= MathUtil.Epsilon)
        //    {
        //        intersect.Normal = this.normal;
        //        intersect.TMin = t;

        //        intersect.HitPoint = ray.Origin + (t * ray.Direction);
        //        this.CurrentBarycentricCoordinate = new BarycentricCoordinate(alpha, u, v);
        //        intersect.HitPrimitive = this;
        //        if (this.material != null && this.material.IsTexturized) {
        //            //int widthTex = this.material.Texture.Width - 1;
        //            //int heightTex = this.material.Texture.Height - 1;
        //            //this.material.Color = this.material.Texture.GetPixel((int)(u * widthTex), (int)(v * heightTex));
        //            intersect.CurrentTextureCoordinate.U = u;
        //            intersect.CurrentTextureCoordinate.V = v;
        //        }
        //        return true;
        //    }
        //    return false;
        //}

        #endregion

        public override bool FindIntersection(Ray ray, out Intersection intersect)
        {
            intersect = new Intersection();
            float u, v;

            /* begin calculating determinant - also used to calculate U parameter */
            Vector3D pvec = ray.Direction ^ this.edge2;

            /* if determinant is near zero, ray lies in plane of triangle */
            float det = this.edge1 * pvec;

            /* calculate distance from vert0 to ray origin */
            Vector3D tvec    = ray.Origin - this.vertex1;
            float    inv_det = 1.0f / det;

            Vector3D qvec = tvec ^ this.edge1;

            if (det > MathUtil.Epsilon)
            {
                u = (tvec * pvec);
                if (u < 0.0 || u > det)
                {
                    return(false);
                }

                /* calculate V parameter and test bounds */
                v = (ray.Direction * qvec);
                if (v < 0.0 || u + v > det)
                {
                    return(false);
                }
            }
            else if (det < -MathUtil.Epsilon)
            {
                /* calculate U parameter and test bounds */
                u = (tvec * pvec);
                if (u > 0.0 || u < det)
                {
                    return(false);
                }

                /* calculate V parameter and test bounds */
                v = (ray.Direction * qvec);
                if (v > 0.0 || u + v < det)
                {
                    return(false);
                }
            }
            else
            {
                return(false);  /* ray is parallell to the plane of the triangle */
            }
            u *= inv_det;
            v *= inv_det;
            float alpha = 1.0f - (u + v);

            const double epsilon = 2.5E-2;

            if (this.Wireframed && (!u.NearZero(epsilon) && !v.NearZero(epsilon) && !alpha.NearZero(epsilon)))
            {
                return(false);
            }

            intersect.Normal = this.normal;
            intersect.TMin   = (edge2 * qvec) * inv_det;
            if (intersect.TMin >= MathUtil.Epsilon)
            {
                intersect.HitPoint = ray.Origin + (intersect.TMin * ray.Direction);
                this.CurrentBarycentricCoordinate = new BarycentricCoordinate(alpha, u, v);
                intersect.HitPrimitive            = this;
                if (this.material != null && this.material.IsTexturized)
                {
                    int widthTex  = this.material.Texture.Width - 1;
                    int heightTex = this.material.Texture.Height - 1;
                    this.material.DiffuseColor = this.material.Texture.GetPixel((int)(u * widthTex),
                                                                                (int)(v * heightTex));
                    intersect.CurrentTextureCoordinate.U = u;
                    intersect.CurrentTextureCoordinate.V = v;
                }
                return(true);
            }

            return(false);
        }
예제 #9
0
        //From http://jgt.akpeters.com/papers/GuigueDevillers03/ray_triangle_intersection.html
        public bool FindIntersection(Ray ray, out Intersection intersect)
        {
            intersect = new Intersection();
            Vector3D vect0, vect1, nvect;
            float    det, inv_det;

            vect0 = this.Vertex2.Position - this.Vertex1.Position;
            vect1 = this.Vertex3.Position - this.Vertex1.Position;
            Vector3D normalNonNormalized = vect0 ^ vect1;

            /* orientation of the ray with respect to the triangle's normal,
             * also used to calculate output parameters*/
            det = -(ray.Direction * normalNonNormalized);
#if TEST_CULL
            /* define TEST_CULL if culling is desired */
            if (det < MathUtil.Epsilon)
            {
                return(false);
            }

            /* calculate vector from ray origin to this.vertex1 */
            vect0 = this.Vertex1.Position - ray.Origin;
            /* vector used to calculate u and v parameters */
            nvect = ray.Direction ^ vect0;

            /* calculate vector from ray origin to this.vertex2*/
            vect1 = this.Vertex2.Position - ray.Origin;
            /* calculate unnormalized v parameter and test bounds */
            float v = -(vect1 * nvect);

            if (v < 0.0 || v > det)
            {
                return(false);
            }

            /* calculate vector from ray origin to this.vertex3*/
            vect1 = this.Vertex3.Position - ray.Origin;
            /* calculate unnormalized v parameter and test bounds */
            float u = vect1 * nvect;

            if (u < 0.0 || u + v > det)
            {
                return(false);
            }

            /* calculate unormalized t parameter */
            float t = -(vect0 * normalNonNormalized);

            inv_det = 1.0f / det;
            /* calculate u v t, ray intersects triangle */
            u = u * inv_det;
            v = v * inv_det;
            t = t * inv_det;
#else
            /* the non-culling branch */

            /* if determinant is near zero, ray is parallel to the plane of triangle */
            if (det.NearZero())
            {
                return(false);
            }

            /* calculate vector from ray origin to this.vertex1 */
            vect0 = this.Vertex1.Position - ray.Origin;

            /* normal vector used to calculate u and v parameters */
            nvect = ray.Direction ^ vect0;

            inv_det = 1.0f / det;
            /* calculate vector from ray origin to this.vertex2*/
            vect1 = this.Vertex2.Position - ray.Origin;

            /* calculate v parameter and test bounds */
            float v = -(vect1 * nvect) * inv_det;

            if (v < 0.0f || v > 1.0f)
            {
                return(false);
            }

            /* calculate vector from ray origin to this.vertex3*/
            vect1 = this.Vertex3.Position - ray.Origin;
            /* calculate v parameter and test bounds */
            float u = (vect1 * nvect) * inv_det;

            if (u < 0.0f || u + v > 1.0f)
            {
                return(false);
            }

            /* calculate t, ray intersects triangle */
            float t = -(vect0 * normalNonNormalized) * inv_det;
#endif

            //if (t < 100)
            //    return false;
            // return 1;

            //if (t < 100) //FIXME: the correct is t < 0, but dont work, why? tell me you! =P
            //{
            //    return false;
            //}
            if (t >= 0)
            {
                intersect.TMin     = t;
                intersect.Normal   = Vector3D.Normal(this.Vertex1.Position, this.Vertex2.Position, this.Vertex3.Position);
                intersect.HitPoint = ray.Origin + (t * ray.Direction);
                this.CurrentBarycentricCoordinate = new BarycentricCoordinate(1.0f - (u + v), u, v);
                intersect.HitPrimitive            = this;
                return(true);
            }
            return(false);
        }