private void ButtonImport_OnClick(object sender, RoutedEventArgs e)
        {
            List <int> SelectedGroups = new List <int>();

            for (int i = 0; i < AvailableGroups.Count; i++)
            {
                foreach (var selectedItem in ListGroups.SelectedItems)
                {
                    if ((string)selectedItem == AvailableGroups[i])
                    {
                        SelectedGroups.Add(i);
                    }
                }
            }

            using (Stream SessionStream = File.OpenRead(SessionPath))
            {
                XPathDocument  Doc    = new XPathDocument(SessionStream);
                XPathNavigator Reader = Doc.CreateNavigator();
                Reader.MoveToRoot();

                int iGroup = 0;
                foreach (XPathNavigator groupNav in Reader.Select("//PointGroups/Group"))
                {
                    if (SelectedGroups.Contains(iGroup))
                    {
                        PointGroup NewGroup = new PointGroup
                        {
                            Name  = XMLHelper.LoadAttribute(groupNav, "Name", "Group " + (MainWindow.Options.Membrane.PointGroups.Count + 1)),
                            Size  = XMLHelper.LoadAttribute(groupNav, "Size", 10),
                            Color = ColorHelper.LoadAttribute(groupNav, "Color", ColorHelper.SpectrumColor(MainWindow.Options.Membrane.PointGroups.Count, 0.3f))
                        };
                        NewGroup.PointCloud.GLContext = MainWindow.Options.Viewport.GetControl();

                        foreach (XPathNavigator pointNav in groupNav.SelectChildren("Point", ""))
                        {
                            int          TriangleID = XMLHelper.LoadAttribute(pointNav, "ID", 0);
                            SurfacePoint NewPoint   = new SurfacePoint(OpenGLHelper.LoadAttribute(pointNav, "Position", new Vector3(0)),
                                                                       MainWindow.Options.Membrane.SurfaceMesh.Triangles[TriangleID < MainWindow.Options.Membrane.SurfaceMesh.Triangles.Count ? TriangleID : 0],
                                                                       OpenGLHelper.LoadAttribute(pointNav, "Barycentric", new Vector3(0)),
                                                                       XMLHelper.LoadAttribute(pointNav, "Offset", 0f),
                                                                       OpenGLHelper.LoadAttribute(pointNav, "Orientation", new Vector3(0)).X);
                            NewGroup.Points.Add(NewPoint);
                        }

                        MainWindow.Options.Membrane.PointGroups.Add(NewGroup);
                        NewGroup.IsVisible = XMLHelper.LoadAttribute(groupNav, "IsVisible", true);
                    }

                    iGroup++;
                }
            }

            if (SelectedGroups.Count > 0)
            {
                MainWindow.Options.Viewport.Redraw();
            }

            Close();
        }
        /// <summary>
        /// Инициализация матрицы
        /// </summary>
        /// <param name="surfacePoint">Ключевая(начальная) точка массива</param>
        /// <param name="countpointX">Количество точек/рядов сканирования по оси X</param>
        /// <param name="countpointY">Количество точек/строк сканирования по оси Y</param>
        /// <param name="stepx">Интервал между точками</param>
        /// <param name="stepy">Интервал между точками</param>
        public static void Init(SurfacePoint surfacePoint, int countpointX, int countpointY, float stepx, float stepy)
        {
            _primaryPosition = surfacePoint == null ? new SurfacePoint() : new SurfacePoint(surfacePoint);

            _countPointX = countpointX;
            _countPointY = countpointY;
            _stepX       = stepx;
            _stepY       = stepy;

            SpeedMove = 200;
            SpeedScan = 50;

            Matrix = new SurfacePoint[_countPointX, _countPointY];

            // заполним пустыми данными
            for (int y = 0; y < _countPointY; y++)
            {
                for (int x = 0; x < _countPointX; x++)
                {
                    SurfacePoint tmPoint = new SurfacePoint();

                    if (surfacePoint != null)
                    {
                        tmPoint.PosX = (x * stepx) + surfacePoint.PosX;
                        tmPoint.PosY = (y * stepy) + surfacePoint.PosY;
                        tmPoint.PosZ = surfacePoint.PosZ;
                    }
                    tmPoint.PosZ = 0;

                    Matrix[x, y] = new SurfacePoint(tmPoint);
                }
            }

            NotInit = false;
        }
示例#3
0
 public override (int, int, float) SelectBidirPath(SurfacePoint cameraPoint, Vector3 outDir,
                                                   int pixelIndex, RNG rng)
 {
     // Select a single vertex from the entire cache at random
     var(path, vertex) = vertexSelector.Select(rng);
     return(path, vertex, BidirSelectDensity());
 }
 /// <summary>
 /// Клонирование данных из существующей точки
 /// </summary>
 /// <param name="_point"></param>
 public SurfacePoint(SurfacePoint _point)
 {
     PosX = _point.PosX;
     PosY = _point.PosY;
     PosZ = _point.PosZ;
     //deltaZ = _point.deltaZ;
 }
