Esempio n. 1
0
        public virtual void Draw(Vector3d location, Quaterniond rotation)
        {
            Matrix4d trans;
            Matrix4d rot;
            Matrix4d sca;
            Matrix4d temp;
            Vector3d axis;
            double   angle;

            //Console.WriteLine("DDDDrawing at {0},{1},{2}", location.X, location.Y, location.Z);

            // Translate and rotate stuff.
            trans = Matrix4d.CreateTranslation(location);
            rotation.ToAxisAngle(out axis, out angle);
            Matrix4d.CreateFromAxisAngle(axis, angle, out rot);
            sca = Matrix4d.Scale(scale.X, 1, scale.Y);

            temp = Matrix4d.Mult(Graphics.Modelview, trans);
            temp = Matrix4d.Mult(sca, Matrix4d.Mult(rot, temp));

            //Console.WriteLine("MMMMatrix:\n{0}", temp);
            GL.PushMatrix();
            GL.LoadMatrix(ref temp);
            //Console.WriteLine("Matrix'd");

            // Do drawing stuff.
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, frames[animFrame]);
            geometry.Draw();
            GL.PopMatrix();
        }
Esempio n. 2
0
        public virtual void Draw(Vector3d location, Quaterniond rotation)
        {
            Matrix4d trans;
            Matrix4d rot;
            Matrix4d sca;
            Matrix4d temp;
            Vector3d axis;
            double   angle;

            // Translate and rotate stuff.
            trans = Matrix4d.CreateTranslation(location);
            rotation.ToAxisAngle(out axis, out angle);
            Matrix4d.CreateFromAxisAngle(axis, angle, out rot);
            sca = Matrix4d.Scale(scale.X, 1, scale.Y);

            temp = Matrix4d.Mult(Graphics.Modelview, trans);
            temp = Matrix4d.Mult(sca, Matrix4d.Mult(rot, temp));

            GL.PushMatrix();
            GL.LoadMatrix(ref temp);
            //Console.WriteLine("Matrix'd");

            // Do drawing stuff.
            //GL.ClientActiveTexture(TextureUnit.Texture0);
            //GL.ActiveTexture(TextureUnit.Texture1);
            //GL.BindTexture(TextureTarget.Texture2D, tex);
            //int loc = GL.GetUniformLocation(Graphics.CurrentShader, "tex1");
            //GL.Uniform1(loc, 1);
            //Console.WriteLine("Texture'd {0}", tex);

            material.Draw();
            geometry.Draw();
            GL.PopMatrix();
        }
