Пример #1
0
 public PointLight(Color clr, Vector3D position, double constant, double range, double linear, double quadratic)
     : base(clr, position, 1 / constant)
 {
     this.range = range;
     this.linear = linear;
     this.quadratic = quadratic;
 }
Пример #2
0
 public Light(Color clr, Vector3D position, double intensity)
 {
     this.clr = clr;
     this.position = position;
     this.intensity = intensity;
     clr3D = new Vector3D((double)clr.R / 255, (double)clr.G / 255, (double)clr.B / 255);
 }
Пример #3
0
 public override double LuminosityForPoint(Vector3D point)
 {
     double distance = (position - point).Length();
     if (distance > range)
         return 0;
     double attenuation = intensity + linear * distance + quadratic * (distance * distance);
     return 1 / attenuation;
 }
Пример #4
0
 public RGBA_D Shade(Ray ray, Vector3D pos, uint subIdx, out Ray reflection, out Ray refraction,
                     ISceneManager scene)
 {
     if (shader != null)
         return shader.Shade(ray, pos, subIdx, this, scene, out reflection, out refraction);
     reflection = null;
     refraction = null;
     return RGBA_D.Empty;
 }
Пример #5
0
 public bool IntersectWithLimitedLine(Vector3D linePoint1, Vector3D linePoint2,
                                      Vector3D lineDir, out Vector3D intersectPoint)
 {
     // first intersect with plane
     if (plane.GetIntersectionWithLimitedLine(linePoint1, linePoint2, lineDir, out intersectPoint))
     {
         // check within rectangle area
         if (intersectPoint >= min && intersectPoint <= max)
         {
             return true;
         }
     }
     return false;
 }
Пример #6
0
        public bool GetFirstIntersection(Vector3D origin, Vector3D dir, double maxLength, out IOpticalSceneObject obj,
                                         out Vector3D iPos, out double iDistance, out uint subIdx)
        {
            // intersect all bounds
            Vector3D endPt = origin + (dir * maxLength);
            double nDist = double.MaxValue;
            int nIdx = -1;
            Vector3D nPt = Vector3D.Empty;
            subIdx = 0;
            for (int i = 0; i < objects.Count; i++)
            {
                double dist = 0;
                if (objects[i].Radius == -1 ||
                    (SphereSceneObject.IntersectRaySphere(origin, dir, objects[i].Origin, objects[i].Radius * objects[i].Radius,
                    out dist) && dist < nDist))
                {
                    // try actual intesection
                    Vector3D pt;
                    if (objects[i].GetIntersect(origin, endPt, dir, out pt, out dist, out subIdx) && dist < nDist && dist > 0.01)
                    {
                        nDist = dist;
                        nIdx = i;
                        nPt = pt;
                    }
                    /*else
                    {
                        nDist = dist;
                        nIdx = i;
                        nPt = pt;
                        subIdx = 3;
                    }*/
                }
            }

            // pass back intersection if falls within rays remaining length
            if (nIdx != -1 && nDist < maxLength)
            {
                obj = objects[nIdx];
                iPos = nPt; // even needed?
                iDistance = nDist;
                return true;
            }
            obj = null;
            iPos = Vector3D.Empty;
            iDistance = double.NaN;
            return false;
        }
Пример #7
0
 public bool IntersectWithLine(Vector3D linePoint, Vector3D lineDir,
                               out Vector3D intersectPoint)
 {
     // first intersect with plane
     // TODO: Select if backfacing allowed or not
     if (/*plane.IsFrontFacting(-lineDir) &&*/ plane.GetIntersectionWithLineIgnoreBackfacing(linePoint, lineDir, out intersectPoint))
     {
         // round the intersection off slightly
         intersectPoint.Round(10);
         // check within rectangle area
         if (intersectPoint >= min && intersectPoint <= max)
         {
             return true;
         }
     }
     intersectPoint = Vector3D.Empty;
     return false;
 }