示例#5
0
        /// <summary>
        /// Computes the inverse jacobian for the mapping from surface area around "to" to the sphere around "from".
        ///
        /// Required for integrals that perform this change of variables (e.g., next event estimation).
        ///
        /// Multiplying solid angle pdfs by this value computes the corresponding surface area density.
        /// Dividing surface area pdfs by this value computes the corresponding solid angle density.
        ///
        /// This function simply computes the cosine formed by the normal at "to" and the direction from "to" to "from".
        /// The absolute value of that cosine is then divided by the squared distance between the two points:
        ///
        /// result = cos(normal_to, from - to) / ||from - to||^2
        /// </summary>
        /// <param name="from">The position at which the hemispherical distribution is defined.</param>
        /// <param name="to">The point on the surface area that is projected onto the hemisphere.</param>
        /// <returns>Inverse jacobian, multiply solid angle densities by this value.</returns>
        public static float SurfaceAreaToSolidAngle(SurfacePoint from, SurfacePoint to)
        {
            var dir     = to.Position - from.Position;
            var distSqr = dir.LengthSquared();

            return(MathF.Abs(Vector3.Dot(to.Normal, -dir)) / (distSqr * MathF.Sqrt(distSqr)));
        }
示例#6
0
    protected virtual void ApplyGravity()
    {
        if (customGravity)
        {
            _relativeGravity = customGravityDirection.normalized * rigidbody.mass * gravityScale * -Physics2D.gravity.y;
        }
        else
        {
            if (alignToSurface)
            {
                surface = GetSurfacePoint(maxSurfaceDistance);
                if (surface)
                {
                    // rotate object to have the same normal as the surface point
                    transform.rotation = Quaternion.LookRotation(Vector3.forward, surface.normal);
                    // Set relative gravity to oposite the normal
                    _relativeGravity = -surface.normal * rigidbody.mass * gravityScale * -Physics2D.gravity.y;
                }
            }
            else if (flipWithPlayer)
            {
                _relativeGravity = GameMaster.gameMaster.relativeGravityDirection * rigidbody.mass * gravityScale * -Physics2D.gravity.y;
            }
        }

        if (invertGravity)
        {
            _relativeGravity *= -1;
        }
        if (Application.isPlaying && useGravity)
        {
            rigidbody.AddForce(_relativeGravity);
        }
    }
示例#7
0
        public void EmittedRays_Pdf_ShouldBeOneSided()
        {
            var mesh = new Mesh(
                new Vector3[] {
                new Vector3(-1, 10, -1),
                new Vector3(1, 10, -1),
                new Vector3(1, 10, 1),
                new Vector3(-1, 10, 1)
            }, new int[] {
                0, 1, 2,
                0, 2, 3
            },
                shadingNormals: new Vector3[] {
                new Vector3(0, 1, 0),
                new Vector3(0, 1, 0),
                new Vector3(0, 1, 0),
                new Vector3(0, 1, 0)
            }
                );
            var emitter = new DiffuseEmitter(mesh, RgbColor.White);

            var dummyHit = new SurfacePoint {
                Mesh = mesh
            };

            var p1 = emitter.PdfRay(dummyHit, new Vector3(0, 1, 1));
            var p2 = emitter.PdfRay(dummyHit, new Vector3(0, -1, 1));

            Assert.True(p1 > 0);
            Assert.Equal(0, p2);
        }
示例#8
0
        public void Emission_ShouldBeOneSided()
        {
            var mesh = new Mesh(
                new Vector3[] {
                new Vector3(-1, 10, -1),
                new Vector3(1, 10, -1),
                new Vector3(1, 10, 1),
                new Vector3(-1, 10, 1)
            }, new int[] {
                0, 1, 2,
                0, 2, 3
            },
                shadingNormals: new Vector3[] {
                new Vector3(0, 1, 0),
                new Vector3(0, 1, 0),
                new Vector3(0, 1, 0),
                new Vector3(0, 1, 0)
            }
                );
            var emitter = new DiffuseEmitter(mesh, RgbColor.White);

            var dummyHit = new SurfacePoint {
                Mesh = mesh
            };

            var r1 = emitter.EmittedRadiance(dummyHit, new Vector3(0, 1, 1));
            var r2 = emitter.EmittedRadiance(dummyHit, new Vector3(0, -1, 1));

            Assert.True(r1.R > 0);
            Assert.Equal(0, r2.R);
        }
        public override RgbColor OnCameraHit(CameraPath path, RNG rng, int pixelIndex, Ray ray,
                                             SurfacePoint hit, float pdfFromAncestor, RgbColor throughput,
                                             int depth, float toAncestorJacobian)
        {
            RgbColor value = RgbColor.Black;

            // Was a light hit?
            Emitter light = scene.QueryEmitter(hit);

            if (light != null)
            {
                value += throughput * OnEmitterHit(light, hit, ray, path, toAncestorJacobian);
            }

            // Perform connections if the maximum depth has not yet been reached
            if (depth < MaxDepth)
            {
                if (EnableConnections)
                {
                    value += throughput * BidirConnections(pixelIndex, hit, -ray.Direction, rng, path, toAncestorJacobian);
                }

                var nextEvtSum    = RgbColor.Black;
                var nextEvtSumSqr = RgbColor.Black;
                for (int i = 0; i < NumShadowRays; ++i)
                {
                    var c = throughput * PerformNextEventEstimation(ray, hit, rng, path, toAncestorJacobian);
                    nextEvtSum    += c;
                    nextEvtSumSqr += c * c;
                    value         += c;
                }
            }

            return(value);
        }