Esempio n. 3
0
 public InputManager(KeyboardDevice keyboard)
 {
     _config   = new CameraConfig(new Vector3d(10, 0, 0), new Vector3d(-1, 0, 0), new Vector3d(0, 1, 0), 1, 0, 1);
     _keyboard = keyboard;
     _bindings = new Dictionary <Key, Action <float> >
     {
         { Key.W, dt => _config.Position += _config.Lookat * dt * _config.MoveSpeed },
         { Key.S, dt => _config.Position -= _config.Lookat * dt * _config.MoveSpeed },
         { Key.A, dt => _config.Position += Vector3d.Cross(_config.Up, _config.Lookat) * dt * _config.MoveSpeed },
         { Key.D, dt => _config.Position -= Vector3d.Cross(_config.Up, _config.Lookat) * dt * _config.MoveSpeed },
         { Key.ShiftLeft, dt => _config.Position += _config.Up * dt * _config.MoveSpeed },
         { Key.Space, dt => _config.Position -= _config.Up * dt * _config.MoveSpeed },
         { Key.Q, dt => _config.Up = Vector3d.Transform(_config.Up, Matrix4d.CreateFromAxisAngle(_config.Lookat, TurnSpeed * dt)) },
         { Key.E, dt => _config.Up = Vector3d.Transform(_config.Up, Matrix4d.CreateFromAxisAngle(_config.Lookat, -TurnSpeed * dt)) },
         { Key.Left, dt => _config.Lookat = Vector3d.Transform(_config.Lookat, Matrix4d.CreateFromAxisAngle(_config.Up, TurnSpeed * dt * _config.Fov)) },
         { Key.Right, dt => _config.Lookat = Vector3d.Transform(_config.Lookat, Matrix4d.CreateFromAxisAngle(_config.Up, -TurnSpeed * dt * _config.Fov)) },
         { Key.Up, dt => _config.Lookat = Vector3d.Transform(_config.Lookat, Matrix4d.CreateFromAxisAngle(Vector3d.Cross(_config.Up, _config.Lookat), TurnSpeed * dt * _config.Fov)) },
         { Key.Down, dt => _config.Lookat = Vector3d.Transform(_config.Lookat, Matrix4d.CreateFromAxisAngle(Vector3d.Cross(_config.Up, _config.Lookat), -TurnSpeed * dt * _config.Fov)) },
         { Key.R, dt => _config.MoveSpeed *= 1 + dt },
         { Key.F, dt => _config.MoveSpeed *= 1 - dt },
         { Key.N, dt => _config.Fov *= 1 + dt },
         { Key.M, dt => _config.Fov *= 1 - dt }
     };
     _keyboard.KeyDown += KeyboardOnKeyDown;
 }
        public void Update(double elapsedTime, EntityManager entityManager)
        {
            var speedExponent = Math.Max(0.5, Math.Log10(Math.Abs(_camera.Position.Y)));
            var delta         = (elapsedTime - _lastUpdate) * Math.Pow(10, speedExponent);

            var up = Vector3d.Cross(_camera.Right, _camera.Forward).Normalized();

            var  direction = new Vector3d(0, 0, 0);
            bool keyDown   = false;

            if (_keyboardInputProcessor.IsButtonDown(Key.W))
            {
                direction += _camera.Forward;
                keyDown    = true;
            }
            if (_keyboardInputProcessor.IsButtonDown(Key.S))
            {
                direction += -_camera.Forward;
                keyDown    = true;
            }
            if (_keyboardInputProcessor.IsButtonDown(Key.D))
            {
                direction += _camera.Right;
                keyDown    = true;
            }
            if (_keyboardInputProcessor.IsButtonDown(Key.A))
            {
                direction += -_camera.Right;
                keyDown    = true;
            }
            if (_keyboardInputProcessor.IsButtonDown(Key.LShift))
            {
                direction += up;
                keyDown    = true;
            }
            if (_keyboardInputProcessor.IsButtonDown(Key.LControl))
            {
                direction += -up;
                keyDown    = true;
            }

            if (keyDown)
            {
                var result = Vector3d.Multiply(direction.Normalized(), delta);
                _camera.Target   += result;
                _camera.Position += result;
            }

            var relativeMousePositionDelta = _mouseInputProcessor.GetMousePositionDelta();
            var rotation = Matrix4d.CreateFromAxisAngle(up, -relativeMousePositionDelta.X / 500.0) * Matrix4d.CreateFromAxisAngle(_camera.Right, -relativeMousePositionDelta.Y / 500.0);
            var rotated  = Vector3d.Transform(_camera.Forward, rotation);

            _camera.Target = _camera.Position + rotated;

            _lastUpdate = elapsedTime;
        }
Esempio n. 5
0
        public static Location RotateAround(this ILocatable loc, ILocatable axis, float degs)
        {
            var a = degs * Math.PI / 180;
            var p = loc.ToPositionAboveSeaLeveld(0);
            var o = axis.ToPositionAboveSeaLeveld(0);

            o.Normalize();

            var m = Matrix4d.CreateFromAxisAngle(o, a);

            var r = m.Tx(p);

            return(r.ToLocation());
        }
Esempio n. 6
0
        Vector3d point(double ang)
        {
            var maxr = Math.Max(MajorRadius, MinorRadius);
            var minr = Math.Min(MajorRadius, MinorRadius);

            MajorRadius = maxr;
            MinorRadius = minr;

            var mtr4    = Matrix4d.CreateFromAxisAngle(Normal, ang);
            var res     = Vector4d.Transform(new Vector4d(norm), mtr4);
            var realAng = Vector3d.CalculateAngle(res.Xyz, RefDir);
            var rad     = MajorRadius * MinorRadius / (Math.Sqrt(Math.Pow(MajorRadius * Math.Sin(realAng), 2) + Math.Pow(MinorRadius * Math.Cos(realAng), 2)));

            res *= rad;
            return(Location + res.Xyz);
        }