Пример #8
0
        public HeightFieldObject(Vector3D origin, MaterialShader shader, Vector2D size, Bitmap bitmapSrc)
            : base(origin, shader, -1)
        {
            this.bitmapSrc = bitmapSrc;
            // calculate bounds
            areaExtent = size;
            Vector2D halfSize = size * 0.5;
            areaStart = origin - halfSize;
            areaEnd = origin + halfSize;
            double szLen = size.Length();
            radius = Math.Sqrt((szLen * szLen) + (1.1 * 1.1)) / 2;

            hField = HeightField.FromBitmap(bitmapSrc);

            onePx = new Vector2D(areaExtent.X / hField.Width, areaExtent.Y / hField.Height);

            this.origin.Y = 0.5;

            zMin = 0;
            zTop = 1;

            rectangles = new Rectangle3D[]
            {
                new Rectangle3D(new Vector3D(areaStart.X, zTop, areaStart.Y), new Vector3D(areaEnd.X, zTop, areaEnd.Y),
                                new PlaneD(new Vector3D(0, 1, 0), -zTop)),           // top
                new Rectangle3D(new Vector3D(areaStart.X, zMin, areaStart.Y), new Vector3D(areaEnd.X, zMin, areaEnd.Y),
                                new PlaneD(new Vector3D(0, -1, 0), zMin)),          // bottom
                new Rectangle3D(new Vector3D(areaStart.X, zMin, areaStart.Y), new Vector3D(areaStart.X, zTop, areaEnd.Y), 
                                new PlaneD(new Vector3D(-1, 0, 0), halfSize.X)),    // left
                new Rectangle3D(new Vector3D(areaEnd.X, zMin, areaStart.Y), new Vector3D(areaEnd.X, zTop, areaEnd.Y),
                                new PlaneD(new Vector3D(1, 0, 0), -halfSize.X)),     // right
                new Rectangle3D(new Vector3D(areaStart.X, zMin, areaStart.Y), new Vector3D(areaEnd.X, zTop, areaStart.Y),
                                new PlaneD(new Vector3D(0, 0, -1), halfSize.Y)),    // front 
                new Rectangle3D(new Vector3D(areaStart.X, zMin, areaEnd.Y), new Vector3D(areaEnd.X, zTop, areaEnd.Y),
                                new PlaneD(new Vector3D(0, 0, 1), -halfSize.Y)),     // back
            };
        }
        public TriangleGroupSceneObject(Vector3D origin, MaterialShader shader, double radius)
            : base(origin, shader, radius)
        {
            // determine scaling factor
            double scale = Math.Sqrt((radius * radius) / 2);
            this.radius *= 2;
            points = new Vector3D[] { new Vector3D(-1, -1, 1), new Vector3D(-1, 1, 1),
                                      new Vector3D(1, 1, 1), new Vector3D(1, -1, 1),
                                      new Vector3D(-1, -1, -1), new Vector3D(-1, 1, -1),
                                      new Vector3D(1, 1, -1), new Vector3D(1, -1, -1)  };
            
            // tansform points
            for (int i = 0; i < points.Length; i++)
            {
                points[i].X *= scale;
                points[i].X += origin.X;
                points[i].Y *= scale;
                points[i].Y += origin.Y;
                points[i].Z *= scale;
                points[i].Z += origin.Z;
            }

            triangles = new Triangle[] { new Triangle(4, 7, 6), new Triangle(6, 5, 4),
                                         new Triangle(2, 3, 0), new Triangle(0, 1, 2),
                                         new Triangle(1, 0, 4), new Triangle(4, 5, 1),
                                         new Triangle(7, 3, 2), new Triangle(2, 6, 7),
                                         new Triangle(0, 3, 7), new Triangle(7, 4, 0),
                                         new Triangle(6, 2, 1), new Triangle(1, 5, 6) };

            tCoords = new Vector2D[] { new Vector2D(0, 0), new Vector2D(0, 1), new Vector2D(1, 1), 
                                       new Vector2D(1, 1), new Vector2D(1, 0), new Vector2D(0, 0), 
            };

            CalcFaceNormals();
            CalcVertexNormals();
        }