示例#10
0
        public virtual RgbColor EstimatePixelValue(SurfacePoint cameraPoint, Vector2 filmPosition, Ray primaryRay,
                                                   float pdfFromCamera, RgbColor initialWeight, RNG rng)
        {
            // Trace the primary ray into the scene
            var hit = scene.Raytracer.Trace(primaryRay);

            if (!hit)
            {
                return(scene.Background?.EmittedRadiance(primaryRay.Direction) ?? RgbColor.Black);
            }

            // Gather nearby photons
            float    radius   = scene.Radius / 100.0f;
            RgbColor estimate = photonMap.Accumulate(radius, hit, -primaryRay.Direction, Merge, radius);

            // Add contribution from directly visible light sources
            var light = scene.QueryEmitter(hit);

            if (light != null)
            {
                estimate += light.EmittedRadiance(hit, -primaryRay.Direction);
            }

            return(estimate);
        }
示例#11
0
        public EarthPoint InverseProject(Point Point, int Zoom)
        {
            double mpp          = _scales[Zoom];
            var    surfacePoint = new SurfacePoint(Point.X * mpp, -Point.Y * mpp);

            return((EarthPoint)surfacePoint);
        }
 public void MarsLanderNewData(int positionX, int positionY, int hSpeed, int vSpeed, int rotate, int power)
 {
     this.currentPoint = new SurfacePoint(positionX, positionY);
     this._hSpeed      = hSpeed;
     this._vSpeed      = vSpeed;
     this._rotate      = rotate;
     this._power       = power;
 }
示例#13
0
        /// <summary>
        /// The shading value at a primary hit point. The default implementation uses "eye light shading",
        /// i.e., the cosine between the outgoing direction and the normal.
        /// </summary>
        public virtual RgbColor ComputeColor(SurfacePoint hit, Vector3 from)
        {
            float cosine = Math.Abs(Vector3.Dot(hit.Normal, from));

            cosine /= hit.Normal.Length();
            cosine /= from.Length();
            return(RgbColor.White * cosine);
        }
        //нахождение высоты Z точки p0, лежащей на прямой между точками p3 p4  (прямая паралельна оси Y)
        private static SurfacePoint CalcPY(SurfacePoint p1, SurfacePoint p2, SurfacePoint p0)
        {
            SurfacePoint ReturnPoint = new SurfacePoint(p0.PosX, p0.PosY, p0.PosZ);

            ReturnPoint.PosZ = p1.PosZ + (((p1.PosZ - p2.PosZ) / (p1.PosY - p2.PosY)) * (p0.PosY - p1.PosY));

            return(ReturnPoint);
        }
        public double ClosestDistanceTo(SurfacePoint ladderPoint)
        {
            double powOfX   = Math.Pow((this._x - ladderPoint._x), 2);
            double powOfY   = Math.Pow((this._y - ladderPoint._y), 2);
            double distance = Math.Sqrt(powOfX + powOfY);

            return(distance);
        }
示例#16
0
 public override RgbColor EmittedRadiance(SurfacePoint point, Vector3 direction)
 {
     if (Vector3.Dot(point.ShadingNormal, direction) < 0)
     {
         return(RgbColor.Black);
     }
     return(Radiance);
 }
示例#17
0
        SurfacePoint Lin1(SurfacePoint p1, SurfacePoint p2, double t)
        {
            SurfacePoint q = new SurfacePoint();

            q.Vertex.X = p2.Vertex.X * t + p1.Vertex.X * (1 - t);
            q.Vertex.Y = p2.Vertex.Y * t + p1.Vertex.Y * (1 - t);
            q.Vertex.Z = p2.Vertex.Z * t + p1.Vertex.Z * (1 - t);
            return(q);
        }
