/// <summary> /// Transform the point from the camera's local coordinate system to the camera's /// view coordinate system. /// </summary> /// <param name="point"> /// The point in the camera's local coordinate system to be transformed. /// </param> /// <returns>The point in the camera's view coordinate system.</returns> public virtual PointFx LocalToView(PointFx point) { return(MatrixExtensions.InverseTransform(viewMatrix, point)); }
/// <summary> /// Transform the size from the camera's local coordinate system to the camera's /// view coordinate system. /// </summary> /// <param name="size"> /// The size in the camera's local coordinate system to be transformed. /// </param> /// <returns>The size in the camera's view coordinate system.</returns> public virtual SizeFx LocalToView(SizeFx size) { return(MatrixExtensions.InverseTransform(viewMatrix, size)); }
private Matrix CalculateScaleMatrix() { return(MatrixExtensions.CreateScaleTranslation(scaleDX * offsetX + suboffsetX, scaleDY * offsetY + suboffsetY, scaleXY, scaleXY)); }
/// <summary> /// Transform the rectangle from the camera's view coordinate system to the /// camera's local coordinate system. /// </summary> /// <param name="rectangle"> /// The rectangle in the camera's view coordinate system to be transformed. /// </param> /// <returns>The rectangle in the camera's local coordinate system.</returns> public virtual RectangleFx ViewToLocal(RectangleFx rectangle) { return(MatrixExtensions.Transform(viewMatrix, rectangle)); }
private void updateVertexBuffer() { const float start_angle = 0; const float step = MathHelper.Pi / MAXRES; float dir = Math.Sign(Angle); int amountPoints = (int)Math.Ceiling(Math.Abs(Angle) / step); Matrix3 transformationMatrix = DrawInfo.Matrix; MatrixExtensions.ScaleFromLeft(ref transformationMatrix, DrawSize); Vector2 current = origin + pointOnCircle(start_angle) * 0.5f; Color4 currentColour = colourAt(current); current = Vector2Extensions.Transform(current, transformationMatrix); Vector2 screenOrigin = Vector2Extensions.Transform(origin, transformationMatrix); Color4 originColour = colourAt(origin); // First center point Shared.HalfCircleBatch.Add(new TexturedVertex2D { Position = Vector2.Lerp(current, screenOrigin, InnerRadius), TexturePosition = new Vector2(0, 0), Colour = originColour }); // First outer point. Shared.HalfCircleBatch.Add(new TexturedVertex2D { Position = new Vector2(current.X, current.Y), TexturePosition = new Vector2(0, 1 - 1 / Texture.Height), Colour = currentColour }); for (int i = 1; i <= amountPoints; i++) { // Clamps the angle so we don't overshoot. // dir is used so negative angles result in negative angularOffset. float angularOffset = dir * Math.Min(i * step, dir * Angle); float normalisedStartAngle = amountPoints > 1 ? (1 - 1 / Texture.Width) * ((float)(i - 1) / amountPoints * Angle / MathHelper.TwoPi + (dir > 0 ? 0 : 1)) : 0; float normalisedEndAngle = amountPoints > 1 ? (1 - 1 / Texture.Width) * ((float)i / amountPoints * Angle / MathHelper.TwoPi + (dir > 0 ? 0 : 1)) : 0; // Update `current` current = origin + pointOnCircle(start_angle + angularOffset) * 0.5f; currentColour = colourAt(current); current = Vector2Extensions.Transform(current, transformationMatrix); // current center point Shared.HalfCircleBatch.Add(new TexturedVertex2D { Position = Vector2.Lerp(current, screenOrigin, InnerRadius), TexturePosition = new Vector2((normalisedStartAngle + normalisedEndAngle) / 2, 0), Colour = originColour }); // current outer point Shared.HalfCircleBatch.Add(new TexturedVertex2D { Position = new Vector2(current.X, current.Y), TexturePosition = new Vector2(normalisedEndAngle, 1 - 1 / Texture.Height), Colour = currentColour }); } }
private void updateVertexBuffer() { const float start_angle = 0; const float step = MathHelper.Pi / MAX_RES; float dir = Math.Sign(angle); int amountPoints = (int)Math.Ceiling(Math.Abs(angle) / step); Matrix3 transformationMatrix = DrawInfo.Matrix; MatrixExtensions.ScaleFromLeft(ref transformationMatrix, drawSize); Vector2 current = origin + pointOnCircle(start_angle) * 0.5f; Color4 currentColour = colourAt(current); current = Vector2Extensions.Transform(current, transformationMatrix); Vector2 screenOrigin = Vector2Extensions.Transform(origin, transformationMatrix); Color4 originColour = colourAt(origin); // Offset by 0.5 pixels inwards to ensure we never sample texels outside the bounds RectangleF texRect = texture.GetTextureRect(new RectangleF(0.5f, 0.5f, texture.Width - 1, texture.Height - 1)); float prevOffset = dir >= 0 ? 0 : 1; // First center point halfCircleBatch.Add(new TexturedVertex2D { Position = Vector2.Lerp(current, screenOrigin, innerRadius), TexturePosition = new Vector2(dir >= 0 ? texRect.Left : texRect.Right, texRect.Top), Colour = originColour }); // First outer point. halfCircleBatch.Add(new TexturedVertex2D { Position = new Vector2(current.X, current.Y), TexturePosition = new Vector2(dir >= 0 ? texRect.Left : texRect.Right, texRect.Bottom), Colour = currentColour }); for (int i = 1; i <= amountPoints; i++) { // Clamps the angle so we don't overshoot. // dir is used so negative angles result in negative angularOffset. float angularOffset = dir * Math.Min(i * step, dir * angle); float normalisedOffset = angularOffset / MathHelper.TwoPi; if (dir < 0) { normalisedOffset += 1.0f; } // Update `current` current = origin + pointOnCircle(start_angle + angularOffset) * 0.5f; currentColour = colourAt(current); current = Vector2Extensions.Transform(current, transformationMatrix); // current center point halfCircleBatch.Add(new TexturedVertex2D { Position = Vector2.Lerp(current, screenOrigin, innerRadius), TexturePosition = new Vector2(texRect.Left + (normalisedOffset + prevOffset) / 2 * texRect.Width, texRect.Top), Colour = originColour }); // current outer point halfCircleBatch.Add(new TexturedVertex2D { Position = new Vector2(current.X, current.Y), TexturePosition = new Vector2(texRect.Left + normalisedOffset * texRect.Width, texRect.Bottom), Colour = currentColour }); prevOffset = normalisedOffset; } }
public void ReadFromFile(MemoryStream stream, bool isBigEndian) { //all the same values? for (int i = 0; i != numBones.Length; i++) { numBones[i] = stream.ReadInt32(isBigEndian); } numBlendIDs = stream.ReadInt32(isBigEndian); numLods = stream.ReadInt32(isBigEndian); //unknown lod data; unkLodData = new int[numLods]; for (int i = 0; i != unkLodData.Length; i++) { unkLodData[i] = stream.ReadInt32(isBigEndian); } idType = stream.ReadByte8(); //Bone Names and LOD data. boneNames = new HashName[numBones[0]]; for (int i = 0; i != boneNames.Length; i++) { boneNames[i] = new HashName(stream, isBigEndian); } //Matrices; jointTransforms = new Matrix[numBones[1]]; worldTransforms = new Matrix[numBones[3]]; for (int i = 0; i != jointTransforms.Length; i++) { jointTransforms[i] = MatrixExtensions.ReadFromFile(stream, isBigEndian); } numUnkCount2 = stream.ReadInt32(isBigEndian); boneLODUsage = stream.ReadBytes(numUnkCount2); for (int i = 0; i != worldTransforms.Length; i++) { worldTransforms[i] = MatrixExtensions.ReadFromFile(stream, isBigEndian); } //BoneMappings. mappingForBlendingInfos = new MappingForBlendingInfo[numLods]; for (int i = 0; i != mappingForBlendingInfos.Length; i++) { mappingForBlendingInfos[i].Bounds = new BoundingBox[numBones[2]]; for (int x = 0; x != mappingForBlendingInfos[i].Bounds.Length; x++) { mappingForBlendingInfos[i].Bounds[x] = BoundingBoxExtenders.ReadFromFile(stream, isBigEndian); } if (stream.ReadByte() != 0) { throw new System.Exception("oops"); } mappingForBlendingInfos[i].RefToUsageArray = stream.ReadBytes(numBones[2]); mappingForBlendingInfos[i].UsageArray = stream.ReadBytes(unkLodData[i]); } }
private float GetUserSimilarity(int user, int newUser) { IList <float> rowDiff = MatrixExtensions.RowDifference(user_factors, user, user_factors, newUser); return((float)rowDiff.EuclideanNorm()); }
private void updateVertexBuffer() { const float start_angle = 0; float dir = Math.Sign(angle); float radius = Math.Max(drawSize.X, drawSize.Y); // The amount of points are selected such that discrete curvature is smaller than the provided tolerance. // The exact angle required to meet the tolerance is: 2 * Math.Acos(1 - TOLERANCE / r) // The special case is for extremely small circles where the radius is smaller than the tolerance. int amountPoints = 2 * radius <= arc_tolerance ? 2 : Math.Max(2, (int)Math.Ceiling(Math.PI / Math.Acos(1 - arc_tolerance / radius))); if (halfCircleBatch == null || halfCircleBatch.Size < amountPoints * 2) { halfCircleBatch?.Dispose(); // Amount of points is multiplied by 2 to account for each part requiring two vertices. halfCircleBatch = new LinearBatch <TexturedVertex2D>(amountPoints * 2, 1, PrimitiveType.TriangleStrip); } Matrix3 transformationMatrix = DrawInfo.Matrix; MatrixExtensions.ScaleFromLeft(ref transformationMatrix, drawSize); Vector2 current = origin + pointOnCircle(start_angle) * 0.5f; Color4 currentColour = colourAt(current); current = Vector2Extensions.Transform(current, transformationMatrix); Vector2 screenOrigin = Vector2Extensions.Transform(origin, transformationMatrix); Color4 originColour = colourAt(origin); // Offset by 0.5 pixels inwards to ensure we never sample texels outside the bounds RectangleF texRect = texture.GetTextureRect(new RectangleF(0.5f, 0.5f, texture.Width - 1, texture.Height - 1)); float prevOffset = dir >= 0 ? 0 : 1; // First center point halfCircleBatch.Add(new TexturedVertex2D { Position = Vector2.Lerp(current, screenOrigin, innerRadius), TexturePosition = new Vector2(dir >= 0 ? texRect.Left : texRect.Right, texRect.Top), Colour = originColour }); // First outer point. halfCircleBatch.Add(new TexturedVertex2D { Position = new Vector2(current.X, current.Y), TexturePosition = new Vector2(dir >= 0 ? texRect.Left : texRect.Right, texRect.Bottom), Colour = currentColour }); for (int i = 1; i < amountPoints; i++) { float fract = (float)i / (amountPoints - 1); // Clamps the angle so we don't overshoot. // dir is used so negative angles result in negative angularOffset. float angularOffset = Math.Min(fract * two_pi, dir * angle); float normalisedOffset = angularOffset / two_pi; if (dir < 0) { normalisedOffset += 1.0f; } // Update `current` current = origin + pointOnCircle(start_angle + angularOffset) * 0.5f; currentColour = colourAt(current); current = Vector2Extensions.Transform(current, transformationMatrix); // current center point halfCircleBatch.Add(new TexturedVertex2D { Position = Vector2.Lerp(current, screenOrigin, innerRadius), TexturePosition = new Vector2(texRect.Left + (normalisedOffset + prevOffset) / 2 * texRect.Width, texRect.Top), Colour = originColour }); // current outer point halfCircleBatch.Add(new TexturedVertex2D { Position = new Vector2(current.X, current.Y), TexturePosition = new Vector2(texRect.Left + normalisedOffset * texRect.Width, texRect.Bottom), Colour = currentColour }); prevOffset = normalisedOffset; } }
/// <summary> /// Applies a transformation to the current DrawInfo. /// </summary> /// <param name="target">The DrawInfo instance to be filled with the result.</param> /// <param name="translation">The amount by which to translate the current position.</param> /// <param name="scale">The amount by which to scale.</param> /// <param name="rotation">The amount by which to rotate.</param> /// <param name="origin">The center of rotation and scale.</param> /// <param name="colour">An optional color to be applied multiplicatively.</param> /// <param name="viewport">An optional new viewport size.</param> public void ApplyTransform(ref DrawInfo target, Vector2 translation, Vector2 scale, float rotation, Vector2 origin, Color4?colour = null, BlendingInfo?blending = null) { target.Matrix = Matrix; target.MatrixInverse = MatrixInverse; if (translation != Vector2.Zero) { MatrixExtensions.Translate(ref target.Matrix, translation); } if (rotation != 0) { MatrixExtensions.Rotate(ref target.Matrix, rotation); } if (scale != Vector2.One) { MatrixExtensions.Scale(ref target.Matrix, scale); } if (origin != Vector2.Zero) { MatrixExtensions.Translate(ref target.Matrix, -origin); MatrixExtensions.Translate(ref target.MatrixInverse, origin); } if (scale != Vector2.One) { Vector2 inverseScale = new Vector2(1.0f / scale.X, 1.0f / scale.Y); MatrixExtensions.Scale(ref target.MatrixInverse, inverseScale); } if (rotation != 0) { MatrixExtensions.Rotate(ref target.MatrixInverse, -rotation); } if (translation != Vector2.Zero) { MatrixExtensions.Translate(ref target.MatrixInverse, -translation); } target.Colour = Colour; if (colour != null) { target.Colour.R *= colour.Value.R; target.Colour.G *= colour.Value.G; target.Colour.B *= colour.Value.B; target.Colour.A *= colour.Value.A; } if (blending == null) { Blending.Copy(ref target.Blending); } else { blending.Value.Copy(ref target.Blending); } }
protected override void UpdateFactors(int user_id, int item_id, int other_item_id, bool update_u, bool update_i, bool update_j) { // used by WrapRec-based logic string userIdOrg = UsersMap.ToOriginalID(user_id); string itemIdOrg = ItemsMap.ToOriginalID(item_id); List <Tuple <int, float> > features = new List <Tuple <int, float> >(); if (Split.SetupParameters.ContainsKey("feedbackAttributes")) { features = Split.Container.FeedbacksDic[userIdOrg, itemIdOrg].GetAllAttributes().Select(a => a.Translation).NormalizeSumToOne(Normalize).ToList(); } double item_bias_diff = item_bias[item_id] - item_bias[other_item_id]; double y_uij = item_bias_diff + MatrixExtensions.RowScalarProductWithRowDifference( user_factors, user_id, item_factors, item_id, item_factors, other_item_id); foreach (var feat in features) { y_uij += feat.Item2 * MatrixExtensions.RowScalarProductWithRowDifference( feature_factors, feat.Item1, item_factors, item_id, item_factors, other_item_id); } double exp = Math.Exp(y_uij); double sigmoid = 1 / (1 + exp); // adjust bias terms if (update_i) { // TODO: check why -Bias double update = sigmoid - BiasReg * item_bias[item_id]; item_bias[item_id] += (float)(learn_rate * update); } if (update_j) { double update = -sigmoid - BiasReg * item_bias[other_item_id]; item_bias[other_item_id] += (float)(learn_rate * update); } // adjust factors for (int f = 0; f < num_factors; f++) { float v_uf = user_factors[user_id, f]; float v_if = item_factors[item_id, f]; float v_jf = item_factors[other_item_id, f]; if (update_u) { double update = (v_if - v_jf) * sigmoid - reg_u * v_uf; user_factors[user_id, f] = (float)(v_uf + learn_rate * update); } // update features latent factors and make a sum term to use later for updating item factors // sum = Sum_{l=1}{num_features} c_l * v_{c_l,f} float sum = 0f; foreach (var feat in features) { float v_zf = feature_factors[feat.Item1, f]; float x_z = feat.Item2; sum += x_z * v_zf; double update = x_z * (v_if - v_jf) * sigmoid - reg_c * v_zf; feature_factors[feat.Item1, f] = (float)(v_zf + learn_rate * update); } if (update_i) { double update = (v_uf + sum) * sigmoid - reg_i * v_if; item_factors[item_id, f] = (float)(v_if + learn_rate * update); } if (update_j) { double update = (-v_uf - sum) * sigmoid - reg_j * v_jf; item_factors[other_item_id, f] = (float)(v_jf + learn_rate * update); } } }
private Matrix CalculateScaleMatrix() { return(MatrixExtensions.CreateScaleTranslation(offsetX, offsetY, scaleXY, scaleXY)); }
/// void Iterate(IList <int> rating_indices, bool update_user, bool update_item) { //SetupLoss(); foreach (int index in rating_indices) { int u = ratings.Users[index]; int i = ratings.Items[index]; int correct_label = value_to_label_id[ratings[index]]; float user_reg_weight = FrequencyRegularization ? (float)(RegU / Math.Sqrt(ratings.CountByUser[u])) : RegU; float item_reg_weight = FrequencyRegularization ? (float)(RegI / Math.Sqrt(ratings.CountByItem[i])) : RegI; for (int l = 0; l < label_id_to_value.Count - 1; l++) { double dot_product = user_biases[l, u] + item_biases[l, i] + MatrixExtensions.RowScalarProduct(user_factors[l], u, item_factors[l], i); double label_percentage = 1 / (1 + Math.Exp(-dot_product)); float gradient_common = (float)-label_percentage; if (l == correct_label) { gradient_common += 1; } // adjust biases if (update_user) { user_biases.Inc(l, u, BiasLearnRate * LearnRate * (gradient_common - BiasReg * user_reg_weight * user_biases[l, u])); } if (update_item) { item_biases.Inc(l, i, BiasLearnRate * LearnRate * (gradient_common - BiasReg * item_reg_weight * item_biases[l, i])); } // adjust latent factors for (int f = 0; f < NumFactors; f++) { double u_f = user_factors[l][u, f]; double i_f = item_factors[l][i, f]; if (update_user) { double delta_u = gradient_common * i_f - user_reg_weight * u_f; user_factors[l].Inc(u, f, LearnRate * delta_u); } if (update_item) { double delta_i = gradient_common * u_f - item_reg_weight * i_f; item_factors[l].Inc(i, f, LearnRate * delta_i); } } } } }
/// <summary> /// Transform the rectangle from the camera's local coordinate system to the camera's /// view coordinate system. /// </summary> /// <param name="rectangle"> /// The rectangle in the camera's local coordinate system to be transformed. /// </param> /// <returns>The rectangle in the camera's view coordinate system.</returns> public virtual RectangleFx LocalToView(RectangleFx rectangle) { return(MatrixExtensions.InverseTransform(viewMatrix, rectangle)); }
public void ReadFromFile(MemoryStream stream, bool isBigEndian) { transform = MatrixExtensions.ReadFromFile(stream, isBigEndian); bounds = BoundingBoxExtenders.ReadFromFile(stream, isBigEndian); isValid = stream.ReadByte8(); }
/// public override void LearnAttributeToFactorMapping() { // create attribute-to-factor weight matrix this.attribute_to_factor = new Matrix <float>(NumUserAttributes + 1, num_factors); Console.Error.WriteLine("num_user_attributes=" + NumUserAttributes); // store the results of the different runs in the following array var old_attribute_to_factor = new Matrix <float> [num_init_mapping]; Console.Error.WriteLine("Will use {0} examples ...", num_iter_mapping * MaxUserID); var old_rmse_per_factor = new double[num_init_mapping][]; for (int h = 0; h < num_init_mapping; h++) { MatrixExtensions.InitNormal(attribute_to_factor, InitMean, InitStdDev); Console.Error.WriteLine("----"); for (int i = 0; i < num_iter_mapping * MaxUserID; i++) { if (i % 5000 == 0) { ComputeMappingFit(); } IterateMapping(); } ComputeMappingFit(); old_attribute_to_factor[h] = new Matrix <float>(attribute_to_factor); old_rmse_per_factor[h] = ComputeMappingFit(); } var min_rmse_per_factor = new double[num_factors]; for (int i = 0; i < num_factors; i++) { min_rmse_per_factor[i] = double.MaxValue; } var best_factor_init = new int[num_factors]; // find best factor mappings: for (int i = 0; i < num_init_mapping; i++) { for (int j = 0; j < num_factors; j++) { if (old_rmse_per_factor[i][j] < min_rmse_per_factor[j]) { min_rmse_per_factor[j] = old_rmse_per_factor[i][j]; best_factor_init[j] = i; } } } // set the best weight combinations for each factor mapping for (int i = 0; i < num_factors; i++) { Console.Error.WriteLine("Factor {0}, pick {1}", i, best_factor_init[i]); attribute_to_factor.SetColumn(i, old_attribute_to_factor[best_factor_init[i]].GetColumn(i) ); } Console.Error.WriteLine("----"); ComputeMappingFit(); }
public void Correct() { List <LinearMeasurement2D> measurements = new List <LinearMeasurement2D>(); Map model = new Map(3); double[][] identity = Accord.Math.Matrix.JaggedIdentity(3); double PD = vehicle.PD; Gaussian comp1 = new Gaussian(new double[3] { 3, 5, 0 }, identity, 0.8); Gaussian comp2 = new Gaussian(new double[3] { 7, 5, 0 }, (4.0).Multiply(identity), 1.4); measurements.Add(new LinearMeasurement2D(2, 3)); measurements.Add(new LinearMeasurement2D(5, 3)); model.Add(comp1); model.Add(comp2); // in Linear2D, the measurement covariance in measurement space // is the same as in the map space double[][] mcov = MatrixExtensions.Zero(3); mcov[0][0] = vehicle.MeasurementCovariance[0][0]; mcov[0][1] = vehicle.MeasurementCovariance[0][1]; mcov[1][0] = vehicle.MeasurementCovariance[1][0]; mcov[1][1] = vehicle.MeasurementCovariance[1][1]; Gaussian gz1 = new Gaussian(new double[3] { 1 + 2, 2 + 3, 0 }, mcov, 1.0); Gaussian gz2 = new Gaussian(new double[3] { 1 + 5, 2 + 3, 0 }, mcov, 1.0); Map corrected = navigator.CorrectConditional(measurements, vehicle, model); List <Gaussian> clist = corrected.ToList(); List <Gaussian> explist = new List <Gaussian>(); Gaussian z11 = Gaussian.Multiply(gz1, comp1); Gaussian z12 = Gaussian.Multiply(gz1, comp2); Gaussian z21 = Gaussian.Multiply(gz2, comp1); Gaussian z22 = Gaussian.Multiply(gz2, comp2); double sumw1 = z11.Weight + z12.Weight; double sumw2 = z21.Weight + z22.Weight; double clutter = vehicle.ClutterDensity; explist.Add(comp1.Reweight(0.8 * (1 - PD))); explist.Add(comp2.Reweight(1.4 * (1 - PD))); explist.Add(z11.Reweight(z11.Weight * PD / (clutter + PD * sumw1))); explist.Add(z12.Reweight(z12.Weight * PD / (clutter + PD * sumw1))); explist.Add(z21.Reweight(z21.Weight * PD / (clutter + PD * sumw2))); explist.Add(z22.Reweight(z22.Weight * PD / (clutter + PD * sumw2))); Assert.AreEqual(6, clist.Count); foreach (Gaussian expected in explist) { bool found = false; for (int i = 0; i < clist.Count; i++) { if (expected.Equals(clist[i], 1e-5)) { found = true; clist.RemoveAt(i); break; } } if (!found) { Assert.Fail("Component not found: " + expected); } } }
private float GetItemSimilarity(int itemBought, int newItem) { IList <float> rowDiff = MatrixExtensions.RowDifference(item_factors, itemBought, item_factors, newItem); return((float)rowDiff.EuclideanNorm()); }
//**************************************************************** // Camera View Coordinate System Conversions - Methods to // translate from the camera's local coordinate system (above the // camera's view matrix) to the camera view coordinate system // (below the camera's view matrix). When converting geometry from // one of the canvas’s layers you must go through the view matrix. //**************************************************************** /// <summary> /// Transform the point from the camera's view coordinate system to the camera's /// local coordinate system. /// </summary> /// <param name="point"> /// The point in the camera's view coordinate system to be transformed. /// </param> /// <returns>The point in the camera's local coordinate system.</returns> public virtual PointFx ViewToLocal(PointFx point) { return(MatrixExtensions.Transform(viewMatrix, point)); }
protected override bool OnHitTest(RenderContext context, Matrix totalModelMatrix, ref Ray ray, ref List <HitTestResult> hits) { var p = Vector4.Transform(new Vector4(ray.Position, 1), context.ScreenViewProjectionMatrix); if (Math.Abs(p.W) > 1e-7) { p /= p.W; } else { return(false); } var screenSpaceCore = RenderCore as ScreenSpacedMeshRenderCore; float viewportSize = screenSpaceCore.Size * screenSpaceCore.SizeScale; var px = p.X - (float)(context.ActualWidth / 2 * (1 + screenSpaceCore.RelativeScreenLocationX) - viewportSize / 2); var py = p.Y - (float)(context.ActualHeight / 2 * (1 - screenSpaceCore.RelativeScreenLocationY) - viewportSize / 2); if (px < 0 || py < 0 || px > viewportSize || py > viewportSize) { return(false); } var viewMatrix = screenSpaceCore.GlobalTransform.View; Vector3 v = new Vector3(); var matrix = MatrixExtensions.PsudoInvert(ref viewMatrix); var aspectRatio = screenSpaceCore.ScreenRatio; var projMatrix = screenSpaceCore.GlobalTransform.Projection; Vector3 zn; v.X = (2 * px / viewportSize - 1) / projMatrix.M11; v.Y = -(2 * py / viewportSize - 1) / projMatrix.M22; v.Z = 1 / projMatrix.M33; Vector3.TransformCoordinate(ref v, ref matrix, out Vector3 zf); if (screenSpaceCore.IsPerspective) { zn = screenSpaceCore.GlobalTransform.EyePos; } else { v.Z = 0; Vector3.TransformCoordinate(ref v, ref matrix, out zn); } Vector3 r = zf - zn; r.Normalize(); ray = new Ray(zn, r); List <HitTestResult> viewBoxHit = new List <HitTestResult>(); if (base.OnHitTest(context, totalModelMatrix, ref ray, ref viewBoxHit)) { hits?.Clear(); hits = viewBoxHit; Debug.WriteLine("View box hit."); var hit = viewBoxHit[0]; Vector3 normal = Vector3.Zero; int inv = isRightHanded ? 1 : -1; if (hit.ModelHit == ViewBoxMeshModel) { normal = -hit.NormalAtHit * inv; //Fix the normal if returned normal is reversed if (Vector3.Dot(normal, context.Camera.LookDirection) < 0) { normal *= -1; } } else if (hit.Tag is int index) { if (hit.ModelHit == EdgeModel && index < edgeInstances.Length) { Matrix transform = edgeInstances[index]; normal = -transform.TranslationVector; } else if (hit.ModelHit == CornerModel && index < cornerInstances.Length) { Matrix transform = cornerInstances[index]; normal = -transform.TranslationVector; } else { return(false); } } else { return(false); } normal.Normalize(); if (Vector3.Cross(normal, UpDirection).LengthSquared() < 1e-5) { var vecLeft = new Vector3(-normal.Y, -normal.Z, -normal.X); OnViewBoxClicked?.Invoke(this, new ViewBoxClickedEventArgs(normal, vecLeft)); } else { OnViewBoxClicked?.Invoke(this, new ViewBoxClickedEventArgs(normal, UpDirection)); } return(true); } else { return(false); } }
/// <summary> /// Transform the size from the camera's view coordinate system to the camera's /// local coordinate system. /// </summary> /// <param name="size"> /// The size in the camera's view coordinate system to be transformed. /// </param> /// <returns>The size in the camera's local coordinate system.</returns> public virtual SizeFx ViewToLocal(SizeFx size) { return(MatrixExtensions.Transform(viewMatrix, size)); }
void Start() { _camera = gameObject.GetComponent<Camera>(); _aspect = (float)Screen.width / (float)Screen.height; ortho = Matrix4x4.Ortho(-orthographicSize * _aspect, orthographicSize * _aspect, -orthographicSize, orthographicSize, near, far); perspective = Matrix4x4.Perspective(fov, _aspect, near, far); _camera.projectionMatrix = ortho; _orthoOn = true; _blender = (MatrixBlender)gameObject.GetComponent(typeof(MatrixBlender)); }
protected override bool OnHitTest(RenderContext context, Matrix totalModelMatrix, ref Ray ray, ref List <HitTestResult> hits) { var p = Vector3.TransformCoordinate(ray.Position, context.ScreenViewProjectionMatrix); var screenSpaceCore = RenderCore as ScreenSpacedMeshRenderCore; float viewportSize = screenSpaceCore.Size * screenSpaceCore.SizeScale; var offx = (float)(context.ActualWidth / 2 * (1 + screenSpaceCore.RelativeScreenLocationX) - viewportSize / 2); var offy = (float)(context.ActualHeight / 2 * (1 + screenSpaceCore.RelativeScreenLocationY) - viewportSize / 2); offx = Math.Max(0, Math.Min(offx, (int)(context.ActualWidth - viewportSize))); offy = Math.Max(0, Math.Min(offy, (int)(context.ActualHeight - viewportSize))); var px = p.X - offx; var py = p.Y - offy; if (px < 0 || py < 0 || px > viewportSize || py > viewportSize) { return(false); } var viewMatrix = screenSpaceCore.GlobalTransform.View; Vector3 v = new Vector3(); var matrix = MatrixExtensions.PsudoInvert(ref viewMatrix); var aspectRatio = screenSpaceCore.ScreenRatio; var projMatrix = screenSpaceCore.GlobalTransform.Projection; Vector3 zn; v.X = (2 * px / viewportSize - 1) / projMatrix.M11; v.Y = (2 * py / viewportSize - 1) / projMatrix.M22; v.Z = 1 / projMatrix.M33; Vector3.TransformCoordinate(ref v, ref matrix, out Vector3 zf); if (screenSpaceCore.IsPerspective) { zn = screenSpaceCore.GlobalTransform.EyePos; } else { v.Z = 0; Vector3.TransformCoordinate(ref v, ref matrix, out zn); } Vector3 r = zf - zn; r.Normalize(); ray = new Ray(zn, r); screenSpaceHits.Clear(); if (base.OnHitTest(context, totalModelMatrix, ref ray, ref screenSpaceHits)) { if (hits == null) { hits = new List <HitTestResult>(); } hits.Clear(); hits.AddRange(screenSpaceHits); return(true); } else { return(false); } }