Пример #10
0
 public static Vector3D Reflect(Vector3D i, Vector3D n)
 {
     return Normalize(new Vector3D(i.X - (2.0 * n.X * Dot(n, i)),
                                   i.Y - (2.0 * n.Y * Dot(n, i)),
                                   i.Z - (2.0 * n.Z * Dot(n, i))));
 }
Пример #11
0
 public static Vector3D Cross(Vector3D u, Vector3D w)
 {
     // u x w
     return new Vector3D(w.Z * u.Y - w.Y * u.Z, w.X * u.Z - w.Z * u.X, w.Y * u.X - w.X * u.Y);
 }
Пример #12
0
 public static double modv(Vector3D v)
 {
     return Math.Sqrt(v.X * v.X + v.Y * v.Y + v.Z * v.Z);
 }
Пример #13
0
 public static Vector3D Normalize(Vector3D source)
 {
     double mod_v = modv(source);
     if (Math.Abs(mod_v) < 1.0E-10)
         return Empty;
     return new Vector3D(source.X / mod_v, source.Y / mod_v, source.Z / mod_v);
 }
Пример #14
0
        public RGBA_D Shade(Ray ray, Vector3D hitPoint, uint subIdx, IOpticalSceneObject obj,
                            ISceneManager scene, out Ray reflection, out Ray refraction)
        {
            RGBA_D color = RGBA_D.Empty;

            // needed?
            // normal.Normalize();
            
            Vector3D normal = obj.GetNormal(hitPoint, subIdx);

            //color.R = normal.X * 255;
            //color.G = normal.Y * 255;
            //color.B = normal.Z * 255;
            //color.A = 255;
            //refraction = null;
            //reflection = null;
            //return color;

            /*double len = (ray.Origin - hitPoint).Length();
            len -= 2;
            color.R = color.G = color.B = len * 42.5;*/

            foreach (Light light in scene.Lights)
            {
                Vector3D lv = light.Position - hitPoint;
                lv.Normalize();

                // deal with light ray first (diffuse)
                if (true)//ray.TraceRayToLight(hitPoint, light.Position))
                {
                    // light pixel
                    double cost = Vector3D.GetCosAngle(lv, normal);
                    Vector3D vRefl = Vector3D.Reflect(-lv, normal);
                    vRefl.Normalize();

                    double cosf = Vector3D.GetCosAngle(ray.DirectionUV, vRefl);
                    double result1 = Math.Max(0, cost) * 255;
                    double result2 = Math.Pow(Math.Max(0, cosf), shininess) * 255;

                    double luminosity = light.LuminosityForPoint(hitPoint);

                    double r = ((clr.R * diffuse * light.Clr3D.X * result1) +
                                (light.Clr3D.X * result2)) * luminosity;
                    double g = ((clr.G * diffuse * light.Clr3D.Y * result1) +
                                (light.Clr3D.Y * result2)) * luminosity;
                    double b = ((clr.B * diffuse * light.Clr3D.Z * result1) +
                                (light.Clr3D.Z * result2)) * luminosity;

                    color.R += r;
                    color.G += g;
                    color.B += b;
                }
            }
            
            // add ambient
            double alpha = 1 - transmission;
            color.R += (diffuse * scene.Ambient.R + (clr.R * emmissive)) * 255;
            //color.R *= alpha;
            color.G += (diffuse * scene.Ambient.G + (clr.G * emmissive)) * 255;
            //color.G *= alpha;
            color.B += (diffuse * scene.Ambient.B + (clr.B * emmissive)) * 255;
            //color.B *= alpha;
            
            color.A = alpha * 255;

            // blend texture (if any)
            /*if (texture != null)
            {
                Vector2D tCoord = obj.GetTexCoord(hitPoint, subIdx);
                // clamp for now
                if (tCoord.X < 0)
                    tCoord.X = 0;
                if (tCoord.Y < 0)
                    tCoord.Y = 0;
                if (tCoord.X > 1)
                    tCoord.X = 1;
                if (tCoord.Y > 1)
                    tCoord.Y = 1;

                int tX = (int)(tCoord.X * (texture.Width - 1));
                int tY = (int)(tCoord.Y * (texture.Height - 1));

                Color tClr = ((Bitmap)texture).GetPixel(tX, tY);
                color.R = (color.R + tClr.R) / 2;
                color.G = (color.G + tClr.G) / 2;
                color.B = (color.B + tClr.B) / 2;
            }*/

            if (ray.Intensity > 0)
            {
                /*if (this.reflection > 0)
                {
                    Vector3D refl = Vector3D.Reflect(ray.DirectionUV, normal);
                    reflection = new Ray(hitPoint, refl, ray.Intensity * this.reflection, ray.Length, ray.MaxLength, ray.scene);
                }
                else*/
                    reflection = null;
                /*if (transmission > 0)
                    refraction = new Ray(hitPoint, Vector3D.Normalize(Vector3D.Refract(1, 1.33, -ray.DirectionUV, normal)), ray.Intensity * transmission, ray.Length, ray.MaxLength, ray.scene);
                else*/
                refraction = null;
            }
            else
                reflection = refraction = null;

            ray.Intensity = 0;

            return color;
        }