示例#18
0
        public static bool IsVisible(
            Vector3d bodyCentredVesselPosition,
            SurfacePoint surfacePoint)
        {
            Vector3d surfaceToSatellite =
                bodyCentredVesselPosition - surfacePoint.bodyCentredSurfacePosition;

            return(Vector3d.Dot(surfaceToSatellite, surfacePoint.vertical) > 0);
        }
        /*
         *    Корректировка высоты по оси Z, у точки №5, зная высоту по Z у точек 1,2,3,4
         *
         *  /\ ось Y
         *  |
         *  |    (точка №1) -------------*--------------- (точка №2)
         *  |                            |
         *  |                            |
         *  |                            |
         *  |                       (точка №5)
         *  |                            |
         *  |                            |
         *  |    (точка №3) -------------*--------------- (точка №4)
         *  |
         *  |
         *  *----------------------------------------------------------------> ось X
         *  Корректировка выполняется следующим образом:
         *  1) зная координату X у точки 5, и координаты точек 1 и 2, вычисляем высоту Z в точке которая находится на линии точек 1,2 и перпендикулярно 5-й точке (получает точку №12)
         *  2) Тоже самое вычисляется для точки на линии точек 3,4 (получает точку №34)
         *  3) Зная координаты точек №12, №34 и значение по оси Y у точки 5, вычисляем высоту по оси Z
         */

        /// <summary>
        /// Функция корректирует высоту по оси Z
        /// </summary>
        /// <param name="p1">первая точка первой линии X</param>
        /// <param name="p2">вторая точка первой линии X</param>
        /// <param name="p3">первая точка второй линии X</param>
        /// <param name="p4">вторая точка второй линии X</param>
        /// <param name="p5">точка у которой нужно скорректировать высоту</param>
        /// <returns></returns>
        private static SurfacePoint GetZ(SurfacePoint p1, SurfacePoint p2, SurfacePoint p3, SurfacePoint p4, SurfacePoint p5)
        {
            SurfacePoint p12 = CalcPX(p1, p2, p5);
            SurfacePoint p34 = CalcPX(p3, p4, p5);

            SurfacePoint p1234 = CalcPY(p12, p34, p5);

            return(p1234);
        }
示例#20
0
        public override RgbColor EmittedRadiance(SurfacePoint point, Vector3 direction)
        {
            float cosine = Vector3.Dot(point.ShadingNormal, direction) / direction.Length();

            if (cosine < 0)
            {
                return(RgbColor.Black);
            }
            return(radiance * MathF.Pow(cosine, exponent) * normalizationFactor);
        }
        //нахождение высоты Z точки p0, лежащей на прямой которая паралельна оси X
        private static SurfacePoint CalcPX(SurfacePoint p1, SurfacePoint p2, SurfacePoint p0)
        {
            SurfacePoint ReturnPoint = new SurfacePoint(p0.PosX, p0.PosY, p0.PosZ);

            ReturnPoint.PosZ = p1.PosZ + (((p1.PosZ - p2.PosZ) / (p1.PosX - p2.PosX)) * (p0.PosX - p1.PosX));

            //TODO: учесть на будущее что точка 1 и 2 могут лежать не на одной паралльной линии оси Х
            ReturnPoint.PosY = p1.PosY;

            return(ReturnPoint);
        }
示例#22
0
    void UpdateTangents()
    {
        for (int i = 0; i < surfacePoints.Length; i++)
        {
            SurfacePoint surfacePointLeft  = surfacePoints[(i - 1 + surfacePoints.Length) % surfacePoints.Length];
            SurfacePoint surfacePointRight = surfacePoints[(i + 1) % surfacePoints.Length];
            SurfacePoint targetPoint       = surfacePoints[i];

            Vector3 tangent = surfacePointLeft.transform.position - surfacePointRight.transform.position;
            spriteShapeManager.UpdateTangentAt(i, tangent);
        }
    }
示例#23
0
 bool GetIsOnSolidGround(SurfacePoint surfacePoint)
 {
     if (surfacePoint.otherCollider.attachedRigidbody == null)
     {
         return(true);
     }
     if (surfacePoint.otherCollider.attachedRigidbody.isKinematic)
     {
         return(true);
     }
     return(false);
 }
示例#24
0
            public SurfaceSatelliteGeometry(
                Vector3d bodyCentredVesselPosition,
                SurfacePoint surfacePoint)
            {
                Vector3d surfaceToSatellite =
                    bodyCentredVesselPosition - surfacePoint.bodyCentredSurfacePosition;

                range            = surfaceToSatellite.magnitude;
                cosZenithalAngle =
                    Vector3d.Dot(surfaceToSatellite, surfacePoint.vertical) / range;
                absSinSwathAngle = 0;
            }