Esempio n. 7
0
        public void Orbit(double aYaw, double aPitch)
        {
            Matrix4d m1 = Matrix4d.CreateFromAxisAngle(mUp, aYaw);
            Matrix4d m2 = Matrix4d.CreateFromAxisAngle(mRight, aPitch);
            Matrix4d m  = m1 * m2;
            Matrix4d mI = Matrix4d.Transpose(m);

            Vector3d tmp = mEye - mCenter;
            double   dst = tmp.Length;

            tmp.Normalize();

            mUp = Vector3d.Transform(mUp, mI);
            mUp.Normalize();
            tmp = Vector3d.Transform(tmp, mI);
            tmp.Normalize();
            mRight = Vector3d.Cross(mUp, tmp);
            mEye   = tmp * dst + mCenter;
        }
Esempio n. 8
0
        internal Vector3d CalcConjugateNormal()
        {
            var nm = tring1.GetPlane().Normal.Normalized();

            var          point0 = AuxPoint0;
            var          point1 = AuxPoint1;
            var          neg    = -nm;
            var          axis   = (edge.End - edge.Start).Normalized();
            PlaneSurface pp     = new PlaneSurface()
            {
                Position = edge.Start, Normal = axis
            };
            var prj0 = pp.ProjPoint(point0) - edge.Start;
            var prj1 = pp.ProjPoint(point1) - edge.Start;

            var crs1 = Vector3d.Cross(prj0, prj1) / prj0.Length / prj1.Length;
            var ang2 = Vector3d.CalculateAngle(prj0, prj1);

            if (crs1.Length > 1e-8)
            {
                axis = -crs1.Normalized();
            }
            var mtr    = Matrix4d.CreateFromAxisAngle(axis, ang2);
            var mtr2   = Matrix4d.CreateFromAxisAngle(axis, -ang2);
            var trans  = Vector3d.Transform(neg, mtr2);
            var check  = Vector3d.Transform(prj0.Normalized(), mtr);
            var check2 = Vector3d.Transform(prj1.Normalized(), mtr);

            if (!(Vector3d.Cross(tring2.GetPlane().Normal, trans).Length < 1e-8 || Vector3d.Cross(tring2.GetPlane().Normal, -trans).Length < 1e-8))
            {
                DebugHelper.Error?.Invoke("inconsistent normal was calculated");
            }

            normal1 = trans;
            return(trans);
        }
Esempio n. 9
0
        public override void Drag(OpenGLControlWrapper w, MouseEventArgs e)
        {
            if (_dragging == DragState.Idle)
            {
                return;
            }
            Lookat = Target.Position;
            switch (_dragging)
            {
            case DragState.ArcBalling:     // moving
            {
                var relativePosition = _eye - _lookat;
                var lookToward       = new Vector3d(-relativePosition);
                lookToward.Normalize();
                var right       = Vector3d.Cross(lookToward, Up);
                var yaw         = YawGain * (e.Location.X - _lastLocation.X);
                var yawMatrix   = Matrix4d.CreateFromAxisAngle(Up, yaw);
                var pitch       = PitchGain * (e.Location.Y - _lastLocation.Y);
                var pitchMatrix = Matrix4d.CreateFromAxisAngle(right, pitch);
                var distance    = relativePosition.Length;
                relativePosition = Vector3d.TransformVector(relativePosition, yawMatrix * pitchMatrix);
                relativePosition.Normalize();
                relativePosition = relativePosition * distance;

                _eye = _lookat + relativePosition;
                relativePosition.Normalize();
                Up = Vector3d.Cross(relativePosition, right);
                Up.Normalize();
                _lastLocation = e.Location;
            }
            break;

            case DragState.Scaling:     // scaling
            {
                var d    = ZoomGain * (e.Location.Y - _lastLocation.Y);
                var zoom = Math.Exp(d);
                var rp   = _startPosition * (ZoomFactor * zoom);
                _eye = _lookat + rp;
            }
            break;

            case DragState.RotatingUp:
            {
                var centerX = w.Width / 2;
                var centerY = w.Height / 2;
                var v1      = new Vector3d(_lastLocation.X - centerX, _lastLocation.Y - centerY, 0d);
                var v2      = new Vector3d(e.Location.X - centerX, e.Location.Y - centerY, 0d);
                var v3      = Vector3d.Cross(v1, v2);
                var v3Mag   = v3[2];
                var angDeg  = Math.Asin(v3Mag / (v1.Length * v2.Length));         //*180d/Math.PI
                var axis    = _lookat - _eye;
                axis.Normalize();
                var mat = Matrix4d.CreateFromAxisAngle(axis, -angDeg);
                Up = Vector3d.TransformVector(Up, mat); // was _startUp
                Up.Normalize();
                _lastLocation = e.Location;             // not sure about this
            }
            break;
            }
            Dirty = true;
            w.Invalidate();
        }