Пример #15
0
 public static double Dot(Vector3D a, Vector3D b)
 {
     return (a.X * b.X) + (a.Y * b.Y) + (a.Z * b.Z);
 }
Пример #16
0
 public abstract Vector3D GetNormal(Vector3D pos, uint subIdx);
Пример #17
0
 public abstract bool GetIntersect(Vector3D p1, Vector3D p2, Vector3D uv, out Vector3D iPos, out double iDist, out uint subIdx);
Пример #18
0
 /// <summary>
 /// Returns if the point represented by this vector is between to points
 ///</summary>
 ///<param name="begin">Start point of line</param>
 ///<param name="end">End point of line</param>
 ///<returns> True if between points, false if not. </returns>
 public bool IsBetweenPoints(Vector3D begin, Vector3D end)
 {
     double f = (end - begin).Length();
     return GetDistanceFromSQ(begin) < f &&
            GetDistanceFromSQ(end) < f;
 }
Пример #19
0
 public abstract Vector2D GetTexCoord(Vector3D p, uint subIdx);
Пример #20
0
 public double Dot(Vector3D b)
 {
     return (X * b.X) + (Y * b.Y) + (Z * b.Z);
 }
Пример #21
0
        public static double GetCosAngle(Vector3D v1, Vector3D v2)
        {
            /* incident angle
            // inters pt (i)
            double ix, iy, iz;
            ix = px+t*vx;
            iy = py+t*vy;
            iz = pz+t*vz;

            // normal at i
            double nx, ny, nz;
            nx = ix - cx;
            ny = iy - cy;
            nz = iz - cz;
            */
            v1.Normalize();
            v2.Normalize();

            // cos(t) = (v.w) / (|v|.|w|)
            double n = (v1.X * v2.X + v1.Y * v2.Y + v1.Z * v2.Z);
            double d = (modv(v1) * modv(v2));

            if (Math.Abs(d) < 1.0E-10)
                return 0;
            return n / d;
        }