示例#25
0
            public static SunSurfaceGeometry FromSunDirection(
                SurfacePoint surfacePoint,
                Vector3d bodyCentredSunDirection)
            {
                double cosSolarZenithAngle = Vector3d.Dot(surfacePoint.vertical, bodyCentredSunDirection);

                return(new SunSurfaceGeometry
                {
                    cosSolarZenithAngle = cosSolarZenithAngle,
                    reflectedRay = -bodyCentredSunDirection + 2 * cosSolarZenithAngle * surfacePoint.vertical
                });
            }
    static void Main(string[] args)
    {
        string[] inputs;
        int      surfaceN = int.Parse(Console.ReadLine());    // the number of points used to draw the surface of Mars.

        SurfacePoint[] allPoints = new SurfacePoint[surfaceN];
        for (int i = 0; i < surfaceN; i++)
        {
            inputs = Console.ReadLine().Split(' ');
            int landX = int.Parse(inputs[0]);             // X coordinate of a surface point. (0 to 6999)
            int landY = int.Parse(inputs[1]);             // Y coordinate of a surface point. By linking all the points together in a sequential fashion, you form the surface of Mars.
            allPoints[i] = new SurfacePoint(landX, landY);
        }

        List <SurfacePoint> allPairsOfStraightPoints = new List <SurfacePoint>();

        for (int cur = 0; cur < (allPoints.Length - 1); cur++)
        {
            if (allPoints[cur].CheckThisSurface(allPoints[cur + 1]))
            {
                allPairsOfStraightPoints.Add(allPoints[cur]);
                allPairsOfStraightPoints.Add(allPoints[cur + 1]);
            }
        }

        MarsLander mLander = new MarsLander();
        bool       closestLandingSurfaceChecked = false;

        // game loop
        while (true)
        {
            inputs = Console.ReadLine().Split(' ');
            int X      = int.Parse(inputs[0]);
            int Y      = int.Parse(inputs[1]);
            int hSpeed = int.Parse(inputs[2]);           // the horizontal speed (in m/s), can be negative.
            int vSpeed = int.Parse(inputs[3]);           // the vertical speed (in m/s), can be negative.
            int fuel   = int.Parse(inputs[4]);           // the quantity of remaining fuel in liters.
            int rotate = int.Parse(inputs[5]);           // the rotation angle in degrees (-90 to 90).
            int power  = int.Parse(inputs[6]);           // the thrust power (0 to 4).

            mLander.MarsLanderNewData(X, Y, hSpeed, vSpeed, rotate, power);

            // Write an action using Console.WriteLine()
            // To debug: Console.Error.WriteLine("Debug messages...");
            if (!closestLandingSurfaceChecked)
            {
                mLander.CheckClosestSurfaceForLander(allPairsOfStraightPoints);
                closestLandingSurfaceChecked = true;
            }

            Console.WriteLine(mLander.LanderNextMove());
        }
    }
        // Frank-Wolfe convex optimization algorithm. Returns closest point to a simplex in a signed distance function.
        private static void FrankWolfe <T>(ref T function,
                                           int simplexStart,
                                           int simplexSize,
                                           NativeArray <float4> positions,
                                           NativeArray <float4> radii,
                                           NativeArray <int> simplices,
                                           ref float4 convexPoint,
                                           ref float convexThickness,
                                           ref float4 convexBary,
                                           ref SurfacePoint pointInFunction,
                                           int maxIterations,
                                           float tolerance) where T : struct, IDistanceFunction
        {
            for (int i = 0; i < maxIterations; ++i)
            {
                // sample target function:
                function.Evaluate(convexPoint, ref pointInFunction);

                // find descent direction:
                int   descent = 0;
                float gap     = float.MinValue;
                for (int j = 0; j < simplexSize; ++j)
                {
                    int    particle  = simplices[simplexStart + j];
                    float4 candidate = positions[particle] - convexPoint;

                    // here, we adjust the candidate by projecting it to the engrosed simplex's surface:
                    candidate -= pointInFunction.normal * (radii[particle].x - convexThickness);

                    float corr = math.dot(-pointInFunction.normal, candidate);
                    if (corr > gap)
                    {
                        descent = j;
                        gap     = corr;
                    }
                }

                // if the duality gap is below tolerance threshold, stop iterating.
                if (gap < tolerance)
                {
                    break;
                }

                // update the barycentric coords using 2/(i+2) as  the step factor
                float step = 0.3f * 2.0f / (i + 2);
                convexBary          *= 1 - step;
                convexBary[descent] += step;

                // get cartesian coordinates of current solution:
                GetCartesianConvexAttrib(simplexStart, simplexSize, simplices, positions, radii, convexBary, out convexPoint, out convexThickness);
            }
        }
示例#28
0
        private void InitPoint(ref SurfacePoint point, double x, double y, double?z)
        {
            point.X = x;
            point.Y = y;
            point.Z = z;

            if (z != null)
            {
                point.XLeftProj  = GetXProj(x, z.Value, true);
                point.XRightProj = GetXProj(x, z.Value, false);
                point.YProj      = GetYProj(y, z.Value);
            }
        }