Esempio n. 10
0
        public override void UpdateMesh(ProjectPolygon[] p)
        {
            ProjectPolygons = p;

            PlaneSurface ps = new PlaneSurface()
            {
                Position = Location, Normal = Axis
            };
            var bs   = ps.GetBasis();
            var vec0 = bs[0] * Radius;

            //stage1
            //check nesting
            List <ProjectPolygon> tops = new List <ProjectPolygon>();

            foreach (var item in ProjectPolygons)
            {
                bool good = true;
                foreach (var item2 in ProjectPolygons)
                {
                    if (item == item2)
                    {
                        continue;
                    }
                    var pnts2 = item2.Points.ToArray();

                    if (GeometryUtils.pnpoly(pnts2, item.Points[0].X, item.Points[0].Y))
                    {
                        good = false; break;
                    }
                }
                if (good)
                {
                    tops.Add(item);
                }
            }

            List <Vector2d[]> triangls = new List <Vector2d[]>();
            double            step     = AngleStep / 180f * Math.PI;

            //extract 3d contours
            Contours.Clear();
            foreach (var item in tops)
            {
                var cc = new Contour3d();
                Contours.Add(cc);
                var maxy = item.Points.Max(z => z.Y) + 1;
                var miny = item.Points.Min(z => z.Y) - 1;
                for (int i = 0; i < item.Points.Count; i++)
                {
                    var             p0         = item.Points[i];
                    var             p1         = item.Points[(i + 1) % item.Points.Count];
                    double          last       = 0;
                    List <Vector2d> cutPoints  = new List <Vector2d>();
                    List <Vector2d> tempPoints = new List <Vector2d>();

                    cutPoints.Add(p0);

                    while (true)
                    {
                        var p00 = last;
                        var p11 = p00 + step;
                        last += step;

                        p00 = Math.Min(p00, 10 * Math.PI * 2);
                        p11 = Math.Min(p11, 10 * Math.PI * 2);

                        if (Math.Abs(p00 - p11) < 1e-8)
                        {
                            break;
                        }
                        Vector2d ret1 = Vector2d.Zero;


                        if (GeometryUtils.IntersectSegments(p0, p1, new Vector2d(p11, miny), new Vector2d(p11, maxy), ref ret1))
                        {
                            tempPoints.Add(ret1);
                        }
                    }
                    tempPoints.Add(p1);
                    while (tempPoints.Any())
                    {
                        var fr = tempPoints.OrderBy(z => (z - cutPoints.Last()).Length).First();
                        cutPoints.Add(fr);
                        tempPoints.Remove(fr);
                    }
                    for (int j = 0; j < cutPoints.Count; j++)
                    {
                        var ang  = cutPoints[j].X;
                        var mtr  = Matrix4d.CreateFromAxisAngle(Axis, -ang);
                        var rot0 = Vector3d.Transform(vec0 + Axis * cutPoints[j].Y * Lenght, mtr);
                        cc.Points.Add(Location + rot0);
                    }
                }
            }

            foreach (var item in tops)
            {
                List <ProjectPolygon> holes = new List <ProjectPolygon>();
                var pnts2 = item.Points.ToArray();

                foreach (var xitem in ProjectPolygons.Except(tops))
                {
                    if (GeometryUtils.pnpoly(pnts2, xitem.Points[0].X, xitem.Points[0].Y))
                    {
                        holes.Add(xitem);
                    }
                }


                PolyBoolCS.PolyBool pb = new PolyBoolCS.PolyBool();
                PolyBoolCS.Polygon  p1 = new PolyBoolCS.Polygon();
                var pl1 = new PolyBoolCS.PointList();
                p1.regions = new List <PolyBoolCS.PointList>();

                pl1.AddRange(item.Points.Select(z => new PolyBoolCS.Point(z.X, z.Y)).ToArray());
                p1.regions.Add(pl1);
                var    maxy = pl1.Max(z => z.y) + 1;
                var    miny = pl1.Min(z => z.y) - 1;
                double last = 0;
                while (true)
                //for (double i = step; i < (Math.PI * 2); i += step)
                {
                    var p0  = last;
                    var p11 = p0 + step;
                    last += step;

                    p0  = Math.Min(p0, 10 * Math.PI * 2);
                    p11 = Math.Min(p11, 10 * Math.PI * 2);

                    if (Math.Abs(p0 - p11) < 1e-8)
                    {
                        break;
                    }


                    PolyBoolCS.Polygon p2 = new PolyBoolCS.Polygon();
                    p2.regions = new List <PolyBoolCS.PointList>();
                    var pl2 = new PolyBoolCS.PointList();

                    pl2.Add(new PolyBoolCS.Point(p0, miny));
                    pl2.Add(new PolyBoolCS.Point(p0, maxy));
                    pl2.Add(new PolyBoolCS.Point(p11, maxy));
                    pl2.Add(new PolyBoolCS.Point(p11, miny));


                    p2.regions.Add(pl2);

                    if (holes.Any(z => GeometryUtils.AlmostEqual(z.Area(), 0)))
                    {
                        throw new GeomPadException("zero area contour detected");
                    }
                    var res = pb.intersect(p1, p2);
                    if (res.regions.Any())
                    {
                        foreach (var region in res.regions)
                        {
                            var triangls2 = GeometryUtils.TriangulateWithHoles(
                                new[] { region.Select(z => new Vector2d(z.x, z.y)).ToArray() }
                                ,
                                holes.Select(z => z.Points.ToArray()).ToArray(), true);
                            triangls.AddRange(triangls2);
                        }
                    }
                }
            }

            //stage2
            List <TriangleInfo> tt = new List <TriangleInfo>();

            foreach (var item in triangls)
            {
                TriangleInfo      tin = new TriangleInfo();
                List <VertexInfo> v   = new List <VertexInfo>();
                foreach (var d in item)
                {
                    var ang = d.X;
                    var mtr = Matrix4d.CreateFromAxisAngle(Axis, -ang);

                    var rot0 = Vector3d.Transform(vec0 + Axis * d.Y * Lenght, mtr);
                    v.Add(new VertexInfo()
                    {
                        Position = Location + rot0
                    });
                }
                var v01 = v[1].Position - v[0].Position;
                var v11 = v[2].Position - v[0].Position;
                var crs = Vector3d.Cross(v01, v11).Normalized();
                if (double.IsNaN(crs.X))
                {
                    throw new GeomPadException("normal is NaN");
                }
                foreach (var item0 in v)
                {
                    item0.Normal = crs;
                }
                tin.Vertices = v.ToArray();

                tt.Add(tin);
            }
            Mesh = new Mesh()
            {
                Triangles = tt
            };
        }
