/// <summary> /// Return if the position is inside of the triangle /// </summary> /// <param name="_position"></param> /// <returns></returns> public bool IsInTriangle(Vector3 _position, Triangle _triangle) { Barycentric _barycentric = new Barycentric(NavigationDatas.Vertices[_triangle.Vertices[0]], NavigationDatas.Vertices[_triangle.Vertices[1]], NavigationDatas.Vertices[_triangle.Vertices[2]], _position); return(_barycentric.IsInside); }
public void PolyomnialFitsAtSamplePoints() { IInterpolation it = Barycentric.InterpolateRationalFloaterHormann(_t, _y); for (int i = 0; i < _y.Length; i++) { Assert.AreEqual(_y[i], it.Interpolate(_t[i]), "A Exact Point " + i); } }
public void PlantPatch(Barycentric bary, int BladeCount = 4096, double Area = 1.1, double MaxHeight = 1) { double sq2 = Math.Sqrt(BladeCount); Matrix4d TreeRotation = Matrix4d.CreateFromQuaternion(Globals.LocalUpRotation()); Matrix4d TreePosition; Matrix4 final; Matrix4d TreeScale; Vector3d PlantingPos = new Vector3d(); int bposx = (int)(Tile.x_res * (1 - bary.u)); int bposz = (int)(Tile.z_res * (bary.v)); // Tile.Biome.SetPixel(bposx, bposz, new float[] { 0, 1, 0, 1 }); for (int x = (int)-sq2; x < sq2; x++) { for (int z = (int)-sq2; z < sq2; z++) { bposx = (int)(Tile.x_res * (1 - bary.u)) - x; bposz = (int)(Tile.z_res * (bary.v)) - z; int t = Tile._biome.GetBiomeAt(bposx, bposz); if ((t != MBiome.GRASS) && (t != MBiome.TREES) && (t != MBiome.TREES2) && (t != MBiome.WATER)) { continue; } PlantingPos.X = (int)(Tile.x_res * (1 - bary.u)) - x * 0.05 * Area; PlantingPos.Y = 0; PlantingPos.Z = (int)(Tile.z_res * (bary.v)) - z * 0.05 * Area; double yv = (MPerlin.Noise(PlantingPos.X, PlantingPos.Z) * 0.4) + (MPerlin.Noise(PlantingPos.X * 1.1, PlantingPos.Z * 1.1) * 0.4) ; //if (yv < 0.01) continue; TreeScale = Matrix4d.Scale(0.05 + 0.06 * yv, 0.01 + Math.Abs(yv) * 0.15 * MaxHeight, 0.05 + 0.06 * yv); PlantingPos.X += MPerlin.Noise(PlantingPos.X * 4.0, 0, PlantingPos.Z * 2.0) * 1.1; PlantingPos.Z += MPerlin.Noise(PlantingPos.X * 4.0, 0, PlantingPos.Z * 2.0) * 1.1; PlantingPos = Tile.GetInterpolatedPointOnSurfaceFromGrid2(PlantingPos); TreePosition = Matrix4d.CreateTranslation(PlantingPos); final = MTransform.GetFloatMatrix(TreeScale * TreeRotation * TreePosition); if (TotalInstances < Settings.MaxGrassPerTerrain) { mats[TotalInstances] = final; TotalInstances++; } } } }
public void FitsAtSamplePoints() { IInterpolation it = Barycentric.InterpolatePolynomialEquidistant(Tmin, Tmax, _y); for (int i = 0; i < _y.Length; i++) { Assert.AreEqual(_y[i], it.Interpolate(i), "A Exact Point " + i); } }
private static Mesh PrepareMesh(GameObject go, Component c, Mesh mesh) { Undo.RecordObject(c, "Wireframe.PrepareMesh"); Mesh duplicate = Object.Instantiate(mesh); duplicate.name = mesh.name; Barycentric.CalculateBarycentric(duplicate); EditorUtility.SetDirty(go); return(duplicate); }
public void SupportsLinearCase(int samples) { double[] x, y, xtest, ytest; LinearInterpolationCase.Build(out x, out y, out xtest, out ytest, samples); IInterpolation it = Barycentric.InterpolateRationalFloaterHormann(x, y); for (int i = 0; i < xtest.Length; i++) { Assert.AreEqual(ytest[i], it.Interpolate(xtest[i]), 1e-14, "Linear with {0} samples, sample {1}", samples, i); } }
private int assignObjects( Mesh mesh3d, List <DynamicObject> objects, Vector2 u1, Vector2 u2, Vector2 u3, int i, bool lookAtAllObjects = true) { int found = 0; foreach (DynamicObject obj in objects) { if (obj.assigned) { continue; } Vector2 point = obj.toVector2(); Barycentric a = new Barycentric(u1, u2, u3, point); if (a.IsInside) { //if (a.u == 0 || a.v == 0 || a.w == 0 || a.u == 1 || a.v == 1) { // if (u1 == point || u2 == point || u3 == point || point.x == 0.5 || point.y == 0.5) { } else // Debug.Log("Found object (" + u1.x + ", " + u1.y + " / " // + u2.x + ", " + u2.y + " / " // + u3.x + ", " + u3.y + " - " // + point.x + ", " + point.y + ")"); //} obj.barycentric = a; obj.assigned = true; if (textureObjectsOnTriangles[i / 3] == null) { textureObjectsOnTriangles[i / 3] = new List <DynamicObject>(); } textureObjectsOnTriangles[i / 3].Add(obj); found++; if (lookAtAllObjects && neighbours[i / 3] == null) { neighbours[i / 3] = new NeighbourCreator(mesh3d, i, neighbourRadius).create(); } } } return(found); }
public Vector3 GetPixelWorldPos(Texture2D mainTex, Color32 color, int index) { int w = mainTex.width; int h = mainTex.height; // find color in texture /* * Color[] colors = mainTex.GetPixels(); * int index = -1; * for (int i = 0; i < colors.Length; i++) * { * if (colors[i] == color) * { * index = i; * break; * } * } */ if (index == -1) { return(Vector3.zero); } // Find triangle and get local pos var point = new Vector2(index % w, index / w) - new Vector2(0.5f / w, 0.5f / h); var mf = gameObject.GetComponent <MeshFilter>(); var mesh = m_mesh; var uvs = m_uvs.ToArray(); var verts = mesh.vertices; var tris = mesh.triangles; for (int i = 0; i < m_triangles.Length; i += 3) { var uv0 = m_uvs[i + 0]; var uv1 = m_uvs[i + 1]; var uv2 = m_uvs[i + 2]; var bary = new Barycentric(uv0, uv1, uv2, point); if (bary.IsInside) { Vector3 localPos = m_vertices[i + 0] * bary.u + m_vertices[i + 1] * bary.v + m_vertices[i + 2] * bary.w; // Transform to world pos and return return(gameObject.transform.TransformPoint(localPos)); } } return(Vector3.zero); }
//TODO: pull the nearest blades from the Grassmats and add to mats //OR: Rolling buffer, taking from behind and adding edges of direction of travel public void PlantGrass3(MAstroBody planet, MTerrainTile tile) { Tile = tile; if (tile.material == null) { return; } if (Tile.GrassPlanter.IsComplete == false) { return; } Vector3d AP = Globals.Avatar.GetPosition(); Barycentric bary = new Barycentric(Tile.Boundary.TL, Tile.Boundary.BR, Tile.Boundary.TR, AP); Vector3d Centroid = new Vector3d((1 - bary.u) * MGrassPlanter.LOD0Size, 0, bary.v * MGrassPlanter.LOD0Size); int cx = (int)(bary.u * MGrassPlanter.LOD0Size); int cz = (int)(bary.v * MGrassPlanter.LOD0Size); float numxinterps = MGrassPlanter.LOD0Size / Tile.x_res; float numzinterps = MGrassPlanter.LOD0Size / Tile.z_res; TotalInstances = 0; for (int x = 0; x < 100; x++) { for (int z = 0; z < 100; z++) { if (TotalInstances >= Settings.MaxGrassPerTerrain) { continue; } if (cx + x > MGrassPlanter.LOD0Size) { continue; } if (cz + z > MGrassPlanter.LOD0Size) { continue; } mats[TotalInstances] = Tile.GrassPlanter.Grassmats[cx + x, cz + z]; TotalInstances++; } } Planted = true; }
public void RationalFitsAtSamplePoints() { var t = new double[40]; var x = new double[40]; const double Step = 10.0 / 39.0; for (int i = 0; i < t.Length; i++) { double tt = -5 + (i * Step); t[i] = tt; x[i] = 1.0 / (1.0 + (tt * tt)); } IInterpolation it = Barycentric.InterpolateRationalFloaterHormann(t, x); for (int i = 0; i < x.Length; i++) { Assert.AreEqual(x[i], it.Interpolate(t[i]), "A Exact Point " + i); } }
/// <summary> /// Fill a triangle area on the texture, lerping vertex colors. /// </summary> /// private static void FillInTextureTriangle(Texture2D tex, Vector2 coord_a, Vector2 coord_b, Vector2 coord_c, Color color_a, Color color_b, Color color_c) { int xmin = Mathf.RoundToInt(Mathf.Min(coord_a.x, coord_b.x, coord_c.x)); int xmax = Mathf.RoundToInt(Mathf.Max(coord_a.x, coord_b.x, coord_c.x)); int ymin = Mathf.RoundToInt(Mathf.Min(coord_a.y, coord_b.y, coord_c.y)); int ymax = Mathf.RoundToInt(Mathf.Max(coord_a.y, coord_b.y, coord_c.y)); Color color = Color.clear; for (int x = xmin; x <= xmax; x++) { for (int y = ymin; y <= ymax; y++) { var baryCoord = new Barycentric(coord_a, coord_b, coord_c, new Vector2(x, y)); if (baryCoord.IsInside) { color = baryCoord.Interpolate(color_a, color_b, color_c); tex.SetPixel(x, y, color); } } } }
private void FillInTextureTriangle(Texture2D tex, Vector2 ta, Vector2 tb, Vector2 tc, Color ca, Color cb, Color cc) { int xmin = Mathf.RoundToInt(Mathf.Min(ta.x, tb.x, tc.x)); int xmax = Mathf.RoundToInt(Mathf.Max(ta.x, tb.x, tc.x)); int ymin = Mathf.RoundToInt(Mathf.Min(ta.y, tb.y, tc.y)); int ymax = Mathf.RoundToInt(Mathf.Max(ta.y, tb.y, tc.y)); Color color = Color.clear; for (int x = xmin; x <= xmax; x++) { for (int y = ymin; y <= ymax; y++) { var baryCoord = new Barycentric(ta, tb, tc, new Vector2(x, y)); if (baryCoord.IsInside) { color = baryCoord.Interpolate(ca, cb, cc); tex.SetPixel(x, y, color); } } } }
void GenerateTexture() { int n = 512; Color[] pixels = new Color[n * n]; for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { if (i >= j) { Barycentric b = new Barycentric(new Vector2(0, 0), new Vector2(1, 0), new Vector2(1, 1), new Vector2(i * 1f / n, j * 1f / n)); var c = b.Interpolate(Color.red, Color.green, Color.blue); int k = i * n + j; pixels[k] = c; } } } tex = new Texture2D(n, n); tex.SetPixels(pixels); tex.Apply(); }
public void PolynomialFitsAtArbitraryPointsWithMaple(double t, double x, double maxAbsoluteError) { IInterpolation it = Barycentric.InterpolateRationalFloaterHormann(_t, _y); Assert.AreEqual(x, it.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); }
public void FewSamples() { Assert.That(() => Barycentric.InterpolateRationalFloaterHormann(new double[0], new double[0]), Throws.ArgumentException); Assert.That(Barycentric.InterpolateRationalFloaterHormann(new[] { 1.0 }, new[] { 2.0 }).Interpolate(1.0), Is.EqualTo(2.0)); }
public void PlantGrass(MAstroBody planet, MTerrainTile tile) { // if (Planted == true) return; //DistanceThreshold = tile.DistanceThreshold; Tile = tile; if (tile.material == null) { return; } MTexture tex = Tile.Biome; if (tex == null) { return; } this.transform.Position = tile.transform.Position; //Random ran = new Random(1234); Matrix4d TreeRotation = Matrix4d.CreateFromQuaternion(Globals.LocalUpRotation()); //int i = 0; TotalInstances = 0; Vector3d AP = Globals.Avatar.GetPosition(); // Console.WriteLine(AP); Barycentric bary = new Barycentric(Tile.Boundary.TL, Tile.Boundary.BR, Tile.Boundary.TR, AP); PlantPatch(bary, 64 * 64, 2, 0.8); //PlantPatch(bary, 32 * 32, 8, 0.3); // Console.WriteLine(bary.ToString()); /* * double sq = 64 * 64; * double sq2 = Math.Sqrt(sq); * * Matrix4d TreePosition; * Matrix4 final; * Matrix4d TreeScale; * Vector3d PlantingPos = new Vector3d(); * for (int x = (int)-sq2; x < sq2; x++) * for (int z = (int)-sq2; z < sq2; z++) * { * PlantingPos.X = (int)(Tile.x_res * (1 - bary.u)) - x * 0.05; * PlantingPos.Y = 0; * PlantingPos.Z = (int)(Tile.z_res * (bary.v)) - z * 0.05; * * double yv = * (MPerlin.Noise(PlantingPos.X, PlantingPos.Z) * 0.4) + (MPerlin.Noise(PlantingPos.X * 1.1, PlantingPos.Z * 1.1) * 0.4) + ; + if (yv < 0.1) continue; + + TreeScale = Matrix4d.Scale(0.03+0.04 * yv, 0.01 + yv * 0.14 , 0.03+0.04* yv); + + PlantingPos.X += MPerlin.Noise(PlantingPos.X * 4.0, PlantingPos.Z * 4.1) * 1.1; + PlantingPos.Z += MPerlin.Noise(PlantingPos.X * 3.8, PlantingPos.Z * 4.2) * 1.1; + PlantingPos = Tile.GetInterpolatedPointOnSurfaceFromGrid2(PlantingPos); + + TreePosition = Matrix4d.CreateTranslation(PlantingPos); + final = MTransform.GetFloatMatrix(TreeScale * TreeRotation * TreePosition); + if (i < Settings.MaxGrassPerTerrain) + { + mats[i] = final; + i++; + } + } + + TotalInstances = i; */ for (int j = TotalInstances; j < Settings.MaxGrassPerTerrain; j++) { Matrix4 final = Matrix4.CreateTranslation(9999999999, 0, 0); mats[j] = final; } //Setup(); //UploadBuffer(); Planted = true; }
// rightPoint1 // |\ // | \ // intersectionPoint2|__\ intersectionPoint1 // | \ // leftPoint2 |____\ leftPoint1 // public void CreateTrianglesTwoPointsOnLeft(Vector3 leftPoint1, Vector3 leftPoint2, Vector3 rightPoint1, int i, int n0, int n1, int n2) { var n = _verts.Count; var intersectionPoint1 = IntersectionPlaneLinePoint(leftPoint1, rightPoint1, _planePoint, _planeNormal); var intersectionPoint2 = IntersectionPlaneLinePoint(leftPoint2, rightPoint1, _planePoint, _planeNormal); var localLeftPoint1 = _srcObject.transform.InverseTransformPoint(leftPoint1); var localLeftPoint2 = _srcObject.transform.InverseTransformPoint(leftPoint2); var localIntersectionPoint1 = _srcObject.transform.InverseTransformPoint(intersectionPoint1); var localIntersectionPoint2 = _srcObject.transform.InverseTransformPoint(intersectionPoint2); _wholeSlicePlane.AddSlicePlanePoints(localIntersectionPoint1, localIntersectionPoint2); int t0 = _triangles2[i + n0]; int t1 = _triangles2[i + n1]; int t2 = _triangles2[i + n2]; var localRightPoint1 = _srcObject.transform.InverseTransformPoint(rightPoint1); if (_tangents.Any()) { AddTangents(_tangents[t0], _tangents[t1], _tangents[t2], _tangents[t2]); } if (_uvs.Any()) { var b1 = new Barycentric(localLeftPoint1, localLeftPoint2, localRightPoint1, localIntersectionPoint1); var intersectionPoint1Uv = b1.Interpolate(_uvs[t0], _uvs[t1], _uvs[t2]); var b2 = new Barycentric(localLeftPoint1, localLeftPoint2, localRightPoint1, localIntersectionPoint2); var intersectionPoint2Uv = b2.Interpolate(_uvs[t0], _uvs[t1], _uvs[t2]); AddUVs(_uvs[t0], _uvs[t1], intersectionPoint1Uv, intersectionPoint2Uv); } var b3 = new Barycentric(localLeftPoint1, localLeftPoint2, localRightPoint1, localIntersectionPoint1); var localIntersectionPoint1Normal = b3.Interpolate(_normals[t0], _normals[t1], _normals[t2]); var b4 = new Barycentric(localLeftPoint1, localLeftPoint2, localRightPoint1, localIntersectionPoint2); var localIntersectionPoint2Normal = b4.Interpolate(_normals[t0], _normals[t1], _normals[t2]); AddNormals(_normals[t0], _normals[t1], localIntersectionPoint1Normal, localIntersectionPoint2Normal); AddVerts(localLeftPoint1, localLeftPoint2, localIntersectionPoint1, localIntersectionPoint2); if (n0 == 0 && n1 == 2) { AddTriangle(n, 1, 0, 2); AddTriangle(n, 1, 2, 3); } else //if (n0 == 1) { AddTriangle(n, 0, 1, 3); AddTriangle(n, 0, 3, 2); } }
/// <summary> /// Return if the position is inside of the triangle /// </summary> /// <param name="_position"></param> /// <returns></returns> bool IsInTriangle(Vector3 _position, TDS_Triangle _triangle) { Barycentric _barycentric = new Barycentric(navPoints[_triangle.VerticesIndex[0]].Position, navPoints[_triangle.VerticesIndex[1]].Position, navPoints[_triangle.VerticesIndex[2]].Position, _position); return(_barycentric.IsInside); }
/// <summary> /// Create a Floater-Hormann rational pole-free interpolation based on arbitrary points. /// </summary> /// <param name="points">The sample points t.</param> /// <param name="values">The sample point values x(t).</param> /// <returns> /// An interpolation scheme optimized for the given sample points and values, /// which can then be used to compute interpolations and extrapolations /// on arbitrary points. /// </returns> /// <remarks> /// if your data is already sorted in arrays, consider to use /// MathNet.Numerics.Interpolation.Barycentric.InterpolateRationalFloaterHormannSorted /// instead, which is more efficient. /// </remarks> public static IInterpolation RationalWithoutPoles(IEnumerable <double> points, IEnumerable <double> values) { return(Barycentric.InterpolateRationalFloaterHormann(points, values)); }
/// <summary> /// Create a barycentric polynomial interpolation where the given sample points are equidistant. /// </summary> /// <param name="points">The sample points t, must be equidistant.</param> /// <param name="values">The sample point values x(t).</param> /// <returns> /// An interpolation scheme optimized for the given sample points and values, /// which can then be used to compute interpolations and extrapolations /// on arbitrary points. /// </returns> /// <remarks> /// if your data is already sorted in arrays, consider to use /// MathNet.Numerics.Interpolation.Barycentric.InterpolatePolynomialEquidistantSorted /// instead, which is more efficient. /// </remarks> public static IInterpolation PolynomialEquidistant(IEnumerable <double> points, IEnumerable <double> values) { return(Barycentric.InterpolatePolynomialEquidistant(points, values)); }
/// <summary> /// Return if the position is inside of the triangle /// </summary> /// <param name="_position"></param> /// <returns></returns> public static bool IsInTriangle(Vector3 _position, Triangle _triangle) { Barycentric _barycentric = new Barycentric(_triangle.Vertices[0].Position, _triangle.Vertices[1].Position, _triangle.Vertices[2].Position, _position); return(_barycentric.IsInside); }
public void FewSamples() { Assert.That(() => Barycentric.InterpolatePolynomialEquidistant(new double[0], new double[0]), Throws.ArgumentException); Assert.That(Barycentric.InterpolatePolynomialEquidistant(new[] { 1.0 }, new[] { 2.0 }).Interpolate(1.0), Is.EqualTo(2.0)); }
public void FitsAtArbitraryPoints(double t, double x, double maxAbsoluteError) { IInterpolation it = Barycentric.InterpolatePolynomialEquidistant(Tmin, Tmax, _y); Assert.AreEqual(x, it.Interpolate(t), maxAbsoluteError, "Interpolation at {0}", t); }
// Utility functions public bool IsPointInTriangle(Vector2 p, Vector2 a, Vector2 b, Vector2 c) { Barycentric s = new Barycentric(p, a, b, c); return(s.u >= 0f && s.v >= 0f && s.w >= 0f); }
internal bool TryAddBlends(SurfaceData sd, Mesh mesh, int submeshID, Vector3 point, int triangleID, out float totalWeight) { totalWeight = 0; //Finds Barycentric var triangle = triangleID * 3; var t0 = triangles[triangle + 0]; var t1 = triangles[triangle + 1]; var t2 = triangles[triangle + 2]; var a = vertices[t0]; var b = vertices[t1]; var c = vertices[t2]; point = transform.InverseTransformPoint(point); var bary = new Barycentric(a, b, c, point); #if UNITY_EDITOR lastSampledColors.Clear(); #endif float totalTotalWeight = 0; for (int i = 0; i < blendMaps.Length; i++) { var bm = blendMaps[i]; bm.sampled = false; for (int ii = 0; ii < bm.subMaterials.Length; ii++) { if (bm.subMaterials[ii].materialID == submeshID) { var uv = bary.Interpolate(bm.uvs[t0], bm.uvs[t1], bm.uvs[t2]); uv = uv * new Vector2(bm.uvScaleOffset.x, bm.uvScaleOffset.y) + new Vector2(bm.uvScaleOffset.z, bm.uvScaleOffset.w); //? Color color = bm.map.GetPixelBilinear(uv.x, uv.y); //this only works for clamp or repeat btw (not mirror etc.) bm.sampledColor = color; void SampleColor(BlendMap.SurfaceBlends2 sb2) { if (sb2.colorMap != null) { sb2.sampledColor = sb2.colorMap.GetPixelBilinear(uv.x, uv.y); } else { sb2.sampledColor = Color.white; } } SampleColor(bm.r); SampleColor(bm.g); SampleColor(bm.b); SampleColor(bm.a); totalTotalWeight += bm.weight * (color.r + color.g + color.b + color.a); #if UNITY_EDITOR lastSampledColors.Add(color); #endif bm.sampled = true; break; } } } if (totalTotalWeight > 0) { float invTotalTotal = 1f / totalTotalWeight; for (int i = 0; i < blendMaps.Length; i++) { var bm = blendMaps[i]; if (bm.sampled) { float invTotal = bm.weight * invTotalTotal; var color = bm.sampledColor; Add(sd, bm.r.result, bm.r.sampledColor, color.r * invTotal, ref totalWeight); Add(sd, bm.g.result, bm.g.sampledColor, color.g * invTotal, ref totalWeight); Add(sd, bm.b.result, bm.b.sampledColor, color.b * invTotal, ref totalWeight); Add(sd, bm.a.result, bm.a.sampledColor, color.a * invTotal, ref totalWeight); } } return(true); } return(false); }