示例#29
0
 void DetermineWallPoints(List <ContactPoint> contactPoints, SurfacePoint surfacePoint, out List <ContactPoint> wallPoints)
 {
     wallPoints = new List <ContactPoint>();
     for (int i = 0; i < contactPoints.Count; i++)
     {
         ContactPoint point      = contactPoints[i];
         float        pointAngle = Vector3.Angle(point.normal, rb.transform.up);
         if (pointAngle > moveSlopeAngleLimit)
         {
             wallPoints.Add(point);
         }
     }
 }
示例#30
0
 protected override RgbColor OnHit(Ray ray, SurfacePoint hit, float pdfFromAncestor, RgbColor throughput,
                                   int depth, float toAncestorJacobian)
 {
     // Add the next vertex
     lastId = cache.AddVertex(new PathVertex {
         Point              = hit,
         PdfFromAncestor    = pdfFromAncestor,
         PdfReverseAncestor = nextReversePdf,
         Weight             = throughput,
         AncestorId         = lastId,
         Depth              = (byte)depth
     }, pathIdx);
     return(RgbColor.Black);
 }
示例#31
0
        Vector SampleEmitters(Vector rayDirection, SurfacePoint surfacePoint, Sampler random)
        {
            Vector radiance;

            // single emitter sample, ideal diffuse BRDF:
            // reflected = (emitivity * solidangle) * (emitterscount) *
            // (cos(emitdirection) / pi * reflectivity)
            // -- SurfacePoint does the first and last parts (in separate methods)

            // get position on an emitter
            Vector emitterPosition;
            Triangle emitter;
            scene.GetEmitter(random, out emitterPosition, out emitter);

            // check an emitter was found
            if (null != emitter)
            {
                // make direction to emit point
                Vector emitDirection = (emitterPosition - surfacePoint.Position).Unitize();

                // send shadow ray
                Triangle hitObject;
                Vector hitPosition;
                scene.GetIntersection(surfacePoint.Position, emitDirection, surfacePoint.Item, out hitObject, out hitPosition);
                StatsCounter.RayTraced();

                // if unshadowed, get inward emission value
                Vector emissionIn = null;
                if ((null == hitObject) || (emitter == hitObject))
                    emissionIn = new SurfacePoint(emitter, emitterPosition).GetEmission(surfacePoint.Position, -emitDirection, true);
                else
                    emissionIn = new Vector();

                // get amount reflected by surface
                radiance = surfacePoint.GetReflection(emitDirection, emissionIn * scene.GetEmittersCount(), -rayDirection);
            }
            else
                radiance = new Vector();

            return radiance;
        }
示例#32
0
        public Vector GetRadiance(Vector rayOrigin, Vector rayDirection, Sampler random, Triangle lastHit)
        {
            // intersect ray with scene
            Triangle pHitObject;
            Vector hitPosition;
            scene.GetIntersection(rayOrigin, rayDirection, lastHit, out pHitObject, out hitPosition);

            Vector radiance;
            if (null != pHitObject)
            {
                // make surface point of intersection
                SurfacePoint surfacePoint = new SurfacePoint(pHitObject, hitPosition);

                // local emission only for first-hit
                if (lastHit != null)
                    radiance = Vector.ZERO;
                else
                    radiance = surfacePoint.GetEmission(rayOrigin, -rayDirection, false);

                // add emitter sample
                radiance = radiance + SampleEmitters(rayDirection, surfacePoint, random);

                // add recursive reflection
                //
                // single hemisphere sample, ideal diffuse BRDF:
                // reflected = (inradiance * pi) * (cos(in) / pi * color) * reflectance
                // -- reflectance magnitude is 'scaled' by the russian roulette, cos is
                // importance sampled (both done by SurfacePoint), and the pi and 1/pi
                // cancel out
                Vector nextDirection;
                Vector color;
                // check surface bounces ray, recurse
                if (surfacePoint.GetNextDirection(random, -rayDirection, out nextDirection, out color))
                    radiance = radiance + (color * GetRadiance(surfacePoint.Position, nextDirection, random, surfacePoint.Item));
            }
            else // no hit: default/background scene emission
                radiance = scene.GetDefaultEmission(-rayDirection);

            return radiance;
        }
        private void InitPoint(ref SurfacePoint point, double x, double y, double? z)
        {
            point.X = x;
            point.Y = y;
            point.Z = z;

            if (z != null)
            {
                point.XLeftProj = GetXProj(x, z.Value, true);
                point.XRightProj = GetXProj(x, z.Value, false);
                point.YProj = GetYProj(y, z.Value);
            }
        }