Esempio n. 11
0
        public override void Draw(IDrawingContext gr)
        {
            if (!Visible)
            {
                return;
            }
            GL.Color3(Color.Blue);
            if (Selected)
            {
                GL.Color3(Color.Red);
            }
            if (ShowGismos)
            {
                DrawHelpers.DrawCross(Location, DrawSize);
                PlaneSurface ps = new PlaneSurface()
                {
                    Position = Location, Normal = Axis
                };
                var             bs   = ps.GetBasis();
                var             dir  = bs[0] * Radius;
                List <Vector3d> pnts = new List <Vector3d>();
                var             step = Math.PI * AngleStep / 180f;
                for (double i = 0; i <= Math.PI * 2; i += step)
                {
                    var mtr4 = Matrix4d.CreateFromAxisAngle(Axis, i);
                    var res  = Vector4d.Transform(new Vector4d(dir), mtr4);
                    pnts.Add(Location + res.Xyz);
                }

                GL.Begin(PrimitiveType.LineStrip);
                for (int i = 0; i < pnts.Count; i++)
                {
                    GL.Vertex3(pnts[i]);
                }
                GL.End();
                pnts.Clear();

                for (double i = 0; i <= Math.PI * 2; i += step)
                {
                    var mtr4 = Matrix4d.CreateFromAxisAngle(Axis, i);
                    var res  = Vector4d.Transform(new Vector4d(dir), mtr4);
                    pnts.Add(Location + res.Xyz + Axis * Lenght);
                }

                GL.Begin(PrimitiveType.LineStrip);
                for (int i = 0; i < pnts.Count; i++)
                {
                    GL.Vertex3(pnts[i]);
                }
                GL.End();

                GL.Begin(PrimitiveType.Lines);
                GL.Vertex3(Location);
                GL.Vertex3(Location + Axis * Lenght);
                GL.End();
            }
            if (ShowMesh)
            {
                drawMesh();
            }
            drawContours();
        }