Пример #22
0
        public override bool GetIntersect(Vector3D p1, Vector3D p2, Vector3D uv, out Vector3D iPos,
                                          out double iDist, out uint subIdx)
        {
            subIdx = 0;
            if (IntersectRaySphere(p1, uv, origin, radius * radius, out iDist))
            {
                iPos = p1 - (iDist * uv);
                return true;
            }

            iPos = Vector3D.Empty;
            return false;
            /*subIdx = 0;

            Vector3D dst = p1 - origin;
            double B = Vector3D.Dot(dst, uv);
            double C = Vector3D.Dot(dst, dst) - (radius * radius);
            double D = B * B - C;
            if (D > 0)
            {
                iDist = -B - Math.Sqrt(D);
                iPos = p1 + (uv * iDist);
                return true;
            }
            iDist = -1;
            iPos = Vector3D.Empty;
            return false;*/

            // x-xo 2 + y-yo 2 + z-zo 2 = r 2
            // x,y,z = p+tv 
            // At2 + Bt + C = 0
            /*double vx = p2.X - p1.X;
            double vy = p2.Y - p1.Y;
            double vz = p2.Z - p1.Z;

            double A = (vx * vx + vy * vy + vz * vz);
            double B = 2.0 * (p1.X * vx + p1.Y * vy +
                       p1.Z * vz - vx * origin.X - vy * origin.Y - vz * origin.Z);
            double C = p1.X * p1.X - 2 * p1.X * origin.X + origin.X * origin.X +
                       p1.Y * p1.Y - 2 * p1.Y * origin.Y + origin.Y * origin.Y +
                       p1.Z * p1.Z - 2 * p1.Z * origin.Z + origin.Z * origin.Z -
                       radius * radius;
            double D = B * B - 4 * A * C;
            iDist = -1.0;
            subIdx = 0;

            if (D >= 0)
            {
                double t1 = (-B - Math.Sqrt(D)) / (2.0 * A);
                double t2 = (-B + Math.Sqrt(D)) / (2.0 * A);
                if (t1 < t2)
                    iDist = t1;
                else
                    iDist = t2;

                Vector3D hLen = new Vector3D(iDist * vx, iDist * vy, iDist * vz);
                iDist = hLen.Length();
                iPos = p1 + hLen;//new Vector3D(p1.X + (iDist * vx), p1.Y + (iDist * vy), p1.Z + (iDist * vz));
                return true;
            }
            iPos = Vector3D.Empty;
            return false;*/
        }
Пример #23
0
 public override Vector3D GetNormal(Vector3D pos, uint subIdx)
 {
     return Vector3D.Normalize(new Vector3D(pos.X - origin.X, pos.Y - origin.Y, pos.Z - origin.Z));
 }
Пример #24
0
 public SphereSceneObject(Vector3D origin, MaterialShader shader, double radius)
     : base(origin, shader, radius)
 {
 }
Пример #25
0
        public static Vector3D Refract(double n1, double n2,
                                   Vector3D i,
                                   Vector3D mirror)
        {
            double c1 = -Dot(mirror, i);
            double n = n1 / n2;

            double c2 = Math.Sqrt(1.0 - n * n * (1.0 - c1 * c1));
            return new Vector3D((n * i.X) + (n * c1 - c2) * mirror.X,
                                (n * i.Y) + (n * c1 - c2) * mirror.Y,
                                (n * i.Z) + (n * c1 - c2) * mirror.Z);
        }
Пример #26
0
 public abstract double LuminosityForPoint(Vector3D point);
Пример #27
0
 public Vector3D Cross(Vector3D w)
 {
     // u x w
     return new Vector3D(w.Z * Y - w.Y * Z, w.X * Z - w.Z * X, w.Y * X - w.X * Y);
 }
Пример #28
0
 public DirectionalLight(Color clr, Vector3D position, double intensity)
     : base(clr, position, intensity)
 {
 }
Пример #29
0
 /// <summary>
 /// Returns squared distance from an other point.
 /// Here, the vector is interpreted as point in 3 dimensional space.
 /// </summary>
 public double GetDistanceFromSQ(Vector3D other)
 {
     double vx = X - other.X; double vy = Y - other.Y; double vz = Z - other.Z;
     return (vx*vx + vy*vy + vz*vz);
 }
Пример #30
0
 public override double LuminosityForPoint(Vector3D point)
 {
     throw new System.NotImplementedException();
 }