示例#34
0
        /// <summary>
        /// Инициализация матрицы
        /// </summary>
        /// <param name="surfacePoint">Ключевая(начальная) точка массива</param>
        /// <param name="countpointX">Количество точек/рядов сканирования по оси X</param>
        /// <param name="countpointY">Количество точек/строк сканирования по оси Y</param>
        /// <param name="stepx">Интервал между точками</param>
        /// <param name="stepy">Интервал между точками</param>
        public static void Init(SurfacePoint surfacePoint, int countpointX, int countpointY, float stepx, float stepy)
        {
            
            _primaryPosition = surfacePoint == null ? new SurfacePoint() : new SurfacePoint(surfacePoint);

            _countPointX = countpointX;
            _countPointY = countpointY;
            _stepX = stepx;
            _stepY = stepy;

            SpeedMove = 200;
            SpeedScan = 50;

            Matrix = new SurfacePoint[_countPointX, _countPointY];

            // заполним пустыми данными
            for (int y = 0; y < _countPointY; y++)
            {
                for (int x = 0; x < _countPointX; x++)
                {
                    SurfacePoint tmPoint = new SurfacePoint();

                    if (surfacePoint != null)
                    {
                        tmPoint.PosX = (x * stepx) + surfacePoint.PosX;
                        tmPoint.PosY = (y * stepy) + surfacePoint.PosY;
                        tmPoint.PosZ = surfacePoint.PosZ;
                    }
                    tmPoint.PosZ = 0;

                    Matrix[x, y] = new SurfacePoint(tmPoint);
                }
            }

            NotInit = false;
        }
        private void ButtonImport_OnClick(object sender, RoutedEventArgs e)
        {
            List<int> SelectedGroups = new List<int>();
            for (int i = 0; i < AvailableGroups.Count; i++)
            {
                foreach (var selectedItem in ListGroups.SelectedItems)
                    if ((string)selectedItem == AvailableGroups[i])
                        SelectedGroups.Add(i);
            }

            using (Stream SessionStream = File.OpenRead(SessionPath))
            {
                XPathDocument Doc = new XPathDocument(SessionStream);
                XPathNavigator Reader = Doc.CreateNavigator();
                Reader.MoveToRoot();

                int iGroup = 0;
                foreach (XPathNavigator groupNav in Reader.Select("//PointGroups/Group"))
                {
                    if (SelectedGroups.Contains(iGroup))
                    {
                        PointGroup NewGroup = new PointGroup
                        {
                            Name = XMLHelper.LoadAttribute(groupNav, "Name", "Group " + (MainWindow.Options.Membrane.PointGroups.Count + 1)),
                            Size = XMLHelper.LoadAttribute(groupNav, "Size", 10),
                            Color = ColorHelper.LoadAttribute(groupNav, "Color", ColorHelper.SpectrumColor(MainWindow.Options.Membrane.PointGroups.Count, 0.3f))
                        };
                        NewGroup.PointCloud.GLContext = MainWindow.Options.Viewport.GetControl();

                        foreach (XPathNavigator pointNav in groupNav.SelectChildren("Point", ""))
                        {
                            int TriangleID = XMLHelper.LoadAttribute(pointNav, "ID", 0);
                            SurfacePoint NewPoint = new SurfacePoint(OpenGLHelper.LoadAttribute(pointNav, "Position", new Vector3(0)),
                                                                     MainWindow.Options.Membrane.SurfaceMesh.Triangles[TriangleID < MainWindow.Options.Membrane.SurfaceMesh.Triangles.Count ? TriangleID : 0],
                                                                     OpenGLHelper.LoadAttribute(pointNav, "Barycentric", new Vector3(0)),
                                                                     XMLHelper.LoadAttribute(pointNav, "Offset", 0f),
                                                                     OpenGLHelper.LoadAttribute(pointNav, "Orientation", new Vector3(0)).X);
                            NewGroup.Points.Add(NewPoint);
                        }

                        MainWindow.Options.Membrane.PointGroups.Add(NewGroup);
                        NewGroup.IsVisible = XMLHelper.LoadAttribute(groupNav, "IsVisible", true);
                    }

                    iGroup++;
                }
            }

            if (SelectedGroups.Count > 0)
                MainWindow.Options.Viewport.Redraw();

            Close();
        }