Esempio n. 12
0
 public void RotateAxis(Vector3d axis, double angle)
 {
     matrix          = Matrix4d.CreateFromAxisAngle(axis, angle) * matrix;
     inverse_matrix *= Matrix4d.CreateFromAxisAngle(axis, -angle);
 }
Esempio n. 13
0
        public LensRayTransferFunction.Parameters ConvertSurfaceRayToParameters(
            Ray ray,
            Vector3d canonicalNormal, double surfaceSinTheta,
            Sphere sphericalSurface, ElementSurface surface)
        {
            //Console.WriteLine("ray->parameters");
            // - convert origin
            //   *- transform to hemispherical coordinates
            //     - find out if it is on the surface
            //   *- scale with respect to the spherical cap
            //   *- normalize
            Vector3d unitSpherePos = (ray.Origin - sphericalSurface.Center) * sphericalSurface.RadiusInv;

            unitSpherePos.Z *= canonicalNormal.Z;
            //Console.WriteLine("unit sphere position: {0}", unitSpherePos);
            Vector2d originParametric = Sampler.SampleSphereWithUniformSpacingInverse(
                unitSpherePos, surfaceSinTheta, 1);

            // - convert direction
            //   *- transform from camera space to local frame
            //     *- compute normal at origin

            //Console.WriteLine("ray origin: {0}", ray.Origin);
            Vector3d normalLocal = surface.SurfaceNormalField.GetNormal(ray.Origin);

            normalLocal.Normalize(); // TODO: check if it is unnecessary
            //Console.WriteLine("local normal: {0}", normalLocal);
            //     *- create rotation quaternion from canonical normal to local
            //       normal
            Vector3d direction = ray.Direction;

            //Console.WriteLine("local direction: {0}", direction);
            if (surface.Convex)
            {
                direction = -direction;
            }
            Vector3d rotationAxis = Vector3d.Cross(canonicalNormal, normalLocal);

            //Console.WriteLine("rotation axis: {0}", rotationAxis);
            if (rotationAxis.Length > 0)
            {
                double angle = Math.Acos(Vector3d.Dot(normalLocal, canonicalNormal));
                //Console.WriteLine("angle: {0}", angle);
                double positionPhi = originParametric.Y;
                // first transformed to the frame of the local normal
                //Console.WriteLine("position phi: {0}", positionPhi);
                Matrix4d rotMatrix = Matrix4d.CreateFromAxisAngle(rotationAxis, -angle);
                // then rotate the local direction around Z using the position phi
                rotMatrix = rotMatrix * Matrix4d.CreateRotationZ(2 * Math.PI * -positionPhi);
                direction = Vector3d.Transform(direction, rotMatrix);
            }
            //Console.WriteLine("abs. direction: {0}", direction);

            //   *- transform to hemispherical coordinates
            //     - find out if it is within the local hemisphere
            double sinTheta = direction.Z / canonicalNormal.Z;
            double dirTheta = Math.Asin(sinTheta);

            double cosTheta = Math.Sqrt(1 - sinTheta * sinTheta);
            double dirPhi   = Math.Atan2(direction.Y, direction.X);

            if (dirPhi < 0)
            {
                // map [-PI; PI] to [0; 2*PI]
                dirPhi += 2 * Math.PI;
            }
            //   *- normalize
            Vector2d directionParametric = new Vector2d(
                dirTheta / (0.5 * Math.PI),
                dirPhi / (2 * Math.PI));

            //Console.WriteLine("position parameters: {0}", new Vector2d(
            //    originParametric.X, originParametric.Y));

            return(new LensRayTransferFunction.Parameters(
                       originParametric.X, originParametric.Y,
                       directionParametric.X, directionParametric.Y));
        }