示例#36
0
        /// <summary>
        /// Вычисление высоты Z по переданным 2-м координатам
        /// </summary>
        public static float GetPosZ(float _x, float _y)
        {
            //точка которую нужно отобразить
            SurfacePoint pResult = new SurfacePoint(_x, _y, 0);



            //поиск ближайшей точки из матрицы
            int indexXmin = 0;
            int indexYmin = 0;
            for (int x = 0; x < Matrix.GetLength(0) - 1; x++)
            {
                for (int y = 0; y < Matrix.GetLength(1) - 1; y++)
                {
                    if (_x > Matrix[x, 0].PosX && _x < Matrix[x + 1, 0].PosX && Matrix[0, y].PosY < _y && Matrix[0, y + 1].PosY > _y)
                    {
                        indexXmin = x;
                        indexYmin = y;
                    }
                }
            }


            SurfacePoint p1 = new SurfacePoint(Matrix[indexXmin, indexYmin].PosX, Matrix[indexXmin, indexYmin].PosY, Matrix[indexXmin, indexYmin].PosZ);
            SurfacePoint p3 = new SurfacePoint(Matrix[indexXmin, indexYmin + 1].PosX, Matrix[indexXmin, indexYmin + 1].PosY, Matrix[indexXmin, indexYmin + 1].PosZ);
            SurfacePoint p2 = new SurfacePoint(Matrix[indexXmin + 1, indexYmin].PosX, Matrix[indexXmin + 1, indexYmin].PosY, Matrix[indexXmin + 1, indexYmin].PosZ);
            SurfacePoint p4 = new SurfacePoint(Matrix[indexXmin + 1, indexYmin + 1].PosX, Matrix[indexXmin + 1, indexYmin + 1].PosY, Matrix[indexXmin + 1, indexYmin + 1].PosZ);

            SurfacePoint p12 = CalcPX(p1, p2, pResult);
            SurfacePoint p34 = CalcPX(p3, p4, pResult);
            SurfacePoint p1234 = CalcPY(p12, p34, pResult);


            return p1234.PosZ;
            //return 0;
        }
示例#37
0
 /// <summary>
 /// Клонирование данных из существующей точки
 /// </summary>
 /// <param name="_point"></param>
 public SurfacePoint(SurfacePoint _point)
 {
     PosX = _point.PosX;
     PosY = _point.PosY;
     PosZ = _point.PosZ;
     //deltaZ = _point.deltaZ;
 }
示例#38
0
        //нахождение высоты Z точки p0, лежащей на прямой между точками p3 p4  (прямая паралельна оси Y)
        private static SurfacePoint CalcPY(SurfacePoint p1, SurfacePoint p2, SurfacePoint p0)
        {
            SurfacePoint ReturnPoint = new SurfacePoint(p0.PosX, p0.PosY, p0.PosZ);

            ReturnPoint.PosZ = p1.PosZ + (((p1.PosZ - p2.PosZ) / (p1.PosY - p2.PosY)) * (p0.PosY - p1.PosY));

            return ReturnPoint;
        }
示例#39
0
        //нахождение высоты Z точки p0, лежащей на прямой которая паралельна оси X
        private static SurfacePoint CalcPX(SurfacePoint p1, SurfacePoint p2, SurfacePoint p0)
        {
            SurfacePoint ReturnPoint = new SurfacePoint(p0.PosX, p0.PosY, p0.PosZ);

            ReturnPoint.PosZ = p1.PosZ + (((p1.PosZ - p2.PosZ) / (p1.PosX - p2.PosX)) * (p0.PosX - p1.PosX));

            //TODO: учесть на будущее что точка 1 и 2 могут лежать не на одной паралльной линии оси Х
            ReturnPoint.PosY = p1.PosY;

            return ReturnPoint;
        }
示例#40
0
        /*
         *    Корректировка высоты по оси Z, у точки №5, зная высоту по Z у точек 1,2,3,4 
         * 
         *  /\ ось Y
         *  |
         *  |    (точка №1) -------------*--------------- (точка №2)
         *  |                            |
         *  |                            |
         *  |                            |
         *  |                       (точка №5)
         *  |                            |
         *  |                            |
         *  |    (точка №3) -------------*--------------- (точка №4)
         *  |
         *  |
         *  *----------------------------------------------------------------> ось X 
         *  Корректировка выполняется следующим образом:
         *  1) зная координату X у точки 5, и координаты точек 1 и 2, вычисляем высоту Z в точке которая находится на линии точек 1,2 и перпендикулярно 5-й точке (получает точку №12)
         *  2) Тоже самое вычисляется для точки на линии точек 3,4 (получает точку №34)
         *  3) Зная координаты точек №12, №34 и значение по оси Y у точки 5, вычисляем высоту по оси Z 
         */

        /// <summary>
        /// Функция корректирует высоту по оси Z
        /// </summary>
        /// <param name="p1">первая точка первой линии X</param>
        /// <param name="p2">вторая точка первой линии X</param>
        /// <param name="p3">первая точка второй линии X</param>
        /// <param name="p4">вторая точка второй линии X</param>
        /// <param name="p5">точка у которой нужно скорректировать высоту</param>
        /// <returns></returns>
        private static SurfacePoint GetZ(SurfacePoint p1, SurfacePoint p2, SurfacePoint p3, SurfacePoint p4, SurfacePoint p5)
        {
            SurfacePoint p12 = CalcPX(p1, p2, p5);
            SurfacePoint p34 = CalcPX(p3, p4, p5);

            SurfacePoint p1234 = CalcPY(p12, p34, p5);

            return p1234;
        }