Esempio n. 14
0
        /// <summary>
        /// Convert a ray with origin at the back or front lens surface from
        /// its parametric representation.
        /// </summary>
        /// <param name="position">Position on lens surface in parameteric
        /// representation (normalized hemispherical coordinates).</param>
        /// <param name="direction">Direction of the ray with respect to the
        /// local frame in parameteric representation (normalized hemispherical
        /// coordinates).
        /// </param>
        /// <param name="canonicalNormal">Normal of the lens surface
        /// hemisphere (typically (0,0,1) for the back surface or (0,0,-1) for
        /// the front surface).</param>
        /// <param name="surfaceSinTheta">Sine of the surface spherical cap
        /// theta angle.</param>
        /// <param name="sphericalSurface">Lens surface represented as a
        /// sphere.</param>
        /// <param name="surface">Lens surface with its normal field.</param>
        /// <returns>Ray corresponding to its parametric representation.
        /// </returns>
        public Ray ConvertParametersToSurfaceRay(
            LensRayTransferFunction.Parameters parameters,
            Vector3d canonicalNormal, double surfaceSinTheta,
            Sphere sphericalSurface, ElementSurface surface)
        {
            //Console.WriteLine("parameters->ray");

            //Console.WriteLine("position parameters: {0}", parameters.Position);
            // uniform spacing sampling for LRTF sampling
            Vector3d unitSpherePos = Sampler.SampleSphereWithUniformSpacing(
                parameters.Position, surfaceSinTheta, 1);

            //Console.WriteLine("unit sphere position: {0}", unitSpherePos);
            unitSpherePos.Z *= canonicalNormal.Z;

            Vector3d lensPos = sphericalSurface.Center + sphericalSurface.Radius * unitSpherePos;
            //Console.WriteLine("ray origin: {0}", lensPos);

            // - get normal N at P
            Vector3d normalLocal = surface.SurfaceNormalField.GetNormal(lensPos);
            // - compute direction D from spherical coordinates (wrt normal Z = (0,0,+/-1))
            double   theta      = 0.5 * Math.PI * parameters.DirectionTheta;
            double   phi        = 2 * Math.PI * parameters.DirectionPhi;
            double   cosTheta   = Math.Cos(theta);
            Vector3d directionZ = new Vector3d(
                Math.Cos(phi) * cosTheta,
                Math.Sin(phi) * cosTheta,
                Math.Sin(theta) * canonicalNormal.Z);

            // - rotate D from Z to N frame
            //   - using a (normalized) quaternion Q
            //   - N and Z should be assumed to be already normalized
            //   - more efficient method: Efficiently building a matrix to
            //     rotate one vector to another [moller1999]

            normalLocal.Normalize(); // TODO: check if it is unnecessary
            //Console.WriteLine("abs. direction: {0}", directionZ);
            //Console.WriteLine("local normal: {0}", normalLocal);
            Vector3d rotationAxis = Vector3d.Cross(canonicalNormal, normalLocal);
            //Console.WriteLine("rotation axis: {0}", rotationAxis);

            Vector3d rotatedDir = directionZ;

            if (rotationAxis.Length > 0)
            {
                double angle = Math.Acos(Vector3d.Dot(canonicalNormal, normalLocal));
                //Console.WriteLine("angle: {0}", angle);
                // first the local direction must be rotated around using the position phi!
                //Console.WriteLine("position phi: {0}", parameters.PositionPhi);
                Matrix4d rotMatrix = Matrix4d.CreateRotationZ(2 * Math.PI * parameters.PositionPhi);
                // only then can be transformed to the frame of the local normal
                rotMatrix  = rotMatrix * Matrix4d.CreateFromAxisAngle(rotationAxis, angle);
                rotatedDir = Vector3d.Transform(directionZ, rotMatrix);
            }
            if (surface.Convex)
            {
                rotatedDir = -rotatedDir;
            }
            //Console.WriteLine("local direction: {0}", rotatedDir);

            Ray result = new Ray(lensPos, rotatedDir);

            return(result);
        }